xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/codec/ddi/media_ddi_encode_av1.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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