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