1 /*
2 * Copyright (c) 2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file ddi_encode_av1_specific.cpp
24 //! \brief HEVC class definition for DDI media encoder.
25 //!
26
27 #include "ddi_encode_base_specific.h"
28 #include "ddi_encode_av1_specific.h"
29 #include "media_libva_util_next.h"
30 #include "media_ddi_encode_const.h"
31 #include "media_ddi_factory.h"
32 #include "media_libva_interface_next.h"
33
34 #include "mos_solo_generic.h"
35
36 namespace encode
37 {
38
~DdiEncodeAV1()39 DdiEncodeAV1::~DdiEncodeAV1()
40 {
41 if (m_encodeCtx == nullptr)
42 {
43 return;
44 }
45
46 MOS_FreeMemory(m_encodeCtx->pSeqParams);
47 m_encodeCtx->pSeqParams = nullptr;
48
49 MOS_FreeMemory(m_encodeCtx->pPicParams);
50 m_encodeCtx->pPicParams = nullptr;
51
52 MOS_FreeMemory(m_encodeCtx->pSliceParams);
53 m_encodeCtx->pSliceParams = nullptr;
54
55 MOS_FreeMemory(m_encodeCtx->pEncodeStatusReport);
56 m_encodeCtx->pEncodeStatusReport = nullptr;
57
58 MOS_FreeMemory(m_encodeCtx->pSliceHeaderData);
59 m_encodeCtx->pSliceHeaderData = nullptr;
60
61 if (m_encodeCtx->pbsBuffer)
62 {
63 MOS_FreeMemory(m_encodeCtx->pbsBuffer->pBase);
64 m_encodeCtx->pbsBuffer->pBase = nullptr;
65 }
66 MOS_FreeMemory(m_encodeCtx->pbsBuffer);
67 m_encodeCtx->pbsBuffer = nullptr;
68
69 if (m_encodeCtx->ppNALUnitParams && m_encodeCtx->ppNALUnitParams[0])
70 {
71 // Allocate one contiguous memory for the NALUnitParams buffers
72 // only need to free one time
73 MOS_FreeMemory(m_encodeCtx->ppNALUnitParams[0]);
74 m_encodeCtx->ppNALUnitParams[0] = nullptr;
75 }
76
77 MOS_FreeMemory(m_encodeCtx->ppNALUnitParams);
78 m_encodeCtx->ppNALUnitParams = nullptr;
79 }
80
ContextInitialize(CodechalSetting * codecHalSettings)81 VAStatus DdiEncodeAV1::ContextInitialize(
82 CodechalSetting *codecHalSettings)
83 {
84 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
85 DDI_CODEC_CHK_NULL(m_encodeCtx->pCpDdiInterfaceNext, "nullptr m_encodeCtx->pCpDdiInterfaceNext.", VA_STATUS_ERROR_INVALID_CONTEXT);
86 DDI_CODEC_CHK_NULL(codecHalSettings, "nullptr codecHalSettings.", VA_STATUS_ERROR_INVALID_CONTEXT);
87
88 codecHalSettings->codecFunction = m_encodeCtx->codecFunction;
89 codecHalSettings->width = m_encodeCtx->dworiFrameWidth;
90 codecHalSettings->height = m_encodeCtx->dworiFrameHeight;
91 codecHalSettings->mode = m_encodeCtx->wModeType;
92 codecHalSettings->standard = CODECHAL_AV1;
93 codecHalSettings->chromaFormat = AVP_CHROMA_FORMAT_YUV420;
94 codecHalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_10_BITS;
95
96 VAStatus eStatus = VA_STATUS_SUCCESS;
97
98 // Allocate sequence params
99 m_encodeCtx->pSeqParams = (void *)MOS_AllocAndZeroMemory(sizeof(CODEC_AV1_ENCODE_SEQUENCE_PARAMS));
100 DDI_CODEC_CHK_NULL(m_encodeCtx->pSeqParams, "nullptr m_encodeCtx->pSeqParams.", VA_STATUS_ERROR_ALLOCATION_FAILED);
101
102 // Allocate picture params
103 m_encodeCtx->pPicParams = (void *)MOS_AllocAndZeroMemory(sizeof(CODEC_AV1_ENCODE_PICTURE_PARAMS));
104 DDI_CODEC_CHK_NULL(m_encodeCtx->pPicParams, "nullptr m_encodeCtx->pPicParams.", VA_STATUS_ERROR_ALLOCATION_FAILED);
105
106 // Allocate slice params
107 m_encodeCtx->pSliceParams = (void *)MOS_AllocAndZeroMemory(TILE_GROUP_NUM_INCREMENT * sizeof(CODEC_AV1_ENCODE_TILE_GROUP_PARAMS));
108 DDI_CODEC_CHK_NULL(m_encodeCtx->pSliceParams, "nullptr m_encodeCtx->pSliceParams.", VA_STATUS_ERROR_ALLOCATION_FAILED);
109 allocatedTileNum = TILE_GROUP_NUM_INCREMENT;
110
111 // Allocate encode status report
112 m_encodeCtx->pEncodeStatusReport = (void *)MOS_AllocAndZeroMemory(CODECHAL_ENCODE_STATUS_NUM*sizeof(EncodeStatusReportData));
113 DDI_CODEC_CHK_NULL(m_encodeCtx->pEncodeStatusReport, "nullptr m_encodeCtx->pEncodeStatusReport.", VA_STATUS_ERROR_ALLOCATION_FAILED);
114
115 //Allocate Slice Header Data
116 m_encodeCtx->pSliceHeaderData = (CODEC_ENCODER_SLCDATA *)MOS_AllocAndZeroMemory(ENCODE_VDENC_AV1_MAX_TILE_GROUP_NUM * sizeof(CODEC_ENCODER_SLCDATA));
117 DDI_CODEC_CHK_NULL(m_encodeCtx->pSliceHeaderData, "nullptr m_encodeCtx->pSliceHeaderData.", VA_STATUS_ERROR_ALLOCATION_FAILED);
118
119 // Create the bit stream buffer to hold the packed headers from application
120 m_encodeCtx->pbsBuffer = (PBSBuffer)MOS_AllocAndZeroMemory(sizeof(BSBuffer));
121 DDI_CODEC_CHK_NULL(m_encodeCtx->pbsBuffer, "nullptr m_encodeCtx->pbsBuffer.", VA_STATUS_ERROR_ALLOCATION_FAILED);
122
123 m_encodeCtx->pbsBuffer->BufferSize = CODECHAL_AV1_FRAME_HEADER_SIZE;
124 m_encodeCtx->pbsBuffer->pBase = (uint8_t *)MOS_AllocAndZeroMemory(m_encodeCtx->pbsBuffer->BufferSize);
125 DDI_CODEC_CHK_NULL(m_encodeCtx->pbsBuffer, "nullptr m_encodeCtx->pbsBuffer.", VA_STATUS_ERROR_ALLOCATION_FAILED);
126 m_encodeCtx->pbsBuffer->pCurrent = m_encodeCtx->pbsBuffer->pBase;
127
128 // Allocate NAL unit params
129 m_encodeCtx->ppNALUnitParams = (PCODECHAL_NAL_UNIT_PARAMS *)MOS_AllocAndZeroMemory(sizeof(PCODECHAL_NAL_UNIT_PARAMS)*MAX_NUM_OBU_TYPES);
130 DDI_CODEC_CHK_NULL(m_encodeCtx->ppNALUnitParams, "nullptr m_encodeCtx->ppNALUnitParams", VA_STATUS_ERROR_ALLOCATION_FAILED);
131
132 PCODECHAL_NAL_UNIT_PARAMS nalUnitParams = (CODECHAL_NAL_UNIT_PARAMS *)MOS_AllocAndZeroMemory(sizeof(CODECHAL_NAL_UNIT_PARAMS)*MAX_NUM_OBU_TYPES);
133 DDI_CODEC_CHK_NULL(nalUnitParams, "nullptr nalUnitParams.", VA_STATUS_ERROR_ALLOCATION_FAILED);
134
135 for (uint32_t i = 0; i < MAX_NUM_OBU_TYPES; i++)
136 {
137 m_encodeCtx->ppNALUnitParams[i] = &(nalUnitParams[i]);
138 }
139
140 m_cpuFormat = true;
141
142 if (Mos_Solo_Extension(m_encodeCtx->pCodecHal->GetOsInterface()->pOsContext))
143 {
144 DDI_CODEC_CHK_NULL(m_encodeCtx->pCodecHal, "nullptr m_encodeCtx->pCodecHal", VA_STATUS_ERROR_INVALID_CONTEXT);
145 DDI_CODEC_CHK_NULL(m_encodeCtx->pCodecHal, "nullptr m_encodeCtx->pCodecHal->GetOsInterface()", VA_STATUS_ERROR_INVALID_CONTEXT);
146 DDI_CODEC_CHK_NULL(m_encodeCtx->pCodecHal, "nullptr (m_encodeCtx->pCodecHal->GetOsInterface()->pOsContext", VA_STATUS_ERROR_INVALID_CONTEXT);
147 DDI_CODEC_CHK_NULL(m_encodeCtx->pMediaCtx, "nullptr pMediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
148 Mos_Solo_CreateExtension(ENCODE_MODE_AV1, m_encodeCtx->pMediaCtx->platform.eProductFamily, m_encodeCtx->pCodecHal->GetOsInterface()->pOsContext);
149 }
150
151 return eStatus;
152 }
153
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)154 VAStatus DdiEncodeAV1::RenderPicture(
155 VADriverContextP ctx,
156 VAContextID context,
157 VABufferID *buffers,
158 int32_t numBuffers)
159 {
160 VAStatus vaStatus = VA_STATUS_SUCCESS;
161
162 DDI_CODEC_FUNC_ENTER;
163
164 DDI_CODEC_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
165
166 DDI_MEDIA_CONTEXT *mediaCtx = GetMediaContext(ctx);
167 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
168
169 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
170 DDI_CODEC_CHK_NULL(buffers, "nullptr buffers", VA_STATUS_ERROR_INVALID_BUFFER);
171 for (int32_t i = 0; i < numBuffers; i++)
172 {
173 DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, buffers[i]);
174 DDI_CODEC_CHK_NULL(buf, "Invalid buffer.", VA_STATUS_ERROR_INVALID_BUFFER);
175 if (buf->uiType == VAEncMacroblockDisableSkipMapBufferType)
176 {
177 MediaLibvaCommonNext::MediaBufferToMosResource(buf, &(m_encodeCtx->resPerMBSkipMapBuffer));
178 m_encodeCtx->bMbDisableSkipMapEnabled = true;
179 continue;
180 }
181 uint32_t dataSize = buf->iSize;
182 //can use internal function instead of MediaLibvaInterfaceNext::MapBuffer here?
183 void *data = nullptr;
184 MediaLibvaInterfaceNext::MapBuffer(ctx, buffers[i], &data);
185
186 DDI_CODEC_CHK_NULL(data, "nullptr data.", VA_STATUS_ERROR_INVALID_BUFFER);
187
188 switch (buf->uiType)
189 {
190 case VAEncSequenceParameterBufferType:
191 {
192 DDI_CHK_STATUS(ParseSeqParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
193 m_encodeCtx->bNewSeq = true;
194 break;
195 }
196 case VAEncPictureParameterBufferType:
197 {
198 DDI_CHK_STATUS(ParsePicParams(mediaCtx, data), VA_STATUS_ERROR_INVALID_BUFFER);
199 DDI_CHK_STATUS(
200 AddToStatusReportQueue((void *)m_encodeCtx->resBitstreamBuffer.bo),
201 VA_STATUS_ERROR_INVALID_BUFFER);
202 break;
203 }
204 case VAEncSliceParameterBufferType:
205 {
206 uint32_t numTiles = buf->uiNumElements;
207 DDI_CHK_STATUS(ParseTileGroupParams(data, numTiles), VA_STATUS_ERROR_INVALID_BUFFER);
208 break;
209 }
210 case VAEncPackedHeaderParameterBufferType:
211 {
212 DDI_CHK_STATUS(ParsePackedHeaderParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
213 break;
214 }
215 case VAEncPackedHeaderDataBufferType:
216 {
217 DDI_CHK_STATUS(ParsePackedHeaderData(data), VA_STATUS_ERROR_INVALID_BUFFER);
218 break;
219 }
220 case VAEncMiscParameterBufferType:
221 {
222 DDI_CHK_STATUS(ParseMiscParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
223 break;
224 }
225 case VAEncMacroblockMapBufferType:
226 {
227 DDI_CHK_STATUS(ParseSegMapParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
228 break;
229 }
230 default:
231 {
232 DDI_CODEC_ASSERTMESSAGE("not supported buffer type.");
233 break;
234 }
235 }
236 MediaLibvaInterfaceNext::UnmapBuffer(ctx, buffers[i]);
237 }
238
239 DDI_FUNCTION_EXIT(vaStatus);
240 return vaStatus;
241 }
242
EncodeInCodecHal(uint32_t numSlices)243 VAStatus DdiEncodeAV1::EncodeInCodecHal(uint32_t numSlices)
244 {
245 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
246 DDI_CODEC_CHK_NULL(m_encodeCtx->pCodecHal, "nullptr m_encodeCtx->pCodecHal", VA_STATUS_ERROR_INVALID_CONTEXT);
247
248 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS av1SeqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)((uint8_t *)m_encodeCtx->pSeqParams);
249 DDI_CODEC_CHK_NULL(av1SeqParams, "nullptr av1SeqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
250
251 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_encodeCtx->RTtbl);
252
253 EncoderParamsAV1 encodeParams;
254 MOS_ZeroMemory(&encodeParams, sizeof(encodeParams));
255 encodeParams.ExecCodecFunction = m_encodeCtx->codecFunction;
256
257 /* check whether the target bit rate is initialized for BRC */
258 if ((VA_RC_CBR == m_encodeCtx->uiRCMethod) ||
259 (VA_RC_VBR == m_encodeCtx->uiRCMethod))
260 {
261 if (av1SeqParams->TargetBitRate[0] == 0)
262 {
263 DDI_CODEC_ASSERTMESSAGE("DDI: No RateControl param for BRC\n!");
264 return VA_STATUS_ERROR_INVALID_PARAMETER;
265 }
266 }
267
268 // Raw Surface
269 MOS_SURFACE rawSurface;
270 MOS_ZeroMemory(&rawSurface, sizeof(rawSurface));
271 rawSurface.dwOffset = 0;
272
273 MediaLibvaCommonNext::MediaSurfaceToMosResource(rtTbl->pCurrentRT, &(rawSurface.OsResource));
274
275 // Recon Surface
276 MOS_SURFACE reconSurface;
277 MOS_ZeroMemory(&reconSurface, sizeof(reconSurface));
278 reconSurface.dwOffset = 0;
279
280 MediaLibvaCommonNext::MediaSurfaceToMosResource(rtTbl->pCurrentReconTarget, &(reconSurface.OsResource));
281
282 // Clear registered recon/ref surface flags
283 DDI_CODEC_CHK_RET(ClearRefList(&m_encodeCtx->RTtbl, true), "ClearRefList failed!");
284
285 // Bitsream surface
286 MOS_RESOURCE bitstreamSurface;
287 MOS_ZeroMemory(&bitstreamSurface, sizeof(bitstreamSurface));
288 bitstreamSurface = m_encodeCtx->resBitstreamBuffer;
289 bitstreamSurface.Format = Format_Buffer;
290
291 encodeParams.psRawSurface = &rawSurface;
292 encodeParams.psReconSurface = &reconSurface;
293 encodeParams.presBitstreamBuffer = &bitstreamSurface;
294
295 // Segmentation map won't be sent for each frame, so need to reset params before each frame.
296 encodeParams.pSegmentMap = nullptr;
297 encodeParams.bSegmentMapProvided = false;
298
299 if (m_isSegParamsChanged)
300 {
301 encodeParams.pSegmentMap = m_encodeCtx->pSegmentMap;
302 encodeParams.segmentMapDataSize = m_encodeCtx->segmentMapDataSize;
303 encodeParams.bSegmentMapProvided = true;
304 m_isSegParamsChanged = false;
305 }
306
307 if (m_encodeCtx->bNewSeq)
308 {
309 av1SeqParams->TargetUsage = m_encodeCtx->targetUsage;
310 }
311
312 encodeParams.pSeqParams = m_encodeCtx->pSeqParams;
313 encodeParams.pPicParams = m_encodeCtx->pPicParams;
314 encodeParams.pSliceParams = m_encodeCtx->pSliceParams;
315 encodeParams.ppNALUnitParams = m_encodeCtx->ppNALUnitParams;
316 encodeParams.uiNumNalUnits = m_encodeCtx->indexNALUnit;
317
318 // Sequence data
319 encodeParams.bNewSeq = m_encodeCtx->bNewSeq;
320 if (av1SeqParams->SeqFlags.fields.ResetBRC)
321 {
322 /* When the BRC needs to be reset, it indicates that the new Seq is issued. */
323 encodeParams.bNewSeq = true;
324 }
325
326 // Tile level data
327 encodeParams.dwNumSlices = numSlices;
328
329 for (uint32_t i = 0; i < (av1SeqParams->NumTemporalLayersMinus1 + 1); i++)
330 {
331 if (savedFrameRate[i] == 0)
332 {
333 /* use the default framerate if FrameRate is not passed */
334 av1SeqParams->FrameRate[i].Numerator = 30;
335 av1SeqParams->FrameRate[i].Denominator = 1;
336 }
337 }
338
339 encodeParams.pSlcHeaderData = (void *)m_encodeCtx->pSliceHeaderData;
340 encodeParams.pBSBuffer = m_encodeCtx->pbsBuffer;
341
342 MOS_STATUS status = m_encodeCtx->pCodecHal->Execute(&encodeParams);
343 if (MOS_STATUS_SUCCESS != status)
344 {
345 DDI_CODEC_ASSERTMESSAGE("DDI:Failed in Codechal!");
346 return VA_STATUS_ERROR_ENCODING_ERROR;
347 }
348
349 return VA_STATUS_SUCCESS;
350 }
351
352 // Reset the parameters before each frame
ResetAtFrameLevel()353 VAStatus DdiEncodeAV1::ResetAtFrameLevel()
354 {
355 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
356
357 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS av1SeqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)((uint8_t *)m_encodeCtx->pSeqParams);
358 DDI_CODEC_CHK_NULL(av1SeqParams, "nullptr av1SeqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
359 av1SeqParams->SeqFlags.fields.ResetBRC = 0;
360
361 m_encodeCtx->dwNumSlices = 0;
362 m_encodeCtx->bNewSeq = false;
363
364 // reset bsbuffer every frame
365 PBSBuffer pBSBuffer = m_encodeCtx->pbsBuffer;
366 DDI_CODEC_CHK_NULL(pBSBuffer, "nullptr bsBuffer.", VA_STATUS_ERROR_INVALID_PARAMETER);
367
368 *(pBSBuffer->pBase) = 0; //init first byte to 0
369 pBSBuffer->pCurrent = pBSBuffer->pBase;
370 pBSBuffer->SliceOffset = 0;
371 pBSBuffer->BitOffset = 0;
372 pBSBuffer->BitSize = 0;
373
374 // clear the packed header information
375 if (nullptr != m_encodeCtx->ppNALUnitParams)
376 {
377 MOS_ZeroMemory(m_encodeCtx->ppNALUnitParams[0], sizeof(CODECHAL_NAL_UNIT_PARAMS)*(m_encodeCtx->indexNALUnit));
378 }
379 m_encodeCtx->indexNALUnit = 0;
380
381 return VA_STATUS_SUCCESS;
382 }
383
ParseSeqParams(void * ptr)384 VAStatus DdiEncodeAV1::ParseSeqParams(void *ptr)
385 {
386 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
387 DDI_CODEC_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
388
389 VAEncSequenceParameterBufferAV1 *seqParams = (VAEncSequenceParameterBufferAV1 *)ptr;
390
391 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS av1SeqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)(m_encodeCtx->pSeqParams);
392 DDI_CODEC_CHK_NULL(av1SeqParams, "nullptr av1SeqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
393
394 av1SeqParams->seq_profile = seqParams->seq_profile;
395 av1SeqParams->seq_level_idx = seqParams->seq_level_idx;
396 av1SeqParams->GopPicSize = seqParams->intra_period;
397 av1SeqParams->GopRefDist = seqParams->ip_period;
398
399 switch ((uint32_t)m_encodeCtx->uiRCMethod)
400 {
401 case VA_RC_TCBRC:
402 case VA_RC_VBR:
403 av1SeqParams->RateControlMethod = (uint8_t)RATECONTROL_VBR;
404 break;
405 case VA_RC_CQP:
406 av1SeqParams->RateControlMethod = (uint8_t)RATECONTROL_CQP;
407 break;
408 case VA_RC_ICQ:
409 av1SeqParams->RateControlMethod = (uint8_t)RATECONTROL_CQL;
410 break;
411 default:
412 av1SeqParams->RateControlMethod = (uint8_t)RATECONTROL_CBR;
413 }
414
415 /* the bits_per_second is only used when the target bit_rate is not initialized */
416 if (av1SeqParams->TargetBitRate[0] == 0)
417 {
418 av1SeqParams->TargetBitRate[0] = MOS_ROUNDUP_DIVIDE(seqParams->bits_per_second, CODECHAL_ENCODE_BRC_KBPS);
419 }
420 av1SeqParams->MaxBitRate = MOS_ROUNDUP_DIVIDE(seqParams->bits_per_second, CODECHAL_ENCODE_BRC_KBPS);
421 av1SeqParams->MinBitRate = MOS_ROUNDUP_DIVIDE(seqParams->bits_per_second, CODECHAL_ENCODE_BRC_KBPS);
422
423 //set default same as application, can be overwritten by misc params
424 av1SeqParams->InitVBVBufferFullnessInBit = seqParams->bits_per_second;
425 av1SeqParams->VBVBufferSizeInBit = seqParams->bits_per_second << 1;
426
427 av1SeqParams->CodingToolFlags.fields.enable_order_hint = seqParams->seq_fields.bits.enable_order_hint;
428 av1SeqParams->CodingToolFlags.fields.enable_cdef = seqParams->seq_fields.bits.enable_cdef;
429 av1SeqParams->CodingToolFlags.fields.enable_warped_motion = seqParams->seq_fields.bits.enable_warped_motion;
430 av1SeqParams->CodingToolFlags.fields.enable_restoration = seqParams->seq_fields.bits.enable_restoration;
431
432 av1SeqParams->order_hint_bits_minus_1 = seqParams->order_hint_bits_minus_1;
433 #if VA_CHECK_VERSION(1, 16, 0)
434 av1SeqParams->SeqFlags.fields.HierarchicalFlag = seqParams->hierarchical_flag;
435 #else
436 av1SeqParams->SeqFlags.fields.HierarchicalFlag = seqParams->reserved8b;
437 #endif
438
439 return VA_STATUS_SUCCESS;
440 }
441
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)442 VAStatus DdiEncodeAV1::ParsePicParams(DDI_MEDIA_CONTEXT *mediaCtx, void *ptr)
443 {
444 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
445 DDI_CODEC_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
446 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
447
448 VAEncPictureParameterBufferAV1 *picParams = (VAEncPictureParameterBufferAV1 *)ptr;
449
450 PCODEC_AV1_ENCODE_PICTURE_PARAMS av1PicParams = (PCODEC_AV1_ENCODE_PICTURE_PARAMS)(m_encodeCtx->pPicParams);
451 DDI_CODEC_CHK_NULL(av1PicParams, "nullptr av1PicParams", VA_STATUS_ERROR_INVALID_PARAMETER);
452 MOS_ZeroMemory(av1PicParams, sizeof(CODEC_AV1_ENCODE_PICTURE_PARAMS));
453
454 av1PicParams->frame_width_minus1 = picParams->frame_width_minus_1;
455 av1PicParams->frame_height_minus1 = picParams->frame_height_minus_1;
456 av1PicParams->NumTileGroupsMinus1 = picParams->num_tile_groups_minus1;
457 av1PicParams->PicFlags.fields.EnableFrameOBU = picParams->picture_flags.bits.enable_frame_obu;
458
459 av1PicParams->LoopRestorationFlags.fields.yframe_restoration_type = picParams->loop_restoration_flags.bits.yframe_restoration_type;
460 av1PicParams->LoopRestorationFlags.fields.cbframe_restoration_type = picParams->loop_restoration_flags.bits.cbframe_restoration_type;
461 av1PicParams->LoopRestorationFlags.fields.crframe_restoration_type = picParams->loop_restoration_flags.bits.crframe_restoration_type;
462 av1PicParams->LoopRestorationFlags.fields.lr_unit_shift = picParams->loop_restoration_flags.bits.lr_unit_shift;
463 av1PicParams->LoopRestorationFlags.fields.lr_uv_shift = picParams->loop_restoration_flags.bits.lr_uv_shift;
464
465 if (picParams->num_tile_groups_minus1 > 0 && picParams->picture_flags.bits.enable_frame_obu)
466 {
467 return VA_STATUS_ERROR_INVALID_PARAMETER;
468 }
469
470 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_encodeCtx->RTtbl);
471
472 DDI_MEDIA_SURFACE *recon = MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, picParams->reconstructed_frame);
473
474 DDI_CODEC_CHK_RET(RegisterRTSurfaces(rtTbl, recon), "RegisterRTSurfaces failed");
475
476 SetupCodecPicture(
477 mediaCtx,
478 rtTbl,
479 &av1PicParams->CurrReconstructedPic,
480 picParams->reconstructed_frame,
481 false);
482
483 rtTbl->pCurrentReconTarget = recon;
484 DDI_CODEC_CHK_NULL(rtTbl->pCurrentReconTarget, "NULL rtTbl->pCurrentReconTarget", VA_STATUS_ERROR_INVALID_PARAMETER);
485
486 // curr origin pic
487 av1PicParams->CurrOriginalPic.FrameIdx = (uint8_t)GetRenderTargetID(rtTbl, rtTbl->pCurrentReconTarget);
488 av1PicParams->CurrOriginalPic.PicFlags = av1PicParams->CurrReconstructedPic.PicFlags;
489 av1PicParams->CurrOriginalPic.PicEntry = av1PicParams->CurrReconstructedPic.PicEntry;
490
491 // RefFrame List
492 for (uint32_t i = 0; i < 8; i++)
493 {
494 if (picParams->reference_frames[i] != VA_INVALID_SURFACE)
495 {
496 UpdateRegisteredRTSurfaceFlag(rtTbl, MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, picParams->reference_frames[i]));
497 }
498 SetupCodecPicture(
499 mediaCtx,
500 rtTbl,
501 &av1PicParams->RefFrameList[i],
502 picParams->reference_frames[i],
503 true);
504 }
505
506 // bitstream buffer
507 DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, picParams->coded_buf);
508 DDI_CODEC_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_PARAMETER);
509 RemoveFromStatusReportQueue(buf);
510 MediaLibvaCommonNext::MediaBufferToMosResource(buf, &(m_encodeCtx->resBitstreamBuffer));
511
512 //reference frame index
513 DDI_CODEC_CHK_RET(
514 MOS_SecureMemcpy(av1PicParams->ref_frame_idx,
515 sizeof(av1PicParams->ref_frame_idx),
516 picParams->ref_frame_idx,
517 sizeof(picParams->ref_frame_idx)),
518 "DDI: PicParams parsing failed!");
519
520 if ((picParams->picture_flags.bits.frame_type == intraOnlyFrame || picParams->picture_flags.bits.frame_type == keyFrame) &&
521 picParams->primary_ref_frame != av1PrimaryRefNone)
522 {
523 return VA_STATUS_ERROR_INVALID_PARAMETER;
524 }
525
526 av1PicParams->primary_ref_frame = picParams->primary_ref_frame;
527 av1PicParams->order_hint = picParams->order_hint;
528
529 av1PicParams->ref_frame_ctrl_l0.RefFrameCtrl.value = picParams->ref_frame_ctrl_l0.value;
530 av1PicParams->ref_frame_ctrl_l1.RefFrameCtrl.value = picParams->ref_frame_ctrl_l1.value;
531
532 if (picParams->picture_flags.bits.frame_type == sFrame && picParams->picture_flags.bits.error_resilient_mode != 1)
533 {
534 return VA_STATUS_ERROR_INVALID_PARAMETER;
535 }
536
537 // picture flags
538 av1PicParams->PicFlags.fields.frame_type = picParams->picture_flags.bits.frame_type;
539 av1PicParams->PicFlags.fields.error_resilient_mode = picParams->picture_flags.bits.error_resilient_mode;
540 av1PicParams->PicFlags.fields.disable_cdf_update = picParams->picture_flags.bits.disable_cdf_update;
541 av1PicParams->PicFlags.fields.allow_high_precision_mv = picParams->picture_flags.bits.allow_high_precision_mv;
542 av1PicParams->PicFlags.fields.use_ref_frame_mvs = picParams->picture_flags.bits.use_ref_frame_mvs;
543 av1PicParams->PicFlags.fields.disable_frame_end_update_cdf = picParams->picture_flags.bits.disable_frame_end_update_cdf;
544 av1PicParams->PicFlags.fields.reduced_tx_set_used = picParams->picture_flags.bits.reduced_tx_set;
545 av1PicParams->PicFlags.fields.EnableFrameOBU = picParams->picture_flags.bits.enable_frame_obu;
546 av1PicParams->PicFlags.fields.LongTermReference = picParams->picture_flags.bits.long_term_reference;
547 av1PicParams->PicFlags.fields.DisableFrameRecon = picParams->picture_flags.bits.disable_frame_recon;
548 av1PicParams->PicFlags.fields.PaletteModeEnable = picParams->picture_flags.bits.palette_mode_enable;
549 av1PicParams->PicFlags.fields.allow_intrabc = picParams->picture_flags.bits.allow_intrabc;
550 av1PicParams->PicFlags.fields.SegIdBlockSize = picParams->seg_id_block_size;
551
552 #if VA_CHECK_VERSION(1, 16, 0)
553 av1PicParams->HierarchLevelPlus1 = picParams->hierarchical_level_plus1;
554 #else
555 av1PicParams->HierarchLevelPlus1 = picParams->reserved8bits0;
556 #endif
557
558 DDI_CODEC_CHK_RET(
559 MOS_SecureMemcpy(av1PicParams->filter_level,
560 sizeof(av1PicParams->filter_level),
561 picParams->filter_level,
562 sizeof(picParams->filter_level)),
563 "DDI: PicParams parsing failed!");
564
565 av1PicParams->filter_level_u = picParams->filter_level_u;
566 av1PicParams->filter_level_v = picParams->filter_level_v;
567
568 av1PicParams->cLoopFilterInfoFlags.value = picParams->loop_filter_flags.value;
569 av1PicParams->interp_filter = picParams->interpolation_filter;
570
571 DDI_CODEC_CHK_RET(
572 MOS_SecureMemcpy(av1PicParams->ref_deltas,
573 sizeof(av1PicParams->ref_deltas),
574 picParams->ref_deltas,
575 sizeof(picParams->ref_deltas)),
576 "DDI: PicParams parsing failed!");
577
578 DDI_CODEC_CHK_RET(
579 MOS_SecureMemcpy(av1PicParams->mode_deltas,
580 sizeof(av1PicParams->mode_deltas),
581 picParams->mode_deltas,
582 sizeof(picParams->mode_deltas)),
583 "DDI: PicParams parsing failed!");
584
585 if (abs(picParams->y_dc_delta_q) > 15)
586 {
587 return VA_STATUS_ERROR_INVALID_PARAMETER;
588 }
589
590 av1PicParams->base_qindex = picParams->base_qindex;
591 av1PicParams->y_dc_delta_q = picParams->y_dc_delta_q;
592 av1PicParams->u_dc_delta_q = picParams->u_dc_delta_q;
593 av1PicParams->u_ac_delta_q = picParams->u_ac_delta_q;
594 av1PicParams->v_dc_delta_q = picParams->v_dc_delta_q;
595 av1PicParams->v_ac_delta_q = picParams->v_ac_delta_q;
596 av1PicParams->MinBaseQIndex = picParams->min_base_qindex;
597 av1PicParams->MaxBaseQIndex = picParams->max_base_qindex;
598
599 // Quatization Matrix is not supportted
600 if (picParams->qmatrix_flags.bits.using_qmatrix != 0)
601 {
602 DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing AV1 Picture parameter");
603 return VA_STATUS_ERROR_INVALID_PARAMETER;
604 }
605
606 av1PicParams->wQMatrixFlags.value = picParams->qmatrix_flags.value;
607
608 av1PicParams->dwModeControlFlags.value = picParams->mode_control_flags.value;
609
610 //segment params
611 av1PicParams->stAV1Segments.SegmentFlags.fields.segmentation_enabled = picParams->segments.seg_flags.bits.segmentation_enabled;
612 av1PicParams->stAV1Segments.SegmentFlags.fields.SegmentNumber = picParams->segments.segment_number;
613 av1PicParams->stAV1Segments.SegmentFlags.fields.update_map = picParams->segments.seg_flags.bits.segmentation_update_map;
614 av1PicParams->stAV1Segments.SegmentFlags.fields.temporal_update = picParams->segments.seg_flags.bits.segmentation_temporal_update;
615
616 DDI_CODEC_CHK_RET(
617 MOS_SecureMemcpy(av1PicParams->stAV1Segments.feature_data,
618 sizeof(av1PicParams->stAV1Segments.feature_data),
619 picParams->segments.feature_data,
620 sizeof(picParams->segments.feature_data)),
621 "DDI: PicParams parsing failed!");
622
623 DDI_CODEC_CHK_RET(
624 MOS_SecureMemcpy(av1PicParams->stAV1Segments.feature_mask,
625 sizeof(av1PicParams->stAV1Segments.feature_mask),
626 picParams->segments.feature_mask,
627 sizeof(picParams->segments.feature_mask)),
628 "DDI: PicParams parsing failed!");
629
630 av1PicParams->tile_cols = picParams->tile_cols;
631
632 DDI_CODEC_CHK_RET(
633 MOS_SecureMemcpy(av1PicParams->width_in_sbs_minus_1,
634 sizeof(av1PicParams->width_in_sbs_minus_1),
635 picParams->width_in_sbs_minus_1,
636 sizeof(picParams->width_in_sbs_minus_1)),
637 "DDI: PicParams parsing failed!");
638
639 av1PicParams->tile_rows = picParams->tile_rows;
640
641 DDI_CODEC_CHK_RET(
642 MOS_SecureMemcpy(av1PicParams->height_in_sbs_minus_1,
643 sizeof(av1PicParams->height_in_sbs_minus_1),
644 picParams->height_in_sbs_minus_1,
645 sizeof(picParams->height_in_sbs_minus_1)),
646 "DDI: PicParams parsing failed!");
647
648 DDI_CODEC_CHK_RET(CheckCDEF(picParams, mediaCtx->platform.eProductFamily), "invalid CDEF Paramter");
649
650 DDI_CODEC_CHK_RET(CheckTile(picParams), "invalid Tile Paramter");
651
652 av1PicParams->context_update_tile_id = picParams->context_update_tile_id;
653 av1PicParams->temporal_id = picParams->temporal_id;
654
655 av1PicParams->cdef_damping_minus_3 = picParams->cdef_damping_minus_3;
656 av1PicParams->cdef_bits = picParams->cdef_bits;
657
658 DDI_CODEC_CHK_RET(
659 MOS_SecureMemcpy(av1PicParams->cdef_y_strengths,
660 sizeof(av1PicParams->cdef_y_strengths),
661 picParams->cdef_y_strengths,
662 sizeof(picParams->cdef_y_strengths)),
663 "DDI: PicParams parsing failed!");
664
665 DDI_CODEC_CHK_RET(
666 MOS_SecureMemcpy(av1PicParams->cdef_uv_strengths,
667 sizeof(av1PicParams->cdef_uv_strengths),
668 picParams->cdef_uv_strengths,
669 sizeof(picParams->cdef_uv_strengths)),
670 "DDI: PicParams parsing failed!");
671
672 for(uint32_t i = 0; i < 7; i++)
673 {
674 av1PicParams->wm[i].wmtype = picParams->wm[i].wmtype;
675 av1PicParams->wm[i].invalid = picParams->wm[i].invalid;
676
677 DDI_CODEC_CHK_RET(
678 MOS_SecureMemcpy(av1PicParams->wm[i].wmmat,
679 sizeof(av1PicParams->wm[i].wmmat),
680 picParams->wm[i].wmmat,
681 sizeof(picParams->wm[i].wmmat)),
682 "DDI: PicParams parsing failed!");
683 }
684
685 av1PicParams->QIndexBitOffset = picParams->bit_offset_qindex;
686 av1PicParams->SegmentationBitOffset = picParams->bit_offset_segmentation;
687 av1PicParams->LoopFilterParamsBitOffset = picParams->bit_offset_loopfilter_params;
688 av1PicParams->CDEFParamsBitOffset = picParams->bit_offset_cdef_params;
689 av1PicParams->CDEFParamsSizeInBits = picParams->size_in_bits_cdef_params;
690 av1PicParams->FrameHdrOBUSizeByteOffset = picParams->byte_offset_frame_hdr_obu_size;
691 av1PicParams->FrameHdrOBUSizeInBits = picParams->size_in_bits_frame_hdr_obu;
692
693 av1PicParams->TileGroupOBUHdrInfo.value = picParams->tile_group_obu_hdr_info.value;
694
695 av1PicParams->NumSkipFrames = picParams->number_skip_frames;
696 av1PicParams->FrameSizeReducedInBytes = 0 - picParams->skip_frames_reduced_size;
697
698 return VA_STATUS_SUCCESS;
699 }
700
ParseTileGroupParams(void * ptr,uint32_t numTileGroupParams)701 VAStatus DdiEncodeAV1::ParseTileGroupParams(void *ptr, uint32_t numTileGroupParams)
702 {
703 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
704 DDI_CODEC_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
705
706 VAEncTileGroupBufferAV1 *vaEncTileGroupParams = (VAEncTileGroupBufferAV1 *)ptr;
707
708 PCODEC_AV1_ENCODE_TILE_GROUP_PARAMS av1TileGroupParams = (PCODEC_AV1_ENCODE_TILE_GROUP_PARAMS)m_encodeCtx->pSliceParams;
709 DDI_CODEC_CHK_NULL(av1TileGroupParams, "nullptr av1TileGroup", VA_STATUS_ERROR_INVALID_PARAMETER);
710
711 if (m_encodeCtx->dwNumSlices + numTileGroupParams > allocatedTileNum)
712 {
713 av1TileGroupParams = (PCODEC_AV1_ENCODE_TILE_GROUP_PARAMS)MOS_ReallocMemory(av1TileGroupParams,
714 (m_encodeCtx->dwNumSlices + numTileGroupParams + TILE_GROUP_NUM_INCREMENT)*sizeof(CODEC_AV1_ENCODE_TILE_GROUP_PARAMS));
715 DDI_CODEC_CHK_NULL(av1TileGroupParams, "nullptr av1TileGroupParams", VA_STATUS_ERROR_INVALID_PARAMETER);
716
717 allocatedTileNum = m_encodeCtx->dwNumSlices + numTileGroupParams + TILE_GROUP_NUM_INCREMENT;
718 m_encodeCtx->pSliceParams = (void *)av1TileGroupParams;
719 }
720
721 av1TileGroupParams += m_encodeCtx->dwNumSlices;
722 MOS_ZeroMemory(av1TileGroupParams, (numTileGroupParams*sizeof(CODEC_AV1_ENCODE_TILE_GROUP_PARAMS)));
723
724 for (uint32_t i = 0; i < numTileGroupParams; i++)
725 {
726 av1TileGroupParams->TileGroupStart = vaEncTileGroupParams->tg_start;
727 av1TileGroupParams->TileGroupEnd = vaEncTileGroupParams->tg_end;
728 av1TileGroupParams++;
729 vaEncTileGroupParams++;
730 }
731
732 m_encodeCtx->dwNumSlices += numTileGroupParams;
733
734 return VA_STATUS_SUCCESS;
735 }
736
ParsePackedHeaderParams(void * ptr)737 VAStatus DdiEncodeAV1::ParsePackedHeaderParams(void *ptr)
738 {
739 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
740 DDI_CODEC_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
741
742 VAEncPackedHeaderParameterBuffer *encPackedHeaderParamBuf = (VAEncPackedHeaderParameterBuffer *)ptr;
743
744 m_encodeCtx->ppNALUnitParams[m_encodeCtx->indexNALUnit]->bInsertEmulationBytes = (encPackedHeaderParamBuf->has_emulation_bytes) ? false : true;
745 m_encodeCtx->ppNALUnitParams[m_encodeCtx->indexNALUnit]->uiSkipEmulationCheckCount = 3;
746 m_encodeCtx->ppNALUnitParams[m_encodeCtx->indexNALUnit]->uiSize = (encPackedHeaderParamBuf->bit_length + 7) / 8;
747 m_encodeCtx->ppNALUnitParams[m_encodeCtx->indexNALUnit]->uiOffset = 0; // will be overwritten later.
748
749 return VA_STATUS_SUCCESS;
750 }
751
ParsePackedHeaderData(void * ptr)752 VAStatus DdiEncodeAV1::ParsePackedHeaderData(void *ptr)
753 {
754 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
755 DDI_CODEC_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
756
757 BSBuffer *bsBuffer = m_encodeCtx->pbsBuffer;
758 DDI_CODEC_CHK_NULL(bsBuffer, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
759
760 if (m_encodeCtx->indexNALUnit == 0)
761 {
762 bsBuffer->pCurrent = bsBuffer->pBase;
763 bsBuffer->SliceOffset = 0;
764 bsBuffer->BitOffset = 0;
765 bsBuffer->BitSize = 0;
766 }
767
768 uint32_t hdrDataSize = m_encodeCtx->ppNALUnitParams[m_encodeCtx->indexNALUnit]->uiSize;
769
770 DDI_CODEC_CHK_RET(
771 MOS_SecureMemcpy(bsBuffer->pCurrent, bsBuffer->BufferSize - bsBuffer->SliceOffset, (uint8_t *)ptr, hdrDataSize),
772 "DDI:packed header size is too large to be supported!");
773
774 m_encodeCtx->ppNALUnitParams[m_encodeCtx->indexNALUnit]->uiOffset = bsBuffer->pCurrent - bsBuffer->pBase;
775 m_encodeCtx->indexNALUnit++;
776
777 bsBuffer->pCurrent += hdrDataSize;
778 bsBuffer->SliceOffset += hdrDataSize;
779
780 return VA_STATUS_SUCCESS;
781 }
782
ParseMiscParams(void * ptr)783 VAStatus DdiEncodeAV1::ParseMiscParams(void *ptr)
784 {
785 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_enocdeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
786 DDI_CODEC_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
787
788 VAEncMiscParameterBuffer *miscParamBuf = (VAEncMiscParameterBuffer *)ptr;
789 DDI_CODEC_CHK_NULL(miscParamBuf->data, "nullptr miscParamBuf->data", VA_STATUS_ERROR_INVALID_PARAMETER);
790
791 VAStatus vaStatus = VA_STATUS_SUCCESS;
792 switch ((int32_t)(miscParamBuf->type))
793 {
794 case VAEncMiscParameterTypeHRD:
795 {
796 vaStatus = ParseMiscParamVBV((void *)miscParamBuf->data);
797 break;
798 }
799 case VAEncMiscParameterTypeFrameRate:
800 {
801 vaStatus = ParseMiscParamFR((void *)miscParamBuf->data);
802 break;
803 }
804 case VAEncMiscParameterTypeRateControl:
805 {
806 vaStatus = ParseMiscParamRC((void *)miscParamBuf->data);
807 break;
808 }
809 case VAEncMiscParameterTypeEncQuality:
810 {
811 vaStatus = ParseMiscParamEncQuality((void *)miscParamBuf->data);
812 break;
813 }
814 case VAEncMiscParameterTypeTemporalLayerStructure:
815 {
816 vaStatus = ParseMiscParamTemporalLayerParams((void *)miscParamBuf->data);
817 break;
818 }
819 case VAEncMiscParameterTypeQualityLevel:
820 {
821 vaStatus = ParseMiscParamQualityLevel((void *)miscParamBuf->data);
822 break;
823 }
824 case VAEncMiscParameterTypeMaxFrameSize:
825 {
826 vaStatus = ParseMiscParamMaxFrameSize((void *)miscParamBuf->data);
827 break;
828 }
829 default:
830 {
831 DDI_CODEC_ASSERTMESSAGE("DDI: unsupported misc parameter type.");
832 return VA_STATUS_ERROR_INVALID_PARAMETER;
833 }
834 }
835
836 return vaStatus;
837 }
838
ParseSegMapParams(void * ptr)839 VAStatus DdiEncodeAV1::ParseSegMapParams(void *ptr)
840 {
841 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_enocdeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
842 DDI_CODEC_CHK_NULL(ptr, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
843
844 VAEncSegMapBufferAV1 *vaEncSegMapBuf = (VAEncSegMapBufferAV1 *)ptr;
845 m_isSegParamsChanged = true;
846
847 m_encodeCtx->segmentMapDataSize = vaEncSegMapBuf->segmentMapDataSize;
848 m_encodeCtx->pSegmentMap = vaEncSegMapBuf->pSegmentMap;
849
850 return VA_STATUS_SUCCESS;
851 }
852
ParseMiscParamVBV(void * data)853 VAStatus DdiEncodeAV1::ParseMiscParamVBV(void *data)
854 {
855 DDI_CODEC_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
856
857 VAEncMiscParameterHRD *vaEncMiscParamHRD = (VAEncMiscParameterHRD *)data;
858
859 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)m_encodeCtx->pSeqParams;
860 DDI_CODEC_CHK_NULL(seqParams, "nullptr seqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
861
862 seqParams->VBVBufferSizeInBit = vaEncMiscParamHRD->buffer_size;
863 seqParams->InitVBVBufferFullnessInBit = vaEncMiscParamHRD->initial_buffer_fullness;
864
865 return VA_STATUS_SUCCESS;
866 }
867
ParseMiscParamFR(void * data)868 VAStatus DdiEncodeAV1::ParseMiscParamFR(void *data)
869 {
870 DDI_CODEC_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
871
872 VAEncMiscParameterFrameRate *vaFrameRate = (VAEncMiscParameterFrameRate *)data;
873
874 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)m_encodeCtx->pSeqParams;
875 DDI_CODEC_CHK_NULL(seqParams, "nullptr seqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
876
877 if (vaFrameRate->framerate_flags.bits.temporal_id > seqParams->NumTemporalLayersMinus1)
878 {
879 return VA_STATUS_ERROR_INVALID_PARAMETER;
880 }
881
882 uint32_t temporalId = vaFrameRate->framerate_flags.bits.temporal_id;
883
884 if (vaFrameRate->framerate != savedFrameRate[temporalId])
885 {
886 savedFrameRate[temporalId] = vaFrameRate->framerate;
887 //seqParams->SeqFlags.fields.ResetBRC |= 0x1;
888
889 uint32_t frameRate = vaFrameRate->framerate;
890 seqParams->FrameRate[temporalId].Numerator = frameRate &(0xFFFF);
891 seqParams->FrameRate[temporalId].Denominator = (frameRate >> 16) &(0xFFFF);
892
893 if (seqParams->FrameRate[temporalId].Denominator == 0)
894 {
895 return VA_STATUS_ERROR_INVALID_PARAMETER;
896 }
897 }
898
899 return VA_STATUS_SUCCESS;
900 }
901
902 // Parse rate control related information from app.
ParseMiscParamRC(void * data)903 VAStatus DdiEncodeAV1::ParseMiscParamRC(void *data)
904 {
905 DDI_CODEC_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
906
907 VAEncMiscParameterRateControl *vaEncMiscParamRC = (VAEncMiscParameterRateControl *)data;
908
909 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)m_encodeCtx->pSeqParams;
910 DDI_CODEC_CHK_NULL(seqParams, "nullptr seqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
911
912 uint32_t temporalId = vaEncMiscParamRC->rc_flags.bits.temporal_id;
913 DDI_CHK_LESS(temporalId, (seqParams->NumTemporalLayersMinus1 + 1),
914 "invalid temporal id", VA_STATUS_ERROR_INVALID_PARAMETER);
915
916 uint32_t bitRate = MOS_ROUNDUP_DIVIDE(vaEncMiscParamRC->bits_per_second, CODECHAL_ENCODE_BRC_KBPS);
917 seqParams->MaxBitRate = MOS_MAX(seqParams->MaxBitRate, bitRate);
918 seqParams->SeqFlags.fields.ResetBRC = vaEncMiscParamRC->rc_flags.bits.reset;
919
920 if (VA_RC_CBR == m_encodeCtx->uiRCMethod)
921 {
922 if(vaEncMiscParamRC->target_percentage != 0)
923 seqParams->TargetBitRate[temporalId] = bitRate * vaEncMiscParamRC->target_percentage / 100;
924 else
925 seqParams->TargetBitRate[temporalId] = bitRate;
926 seqParams->MaxBitRate = seqParams->TargetBitRate[temporalId];
927 seqParams->MinBitRate = seqParams->TargetBitRate[temporalId];
928 seqParams->RateControlMethod = RATECONTROL_CBR;
929 if (savedTargetBit[temporalId] != bitRate)
930 {
931 if (savedTargetBit[temporalId] != 0)
932 {
933 seqParams->SeqFlags.fields.ResetBRC |= 0x01;
934 }
935 savedTargetBit[temporalId] = bitRate;
936 }
937 }
938 else if (VA_RC_VBR == m_encodeCtx->uiRCMethod)
939 {
940 if(vaEncMiscParamRC->target_percentage != 0)
941 seqParams->TargetBitRate[temporalId] = bitRate * vaEncMiscParamRC->target_percentage / 100;
942 else
943 seqParams->TargetBitRate[temporalId] = bitRate;
944 seqParams->MaxBitRate = bitRate;
945 seqParams->MinBitRate = 0;
946 seqParams->RateControlMethod = RATECONTROL_VBR;
947
948 if ((savedTargetBit[temporalId] != seqParams->TargetBitRate[temporalId]) ||
949 (savedMaxBitRate[temporalId] != bitRate))
950 {
951 if ((savedTargetBit[temporalId] != 0) && (savedMaxBitRate[temporalId] != 0))
952 {
953 seqParams->SeqFlags.fields.ResetBRC |= 0x01;
954 }
955 savedTargetBit[temporalId] = seqParams->TargetBitRate[temporalId];
956 savedMaxBitRate[temporalId] = bitRate;
957 }
958 }
959 else if (VA_RC_ICQ == m_encodeCtx->uiRCMethod)
960 {
961 seqParams->RateControlMethod = RATECONTROL_CQL;
962 seqParams->ICQQualityFactor = vaEncMiscParamRC->quality_factor;
963 if (savedQualityFactor != seqParams->ICQQualityFactor)
964 {
965 if (savedQualityFactor != 0)
966 {
967 seqParams->SeqFlags.fields.ResetBRC |= 0x01;
968 }
969 savedQualityFactor = seqParams->ICQQualityFactor;
970 }
971 }
972
973 /* the reset flag in RC will be considered. */
974 seqParams->SeqFlags.fields.ResetBRC |= vaEncMiscParamRC->rc_flags.bits.reset;
975
976 return VA_STATUS_SUCCESS;
977 }
978
ParseMiscParamEncQuality(void * data)979 VAStatus DdiEncodeAV1::ParseMiscParamEncQuality(void *data)
980 {
981 DDI_CODEC_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
982
983 VAEncMiscParameterEncQuality *vaEncMiscParamEncQuality = (VAEncMiscParameterEncQuality *)data;
984
985 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)m_encodeCtx->pSeqParams;
986 DDI_CODEC_CHK_NULL(seqParams, "nullptr seqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
987
988 seqParams->SeqFlags.fields.UseRawReconRef = vaEncMiscParamEncQuality->useRawPicForRef;
989
990 return VA_STATUS_SUCCESS;
991 }
992
ParseMiscParamTemporalLayerParams(void * data)993 VAStatus DdiEncodeAV1::ParseMiscParamTemporalLayerParams(void* data)
994 {
995 DDI_CODEC_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
996
997 VAEncMiscParameterTemporalLayerStructure *vaEncTempLayerStruct = (VAEncMiscParameterTemporalLayerStructure *)data;
998 DDI_CHK_LESS(vaEncTempLayerStruct->number_of_layers, (ENCODE_AV1_MAX_NUM_TEMPORAL_LAYERS+1),
999 "invalid number of temporal layers", VA_STATUS_ERROR_INVALID_PARAMETER);
1000
1001 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)m_encodeCtx->pSeqParams;
1002 DDI_CODEC_CHK_NULL(seqParams, "nullptr seqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
1003
1004 if (vaEncTempLayerStruct->number_of_layers > 0)
1005 {
1006 seqParams->NumTemporalLayersMinus1 = vaEncTempLayerStruct->number_of_layers - 1;
1007 }
1008 else
1009 {
1010 seqParams->NumTemporalLayersMinus1 = 0;
1011 }
1012
1013 return VA_STATUS_SUCCESS;
1014 }
1015
ParseMiscParamQualityLevel(void * data)1016 VAStatus DdiEncodeAV1::ParseMiscParamQualityLevel(void *data)
1017 {
1018 DDI_CODEC_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
1019 DDI_CODEC_CHK_NULL(m_encodeCtx, "nullptr m_enocdeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
1020
1021 VAEncMiscParameterBufferQualityLevel *vaEncMiscParamQualityLevel = (VAEncMiscParameterBufferQualityLevel *)data;
1022 m_encodeCtx->targetUsage = (uint8_t)vaEncMiscParamQualityLevel->quality_level;
1023
1024 return VA_STATUS_SUCCESS;
1025 }
1026
ParseMiscParamMaxFrameSize(void * data)1027 VAStatus DdiEncodeAV1::ParseMiscParamMaxFrameSize(void *data)
1028 {
1029 DDI_CODEC_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
1030
1031 VAEncMiscParameterBufferMaxFrameSize *vaEncMiscParamMaxFrameSize = (VAEncMiscParameterBufferMaxFrameSize *)data;
1032
1033 PCODEC_AV1_ENCODE_SEQUENCE_PARAMS seqParams = (PCODEC_AV1_ENCODE_SEQUENCE_PARAMS)m_encodeCtx->pSeqParams;
1034 DDI_CODEC_CHK_NULL(seqParams, "nullptr seqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
1035
1036 seqParams->UserMaxIFrameSize = vaEncMiscParamMaxFrameSize->max_frame_size >> 3; // convert to bytes.
1037 seqParams->UserMaxPBFrameSize = vaEncMiscParamMaxFrameSize->max_frame_size >> 3;
1038
1039 return VA_STATUS_SUCCESS;
1040 }
1041
CheckCDEF(const VAEncPictureParameterBufferAV1 * picParams,PRODUCT_FAMILY platform)1042 VAStatus DdiEncodeAV1::CheckCDEF(const VAEncPictureParameterBufferAV1 *picParams, PRODUCT_FAMILY platform)
1043 {
1044 DDI_CODEC_CHK_NULL(picParams, "nullptr picParams", VA_STATUS_ERROR_INVALID_PARAMETER);
1045
1046 if (picParams->cdef_damping_minus_3 > av1MaxCDEFDampingMinus3)
1047 {
1048 DDI_CODEC_ASSERTMESSAGE("The CDEF damping exceeds the max value.");
1049 return VA_STATUS_ERROR_INVALID_PARAMETER;
1050 }
1051
1052 if (picParams->cdef_bits > av1MaxCDEFBits)
1053 {
1054 DDI_CODEC_ASSERTMESSAGE("The CDEF bits exceed the max value.");
1055 return VA_STATUS_ERROR_INVALID_PARAMETER;
1056 }
1057
1058 for (uint32_t i = 0; i < av1MaxCDEFEntries; i++)
1059 {
1060 if (picParams->cdef_y_strengths[i] > av1MaxCDEFStrengths)
1061 {
1062 DDI_CODEC_ASSERTMESSAGE("The CDEF strengths exceed the max value.");
1063 return VA_STATUS_ERROR_INVALID_PARAMETER;
1064 }
1065
1066 if (picParams->cdef_uv_strengths[i] > av1MaxCDEFStrengths)
1067 {
1068 DDI_CODEC_ASSERTMESSAGE("The CDEF strengths exceed the max value.");
1069 return VA_STATUS_ERROR_INVALID_PARAMETER;
1070 }
1071
1072 if (picParams->cdef_uv_strengths[i] != picParams->cdef_y_strengths[i] && platform <= IGFX_DG2)
1073 {
1074 DDI_CODEC_ASSERTMESSAGE("Non-uniform CDEF strength of Y/UV are not supported for DG2.");
1075 return VA_STATUS_ERROR_INVALID_PARAMETER;
1076 }
1077 }
1078 return VA_STATUS_SUCCESS;
1079 }
1080
CheckTile(const VAEncPictureParameterBufferAV1 * picParams)1081 VAStatus DdiEncodeAV1::CheckTile(const VAEncPictureParameterBufferAV1 *picParams)
1082 {
1083 int minTileHeightInSB = picParams->height_in_sbs_minus_1[0] + 1;
1084 int minTileWidthInSB = picParams->width_in_sbs_minus_1[0] + 1;
1085
1086 for(int i = 1;i < picParams->tile_cols;i++)
1087 {
1088 minTileWidthInSB = MOS_MIN(minTileWidthInSB, picParams->width_in_sbs_minus_1[i] + 1);
1089 }
1090 for(int i = 1;i < picParams->tile_rows;i++)
1091 {
1092 minTileHeightInSB = MOS_MIN(minTileHeightInSB, picParams->height_in_sbs_minus_1[i] + 1);
1093 }
1094
1095 if(minTileWidthInSB * minTileHeightInSB < 4 ||
1096 minTileWidthInSB < 2 ||
1097 minTileHeightInSB < 2)
1098 {
1099 DDI_CODEC_ASSERTMESSAGE("Unsupported Tile Size");
1100 return VA_STATUS_ERROR_INVALID_PARAMETER;
1101 }
1102
1103 return VA_STATUS_SUCCESS;
1104 }
1105
SetupCodecPicture(DDI_MEDIA_CONTEXT * mediaCtx,DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,CODEC_PICTURE * codecHalPic,VASurfaceID surfaceID,bool picReference)1106 void DdiEncodeAV1::SetupCodecPicture(
1107 DDI_MEDIA_CONTEXT *mediaCtx,
1108 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl,
1109 CODEC_PICTURE *codecHalPic,
1110 VASurfaceID surfaceID,
1111 bool picReference)
1112 {
1113 if (VA_INVALID_SURFACE != surfaceID)
1114 {
1115 DDI_MEDIA_SURFACE *surface = MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, surfaceID);
1116 codecHalPic->FrameIdx = GetRenderTargetID(rtTbl, surface);
1117 codecHalPic->PicEntry = codecHalPic->FrameIdx;
1118 }
1119 else
1120 {
1121 codecHalPic->FrameIdx = (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX;
1122 codecHalPic->PicEntry = 0xFF;
1123 }
1124
1125 if (picReference)
1126 {
1127 if (codecHalPic->FrameIdx == (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX)
1128 {
1129 codecHalPic->PicFlags = PICTURE_INVALID;
1130 }
1131 else
1132 {
1133 codecHalPic->PicFlags = PICTURE_SHORT_TERM_REFERENCE;
1134 }
1135 }
1136 else
1137 {
1138 codecHalPic->PicFlags = PICTURE_FRAME;
1139 }
1140 }
1141
getSequenceParameterBufferSize()1142 uint32_t DdiEncodeAV1::getSequenceParameterBufferSize()
1143 {
1144 return sizeof(VAEncSequenceParameterBufferAV1);
1145 }
1146
getPictureParameterBufferSize()1147 uint32_t DdiEncodeAV1::getPictureParameterBufferSize()
1148 {
1149 return sizeof(VAEncPictureParameterBufferAV1);
1150 }
1151
getSliceParameterBufferSize()1152 uint32_t DdiEncodeAV1::getSliceParameterBufferSize()
1153 {
1154 return sizeof(VAEncTileGroupBufferAV1);
1155 }
1156
1157
GetEncodeCodecFunction(VAProfile profile,VAEntrypoint entrypoint,bool bVDEnc)1158 CODECHAL_FUNCTION DdiEncodeAV1::GetEncodeCodecFunction(VAProfile profile, VAEntrypoint entrypoint, bool bVDEnc)
1159 {
1160 CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_INVALID;
1161 if (bVDEnc)
1162 {
1163 codecFunction = CODECHAL_FUNCTION_ENC_VDENC_PAK;
1164 }
1165 else
1166 {
1167 DDI_CODEC_ASSERTMESSAGE("Unsuported CODECHAL_FUNCTION");
1168 }
1169 return codecFunction;
1170 }
1171
GetEncodeCodecMode(VAProfile profile,VAEntrypoint entrypoint)1172 CODECHAL_MODE DdiEncodeAV1::GetEncodeCodecMode(
1173 VAProfile profile,
1174 VAEntrypoint entrypoint)
1175 {
1176 switch (profile)
1177 {
1178 case VAProfileAV1Profile0:
1179 case VAProfileAV1Profile1:
1180 return CODECHAL_ENCODE_MODE_AV1;
1181 default:
1182 DDI_CODEC_ASSERTMESSAGE("Unsuported CODECHAL_MODE");
1183 return CODECHAL_UNSUPPORTED_MODE;
1184 }
1185 }
1186
1187 } // namespace encode