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