xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/codec/ddi/media_ddi_decode_av1.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2017-2023, 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_decode_av1.cpp
24 //! \brief    The class implementation of DdiDecodeAV1  for AV1 decode
25 //!
26 
27 #include "media_libva_decoder.h"
28 #include "media_libva_util.h"
29 #include "media_ddi_decode_av1.h"
30 #include "mos_solo_generic.h"
31 #include "codechal_memdecomp.h"
32 #include "media_ddi_decode_const.h"
33 #include "media_ddi_factory.h"
34 #include "codec_def_decode_av1.h"
35 #include "codec_def_common_av1.h"
36 
37 /**
38  * @brief Perse tile parameter
39  *
40  * Method Perse tile parameter from application and fill
41  *
42  * @param
43  *
44  * @return
45  */
ParseTileParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferAV1 * slcParam,uint32_t numTiles)46 VAStatus DdiDecodeAV1::ParseTileParams(
47     DDI_MEDIA_CONTEXT         *mediaCtx,
48     VASliceParameterBufferAV1 *slcParam,
49     uint32_t                   numTiles)
50 {
51     CodecAv1TileParams     *tileParams;
52     VASliceParameterBufferAV1 *pTileCtrl = nullptr;
53 
54     // if number of tile group exceed av1MaxTileNum, need to increase the memory
55     if (av1MaxTileNum < numTiles)
56     {
57         DDI_ASSERTMESSAGE("numTiles = %d : exceeds av1MaxTileNum = %d", numTiles, av1MaxTileNum);
58         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
59     }
60 
61     pTileCtrl = slcParam;
62     tileParams = (CodecAv1TileParams*)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
63     tileParams += m_ddiDecodeCtx->DecodeParams.m_numSlices;
64 
65     MOS_ZeroMemory(tileParams, (numTiles * sizeof(CodecAv1TileParams)));
66 
67     uint32_t sliceBaseOffset;
68     sliceBaseOffset = GetBsBufOffset(m_groupIndex);
69 
70     for (auto idx = 0; idx < numTiles; idx++) {
71         tileParams->m_bsTileDataLocation        = sliceBaseOffset + pTileCtrl->slice_data_offset;
72         tileParams->m_bsTileBytesInBuffer       = pTileCtrl->slice_data_size;
73 
74         tileParams->m_badBSBufferChopping       = 0;                             // app doesn't have this
75         tileParams->m_tileRow                   = pTileCtrl->tile_row;
76         tileParams->m_tileColumn                = pTileCtrl->tile_column;
77 
78         tileParams->m_anchorFrameIdx.FrameIdx   = pTileCtrl->anchor_frame_idx;
79         tileParams->m_tileIndex                 = pTileCtrl->tile_idx_in_tile_list;
80         tileParams->m_anchorFrameIdx.PicFlags   = PICTURE_FRAME;
81         tileParams->m_anchorFrameIdx.PicEntry   = 0;                             // debug only
82 
83         tileParams->m_bsTilePayloadSizeInBytes  = pTileCtrl->slice_data_size;
84 
85         tileParams++;
86         pTileCtrl++;
87     }
88 
89     return VA_STATUS_SUCCESS;
90 }
91 
CalcAv1TileLog2(uint32_t blockSize,uint32_t target)92 static uint32_t CalcAv1TileLog2(uint32_t blockSize, uint32_t target)
93 {
94     uint32_t k;
95     for (k = 0; (blockSize << k) < target; k++) {}
96     return k;
97 }
98 
99 /**
100  * @brief AV1 Picture paramter parser
101  *
102  * Method Parse AV1 parametr
103  *
104  * @param medmaiCtx
105  * @param picParam
106  *
107  * @retrun VA status
108  *
109  */
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VADecPictureParameterBufferAV1 * picParam)110 VAStatus DdiDecodeAV1::ParsePicParams(
111     DDI_MEDIA_CONTEXT              *mediaCtx,
112     VADecPictureParameterBufferAV1 *picParam)
113 {
114     CodecAv1PicParams* picAV1Params = (CodecAv1PicParams*)(m_ddiDecodeCtx->DecodeParams.m_picParams);
115 
116     if ((picParam == nullptr) || (picAV1Params == nullptr))
117     {
118         DDI_ASSERTMESSAGE("Invalid Parameter for Parsing AV1 Picture parameter\n");
119         return VA_STATUS_ERROR_INVALID_PARAMETER;
120     }
121 
122     /***************************************************************************
123      Setup current picture
124      **************************************************************************/
125     int32_t frameIdx = GetRenderTargetID(&m_ddiDecodeCtx->RTtbl, m_ddiDecodeCtx->RTtbl.pCurrentRT);
126     if (frameIdx == DDI_CODEC_INVALID_FRAME_INDEX)
127     {
128         return VA_STATUS_ERROR_INVALID_PARAMETER;
129     }
130     picAV1Params->m_currPic.FrameIdx = frameIdx;
131 
132     picAV1Params->m_profile                                          = picParam->profile;
133     picAV1Params->m_anchorFrameInsertion                             = 0;
134     picAV1Params->m_anchorFrameNum                                   = picParam->anchor_frames_num;
135 
136     if (picAV1Params->m_anchorFrameNum > 0)
137     {
138         if (picParam->anchor_frames_num <= MAX_ANCHOR_FRAME_NUM_AV1)
139         {
140             MOS_SecureMemcpy(anchorFrameListVA, picParam->anchor_frames_num * sizeof(VASurfaceID),
141                              picParam->anchor_frames_list, picParam->anchor_frames_num * sizeof(VASurfaceID));
142         }
143         else
144         {
145             return VA_STATUS_ERROR_INVALID_PARAMETER;
146         }
147     }
148 
149     picAV1Params->m_orderHintBitsMinus1                              = picParam->order_hint_bits_minus_1;
150     picAV1Params->m_bitDepthIdx                                      = picParam->bit_depth_idx;
151 
152     picAV1Params->m_superResUpscaledWidthMinus1                      = picParam->frame_width_minus1;
153     picAV1Params->m_superResUpscaledHeightMinus1                     = picParam->frame_height_minus1;
154     picAV1Params->m_matrixCoefficients                               = picParam->matrix_coefficients;
155 
156     /***************************************************************************
157      Sequence Info
158     ***************************************************************************/
159     picAV1Params->m_seqInfoFlags.m_fields.m_stillPicture             = picParam->seq_info_fields.fields.still_picture;
160     picAV1Params->m_seqInfoFlags.m_fields.m_use128x128Superblock     = picParam->seq_info_fields.fields.use_128x128_superblock;
161     picAV1Params->m_seqInfoFlags.m_fields.m_enableFilterIntra        = picParam->seq_info_fields.fields.enable_filter_intra;
162     picAV1Params->m_seqInfoFlags.m_fields.m_enableIntraEdgeFilter    = picParam->seq_info_fields.fields.enable_intra_edge_filter;
163 
164     picAV1Params->m_seqInfoFlags.m_fields.m_enableInterintraCompound = picParam->seq_info_fields.fields.enable_interintra_compound;
165     picAV1Params->m_seqInfoFlags.m_fields.m_enableMaskedCompound     = picParam->seq_info_fields.fields.enable_masked_compound;
166 
167     picAV1Params->m_seqInfoFlags.m_fields.m_enableDualFilter         = picParam->seq_info_fields.fields.enable_dual_filter;
168     picAV1Params->m_seqInfoFlags.m_fields.m_enableOrderHint          = picParam->seq_info_fields.fields.enable_order_hint;
169     picAV1Params->m_seqInfoFlags.m_fields.m_enableJntComp            = picParam->seq_info_fields.fields.enable_jnt_comp;
170     picAV1Params->m_seqInfoFlags.m_fields.m_enableCdef               = picParam->seq_info_fields.fields.enable_cdef;
171     picAV1Params->m_seqInfoFlags.m_fields.m_reserved3b               = 0;
172 
173     picAV1Params->m_seqInfoFlags.m_fields.m_monoChrome               = picParam->seq_info_fields.fields.mono_chrome;
174     picAV1Params->m_seqInfoFlags.m_fields.m_colorRange               = picParam->seq_info_fields.fields.color_range;
175     picAV1Params->m_seqInfoFlags.m_fields.m_subsamplingX             = picParam->seq_info_fields.fields.subsampling_x;
176     picAV1Params->m_seqInfoFlags.m_fields.m_subsamplingY             = picParam->seq_info_fields.fields.subsampling_y;
177     picAV1Params->m_seqInfoFlags.m_fields.m_filmGrainParamsPresent   = picParam->seq_info_fields.fields.film_grain_params_present;
178     picAV1Params->m_seqInfoFlags.m_fields.m_reservedSeqInfoBits      = 0;
179 
180 
181     /****************************************************************************
182      Picture Info
183     ****************************************************************************/
184     picAV1Params->m_picInfoFlags.m_fields.m_frameType                = picParam->pic_info_fields.bits.frame_type;
185     picAV1Params->m_picInfoFlags.m_fields.m_showFrame                = picParam->pic_info_fields.bits.show_frame;
186     picAV1Params->m_picInfoFlags.m_fields.m_showableFrame            = picParam->pic_info_fields.bits.showable_frame;
187     picAV1Params->m_picInfoFlags.m_fields.m_errorResilientMode       = picParam->pic_info_fields.bits.error_resilient_mode;
188     picAV1Params->m_picInfoFlags.m_fields.m_disableCdfUpdate         = picParam->pic_info_fields.bits.disable_cdf_update;
189     picAV1Params->m_picInfoFlags.m_fields.m_allowScreenContentTools  = picParam->pic_info_fields.bits.allow_screen_content_tools;
190 
191     picAV1Params->m_picInfoFlags.m_fields.m_forceIntegerMv           = picParam->pic_info_fields.bits.force_integer_mv;
192     picAV1Params->m_picInfoFlags.m_fields.m_allowIntrabc             = picParam->pic_info_fields.bits.allow_intrabc;
193 
194     picAV1Params->m_picInfoFlags.m_fields.m_useSuperres              = picParam->pic_info_fields.bits.use_superres;
195     picAV1Params->m_picInfoFlags.m_fields.m_allowHighPrecisionMv     = picParam->pic_info_fields.bits.allow_high_precision_mv;
196     picAV1Params->m_picInfoFlags.m_fields.m_isMotionModeSwitchable   = picParam->pic_info_fields.bits.is_motion_mode_switchable;
197     picAV1Params->m_picInfoFlags.m_fields.m_useRefFrameMvs           = picParam->pic_info_fields.bits.use_ref_frame_mvs;
198     picAV1Params->m_picInfoFlags.m_fields.m_disableFrameEndUpdateCdf = picParam->pic_info_fields.bits.disable_frame_end_update_cdf;
199     picAV1Params->m_picInfoFlags.m_fields.m_uniformTileSpacingFlag   = picParam->pic_info_fields.bits.uniform_tile_spacing_flag;
200     picAV1Params->m_picInfoFlags.m_fields.m_allowWarpedMotion        = picParam->pic_info_fields.bits.allow_warped_motion;
201     picAV1Params->m_picInfoFlags.m_fields.m_largeScaleTile           = picParam->pic_info_fields.bits.large_scale_tile;
202     picAV1Params->m_picInfoFlags.m_fields.m_reservedPicInfoBits      = 0;
203 
204 
205     /***************************************************************************
206         Setup reference frames
207     ***************************************************************************/
208     for (auto i = 0; i < 8; i++)
209     {
210         PDDI_MEDIA_SURFACE refSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->ref_frame_map[i]);
211 
212         if (picParam->ref_frame_map[i] < mediaCtx->uiNumSurfaces)
213         {
214             frameIdx = GetRenderTargetID(&m_ddiDecodeCtx->RTtbl, refSurface);
215 
216             if ((frameIdx == DDI_CODEC_INVALID_FRAME_INDEX) &&
217                 (picParam->pic_info_fields.bits.frame_type != keyFrame) &&
218                 (picParam->pic_info_fields.bits.frame_type != intraOnlyFrame))
219             {
220                  return VA_STATUS_ERROR_INVALID_PARAMETER;
221             }
222 
223             picAV1Params->m_refFrameMap[i].FrameIdx = ((uint32_t)frameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_AV1) ?
224                                                       (CODECHAL_NUM_UNCOMPRESSED_SURFACE_AV1 - 1) : frameIdx;
225         }
226         else
227         {
228             if (refSurface != nullptr)
229             {
230                 frameIdx = GetRenderTargetID(&m_ddiDecodeCtx->RTtbl, refSurface);
231                 if (frameIdx != DDI_CODEC_INVALID_FRAME_INDEX)
232                 {
233                     picAV1Params->m_refFrameMap[i].FrameIdx = ((uint32_t)frameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_AV1) ?
234                                                               (CODECHAL_NUM_UNCOMPRESSED_SURFACE_AV1 - 1) : frameIdx;
235                 }
236                 else
237                 {
238                     picAV1Params->m_refFrameMap[i].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_AV1 - 1;
239                 }
240             }
241             else
242             {
243                 picAV1Params->m_refFrameMap[i].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_AV1 - 1;
244             }
245         }
246     }
247 
248 
249     MOS_SecureMemcpy(picAV1Params->m_refFrameIdx, 7, picParam->ref_frame_idx, 7);
250 
251 
252     picAV1Params->m_primaryRefFrame                = picParam->primary_ref_frame;
253 
254     picAV1Params->m_outputFrameWidthInTilesMinus1  = picParam->output_frame_width_in_tiles_minus_1;
255     picAV1Params->m_outputFrameHeightInTilesMinus1 = picParam->output_frame_height_in_tiles_minus_1;
256     picAV1Params->m_reserved32b2                   = 0;
257 
258 
259     /****************************************************************************
260      Deblocking filter
261     ****************************************************************************/
262     picAV1Params->m_filterLevel[0]         = picParam->filter_level[0];
263     picAV1Params->m_filterLevel[1]         = picParam->filter_level[1];
264     picAV1Params->m_filterLevelU           = picParam->filter_level_u;
265     picAV1Params->m_filterLevelV           = picParam->filter_level_v;
266 
267 
268     /****************************************************************************
269       Loop filter info
270     ****************************************************************************/
271     picAV1Params->m_loopFilterInfoFlags.m_fields.m_sharpnessLevel      = picParam->loop_filter_info_fields.bits.sharpness_level;
272     picAV1Params->m_loopFilterInfoFlags.m_fields.m_modeRefDeltaEnabled = picParam->loop_filter_info_fields.bits.mode_ref_delta_enabled;
273     picAV1Params->m_loopFilterInfoFlags.m_fields.m_modeRefDeltaUpdate  = picParam->loop_filter_info_fields.bits.mode_ref_delta_update;
274     picAV1Params->m_loopFilterInfoFlags.m_fields.m_reservedField       = 0;
275 
276     picAV1Params->m_orderHint                      = picParam->order_hint;
277     picAV1Params->m_superresScaleDenominator       = picParam->superres_scale_denominator;
278     picAV1Params->m_interpFilter                   = picParam->interp_filter;
279 
280     MOS_SecureMemcpy(picAV1Params->m_refDeltas, 8, picParam->ref_deltas, 8);
281     MOS_SecureMemcpy(picAV1Params->m_modeDeltas, 2, picParam->mode_deltas, 2);
282 
283 
284     /****************************************************************************
285      Quantization
286     ****************************************************************************/
287     picAV1Params->m_baseQindex  = picParam->base_qindex;
288     picAV1Params->m_yDcDeltaQ   = picParam->y_dc_delta_q;
289     picAV1Params->m_uDcDeltaQ   = picParam->u_dc_delta_q;
290     picAV1Params->m_uAcDeltaQ   = picParam->u_ac_delta_q;
291     picAV1Params->m_vDcDeltaQ   = picParam->v_dc_delta_q;
292     picAV1Params->m_vAcDeltaQ   = picParam->v_ac_delta_q;
293     picAV1Params->m_reserved8b2 = 0;
294 
295 
296     /****************************************************************************
297      quantization_matrix
298     ****************************************************************************/
299     picAV1Params->m_qMatrixFlags.m_value = picParam->qmatrix_fields.value;
300 
301 
302     /****************************************************************************
303       Mode control flags
304     ****************************************************************************/
305     picAV1Params->m_modeControlFlags.m_fields.m_deltaQPresentFlag  = picParam->mode_control_fields.bits.delta_q_present_flag;
306     picAV1Params->m_modeControlFlags.m_fields.m_log2DeltaQRes      = picParam->mode_control_fields.bits.log2_delta_q_res;
307     picAV1Params->m_modeControlFlags.m_fields.m_deltaLfPresentFlag = picParam->mode_control_fields.bits.delta_lf_present_flag;
308     picAV1Params->m_modeControlFlags.m_fields.m_log2DeltaLfRes     = picParam->mode_control_fields.bits.log2_delta_lf_res;
309     picAV1Params->m_modeControlFlags.m_fields.m_deltaLfMulti       = picParam->mode_control_fields.bits.delta_lf_multi;
310     picAV1Params->m_modeControlFlags.m_fields.m_txMode             = picParam->mode_control_fields.bits.tx_mode;
311     picAV1Params->m_modeControlFlags.m_fields.m_referenceMode      = (picParam->mode_control_fields.bits.reference_select == 0)? singleReference : referenceModeSelect;
312     picAV1Params->m_modeControlFlags.m_fields.m_reducedTxSetUsed   = picParam->mode_control_fields.bits.reduced_tx_set_used;
313     picAV1Params->m_modeControlFlags.m_fields.m_skipModePresent    = picParam->mode_control_fields.bits.skip_mode_present;
314 
315 
316     /****************************************************************************
317      Segmentation Information
318     ****************************************************************************/
319     picAV1Params->m_av1SegData.m_enabled        = picParam->seg_info.segment_info_fields.bits.enabled;
320     picAV1Params->m_av1SegData.m_updateMap      = picParam->seg_info.segment_info_fields.bits.update_map;
321     picAV1Params->m_av1SegData.m_temporalUpdate = picParam->seg_info.segment_info_fields.bits.temporal_update;
322     picAV1Params->m_av1SegData.m_updateData     = picParam->seg_info.segment_info_fields.bits.update_data;
323     picAV1Params->m_av1SegData.m_reserved4Bits  = 0;
324 
325     MOS_SecureMemcpy(picAV1Params->m_av1SegData.m_featureData, av1MaxSegments * segLvlMax * sizeof(int16_t),
326                      picParam->seg_info.feature_data,          av1MaxSegments * segLvlMax * sizeof(int16_t));
327     MOS_SecureMemcpy(picAV1Params->m_av1SegData.m_featureMask, av1MaxSegments * sizeof(uint8_t),
328                      picParam->seg_info.feature_mask,          av1MaxSegments * sizeof(uint8_t));
329 
330     bool allLossless = true;
331     for (auto seg = 0; seg < av1MaxSegments; seg++)
332     {
333         uint32_t qIndex = Av1GetQindex(&picAV1Params->m_av1SegData, seg, picAV1Params->m_baseQindex);
334 
335         picAV1Params->m_av1SegData.m_losslessFlag[seg] = (qIndex == 0) && (picParam->y_dc_delta_q == 0) &&
336             (picParam->u_ac_delta_q == 0) && (picParam->u_dc_delta_q == 0) &&
337             (picParam->v_ac_delta_q == 0) && (picParam->v_dc_delta_q == 0);
338 
339         //Calc qmlevel for Y/U/V, each segment has the same value
340         if (picAV1Params->m_av1SegData.m_losslessFlag[seg] || !picAV1Params->m_qMatrixFlags.m_fields.m_usingQmatrix)
341         {
342             picAV1Params->m_av1SegData.m_qmLevelY[seg] = av1NumQmLevels - 1;
343             picAV1Params->m_av1SegData.m_qmLevelU[seg] = av1NumQmLevels - 1;
344             picAV1Params->m_av1SegData.m_qmLevelV[seg] = av1NumQmLevels - 1;
345         }
346         else
347         {
348             picAV1Params->m_av1SegData.m_qmLevelY[seg] = picAV1Params->m_qMatrixFlags.m_fields.m_qmY;
349             picAV1Params->m_av1SegData.m_qmLevelU[seg] = picAV1Params->m_qMatrixFlags.m_fields.m_qmU;
350             picAV1Params->m_av1SegData.m_qmLevelV[seg] = picAV1Params->m_qMatrixFlags.m_fields.m_qmV;
351         }
352 
353         allLossless &= picAV1Params->m_av1SegData.m_losslessFlag[seg];
354 
355     }
356 
357     //Frame level lossless flag is set to true when all segments are lossless
358     picAV1Params->m_losslessMode = allLossless;
359 
360     picAV1Params->m_tileCountMinus1 = picParam->tile_count_minus_1;
361     picAV1Params->m_contextUpdateTileId = picParam->context_update_tile_id;
362 
363 
364     /***************************************************************************
365       CDEF params
366     ***************************************************************************/
367     picAV1Params->m_cdefDampingMinus3 = picParam->cdef_damping_minus_3;
368     picAV1Params->m_cdefBits          = picParam->cdef_bits;
369     MOS_SecureMemcpy(picAV1Params->m_cdefYStrengths,  8, picParam->cdef_y_strengths,  8);
370     MOS_SecureMemcpy(picAV1Params->m_cdefUvStrengths, 8, picParam->cdef_uv_strengths, 8);
371 
372 
373     /***************************************************************************
374      Loop restration flags
375     ***************************************************************************/
376     picAV1Params->m_loopRestorationFlags.m_fields.m_yframeRestorationType   = picParam->loop_restoration_fields.bits.yframe_restoration_type;
377     picAV1Params->m_loopRestorationFlags.m_fields.m_cbframeRestorationType  = picParam->loop_restoration_fields.bits.cbframe_restoration_type;
378     picAV1Params->m_loopRestorationFlags.m_fields.m_crframeRestorationType  = picParam->loop_restoration_fields.bits.crframe_restoration_type;
379     picAV1Params->m_loopRestorationFlags.m_fields.m_lrUnitShift             = picParam->loop_restoration_fields.bits.lr_unit_shift;
380     picAV1Params->m_loopRestorationFlags.m_fields.m_lrUvShift               = picParam->loop_restoration_fields.bits.lr_uv_shift;
381     picAV1Params->m_loopRestorationFlags.m_fields.m_reservedField           = 0;
382 
383 
384     /**********************************************
385      Global motion
386     **********************************************/
387     for (auto i = 0; i < 7; i++)
388     {
389         picAV1Params->m_wm[i].m_wmtype  = (CodecAv1TransType)picParam->wm[i].wmtype;
390         picAV1Params->m_wm[i].m_invalid = picParam->wm[i].invalid;
391         for (auto j = 0; j < 8; j++)
392         {
393             picAV1Params->m_wm[i].m_wmmat[j] = picParam->wm[i].wmmat[j];
394         }
395     }
396 
397     /***************************************************************************
398     Film Grain Information
399     ***************************************************************************/
400     MOS_SecureMemcpy(&picAV1Params->m_filmGrainParams, sizeof(CodecAv1FilmGrainParams),
401                      &picParam->film_grain_info,       sizeof(VAFilmGrainStructAV1));
402     if(picAV1Params->m_filmGrainParams.m_filmGrainInfoFlags.m_fields.m_applyGrain)
403     {
404         filmGrainOutSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->current_display_picture);
405     }
406 
407     picAV1Params->m_statusReportFeedbackNumber = 0;
408 
409     // calculate down scaled width
410     if (picAV1Params->m_picInfoFlags.m_fields.m_useSuperres &&
411         (picAV1Params->m_superresScaleDenominator != av1ScaleNumerator)) {
412         if (picAV1Params->m_superresScaleDenominator == 0) {
413             return VA_STATUS_ERROR_INVALID_PARAMETER;
414         }
415         uint32_t dsWidth = ((picParam->frame_width_minus1 + 1 ) *
416                             av1ScaleNumerator + picAV1Params->m_superresScaleDenominator / 2) /
417             picAV1Params->m_superresScaleDenominator;
418         picAV1Params->m_frameWidthMinus1  = dsWidth - 1;
419     }
420     else {
421         picAV1Params->m_frameWidthMinus1  = picParam->frame_width_minus1;
422     }
423 
424     picAV1Params->m_frameHeightMinus1 = picParam->frame_height_minus1;
425 
426     picAV1Params->m_tileCols     = picParam->tile_cols;
427     picAV1Params->m_tileRows     = picParam->tile_rows;
428 
429     if (picParam->pic_info_fields.bits.uniform_tile_spacing_flag)
430     {
431         const uint32_t maxMibSizeLog2   = 5;
432         const uint32_t minMibSizeLog2   = 4;
433         const uint32_t miSizeLog2       = 2;
434         int32_t mibSizeLog2 = picParam->seq_info_fields.fields.use_128x128_superblock ? maxMibSizeLog2 : minMibSizeLog2;
435         int32_t miCols = MOS_ALIGN_CEIL(MOS_ALIGN_CEIL(picAV1Params->m_frameWidthMinus1 + 1, 8) >> miSizeLog2, 1 << mibSizeLog2);
436         int32_t miRows = MOS_ALIGN_CEIL(MOS_ALIGN_CEIL(picAV1Params->m_frameHeightMinus1 + 1, 8) >> miSizeLog2, 1 << mibSizeLog2);
437         int32_t sbCols = miCols >> mibSizeLog2;
438         int32_t sbRows = miRows >> mibSizeLog2;
439 
440         for (auto i = 0; i < picParam->tile_cols - 1; i++)
441         {
442             uint32_t tileColsLog2 = CalcAv1TileLog2(1, picParam->tile_cols);
443             uint32_t sizeSb = MOS_ALIGN_CEIL(sbCols, 1 << tileColsLog2);
444             sizeSb >>= tileColsLog2;
445             picParam->width_in_sbs_minus_1[i] = sizeSb - 1;
446         }
447 
448         for (auto i = 0; i < picParam->tile_rows - 1; i++)
449         {
450             uint32_t tileRowsLog2 = CalcAv1TileLog2(1, picParam->tile_rows);
451             uint32_t sizeSb = MOS_ALIGN_CEIL(sbRows, 1 << tileRowsLog2);
452             sizeSb >>= tileRowsLog2;
453             picParam->height_in_sbs_minus_1[i] = sizeSb - 1;
454         }
455     }
456 
457     MOS_SecureMemcpy(picAV1Params->m_widthInSbsMinus1, 63 * sizeof(uint16_t),
458                      picParam->width_in_sbs_minus_1,   63 * sizeof(uint16_t));
459     MOS_SecureMemcpy(picAV1Params->m_heightInSbsMinus1, 63 * sizeof(uint16_t),
460                      picParam->height_in_sbs_minus_1,   63 * sizeof(uint16_t));
461 
462 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
463     // Picture Info
464     uint32_t subSamplingSum = picAV1Params->m_seqInfoFlags.m_fields.m_subsamplingX + picAV1Params->m_seqInfoFlags.m_fields.m_subsamplingY;
465     DECODE_EVENTDATA_INFO_PICTUREVA eventData = {0};
466     eventData.CodecFormat                   = m_ddiDecodeCtx->wMode;
467     eventData.FrameType                     = picAV1Params->m_picInfoFlags.m_fields.m_frameType == 0 ? I_TYPE : MIXED_TYPE;
468     eventData.PicStruct                     = FRAME_PICTURE;
469     eventData.Width                         = picAV1Params->m_frameWidthMinus1 + 1;
470     eventData.Height                        = picAV1Params->m_frameHeightMinus1 + 1;
471     eventData.Bitdepth                      = picAV1Params->m_bitDepthIdx;
472     eventData.ChromaFormat                  = (subSamplingSum == 2) ? 1 : (subSamplingSum == 1 ? 2 : 3);  // 1-4:2:0; 2-4:2:2; 3-4:4:4
473     eventData.EnabledSCC                    = picAV1Params->m_picInfoFlags.m_fields.m_allowScreenContentTools;
474     eventData.EnabledSegment                = picAV1Params->m_av1SegData.m_enabled;
475     eventData.EnabledFilmGrain              = picAV1Params->m_seqInfoFlags.m_fields.m_filmGrainParamsPresent;
476     MOS_TraceEvent(EVENT_DECODE_INFO_PICTUREVA, EVENT_TYPE_INFO, &eventData, sizeof(eventData), NULL, 0);
477 #endif
478 
479     return VA_STATUS_SUCCESS;
480 }
481 
SetDecodeParams()482 VAStatus DdiDecodeAV1::SetDecodeParams()
483 {
484      DDI_CHK_RET(DdiMediaDecode::SetDecodeParams(),"SetDecodeParams failed!");
485 #ifdef _DECODE_PROCESSING_SUPPORTED
486     // Bridge the SFC input with vdbox output
487     if (m_decProcessingType == VA_DEC_PROCESSING)
488     {
489         auto procParams =
490             (DecodeProcessingParams *)m_ddiDecodeCtx->DecodeParams.m_procParams;
491         procParams->m_inputSurface = (&m_ddiDecodeCtx->DecodeParams)->m_destSurface;
492         // codechal_decode_sfc.c expects Input Width/Height information.
493         procParams->m_inputSurface->dwWidth  = procParams->m_inputSurface->OsResource.iWidth;
494         procParams->m_inputSurface->dwHeight = procParams->m_inputSurface->OsResource.iHeight;
495         procParams->m_inputSurface->dwPitch  = procParams->m_inputSurface->OsResource.iPitch;
496         procParams->m_inputSurface->Format   = procParams->m_inputSurface->OsResource.Format;
497 
498         if(m_requireInputRegion)
499         {
500             procParams->m_inputSurfaceRegion.m_x = 0;
501             procParams->m_inputSurfaceRegion.m_y = 0;
502             procParams->m_inputSurfaceRegion.m_width = procParams->m_inputSurface->dwWidth;
503             procParams->m_inputSurfaceRegion.m_height = procParams->m_inputSurface->dwHeight;
504         }
505     }
506 #endif
507     CodecAv1PicParams *Av1PicParams = static_cast<CodecAv1PicParams *>(m_ddiDecodeCtx->DecodeParams.m_picParams);
508     bool bFilmGrainEnabled = Av1PicParams->m_filmGrainParams.m_filmGrainInfoFlags.m_fields.m_applyGrain;
509     if (bFilmGrainEnabled)
510     {
511         FilmGrainProcParams &filmGrainProcParams = m_ddiDecodeCtx->DecodeParams.m_filmGrainProcParams;
512         MOS_ZeroMemory(&filmGrainProcParams, sizeof(FilmGrainProcParams));
513         filmGrainProcParams.m_inputSurface  = (&m_ddiDecodeCtx->DecodeParams)->m_destSurface;
514         MOS_FORMAT expectedFormat = GetFormat();
515         outputSurface.Format   = expectedFormat;
516         DdiMedia_MediaSurfaceToMosResource(filmGrainOutSurface, &(outputSurface.OsResource));
517         filmGrainProcParams.m_outputSurface = &outputSurface;
518     }
519 
520     //anchor frame list insertion
521     if (Av1PicParams->m_anchorFrameNum > 0 && Av1PicParams->m_anchorFrameNum <= MAX_ANCHOR_FRAME_NUM_AV1)
522     {
523         MOS_FORMAT expectedFormat = GetFormat();
524         for(auto i = 0; i < Av1PicParams->m_anchorFrameNum; i++)
525         {
526             PDDI_MEDIA_SURFACE anchorFrame = DdiMedia_GetSurfaceFromVASurfaceID(m_ddiDecodeCtx->pMediaCtx, anchorFrameListVA[i]);
527             anchorFrameList[i].Format = expectedFormat;
528             DdiMedia_MediaSurfaceToMosResource(anchorFrame, &(anchorFrameList[i].OsResource));
529         }
530         Av1PicParams->m_anchorFrameList = anchorFrameList;
531     }
532 
533     return VA_STATUS_SUCCESS;
534 }
535 
536 
Av1Clamp(int value,int low,int high)537 int DdiDecodeAV1::Av1Clamp(int value, int low, int high)
538 {
539     return value < low ? low : (value > high ? high : value);
540 }
541 
542 
Av1GetQindex(CodecAv1SegmentsParams * segInfo,uint32_t segment_id,uint8_t base_qindex)543 uint32_t DdiDecodeAV1::Av1GetQindex(
544     CodecAv1SegmentsParams *segInfo,
545     uint32_t segment_id,
546     uint8_t base_qindex)
547 {
548     if ((segInfo->m_enabled) && (segInfo->m_featureMask[segment_id] & (1 << segLvlAltQ)))
549     {
550         const int data = segInfo->m_featureData[segment_id][segLvlAltQ];
551         return Av1Clamp(base_qindex + data, 0, av1MaxQindex);  // Delta value
552     }
553     else
554     {
555         return base_qindex;
556     }
557 }
558 
559 
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)560 VAStatus DdiDecodeAV1::RenderPicture(
561     VADriverContextP ctx,
562     VAContextID      context,
563     VABufferID       *buffers,
564     int32_t          numBuffers)
565 {
566     VAStatus           va = VA_STATUS_SUCCESS;
567     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
568 
569     DDI_FUNCTION_ENTER();
570 
571     void             *data = nullptr;
572     for (int32_t i = 0; i < numBuffers; i++)
573     {
574         if (!buffers || (buffers[i] == VA_INVALID_ID))
575         {
576             return VA_STATUS_ERROR_INVALID_BUFFER;
577         }
578         DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffers[i]);
579         if (nullptr == buf)
580         {
581             return VA_STATUS_ERROR_INVALID_BUFFER;
582         }
583 
584         uint32_t dataSize = buf->iSize;
585         DdiMedia_MapBuffer(ctx, buffers[i], &data);
586 
587         if (data == nullptr)
588         {
589             return VA_STATUS_ERROR_INVALID_BUFFER;
590         }
591 
592         switch ((int32_t)buf->uiType)
593         {
594         case VASliceDataBufferType:
595         {
596             int32_t index = GetBitstreamBufIndexFromBuffer(&m_ddiDecodeCtx->BufMgr, buf);
597             if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
598             {
599                 return VA_STATUS_ERROR_INVALID_BUFFER;
600             }
601 
602             DdiMedia_MediaBufferToMosResource(m_ddiDecodeCtx->BufMgr.pBitStreamBuffObject[index],
603                                               &m_ddiDecodeCtx->BufMgr.resBitstreamBuffer);
604             m_ddiDecodeCtx->DecodeParams.m_dataSize += dataSize;
605 
606             break;
607         }
608         case VASliceParameterBufferType:
609         {
610             if (buf->uiNumElements == 0)
611             {
612                 return VA_STATUS_ERROR_INVALID_BUFFER;
613             }
614 
615             VASliceParameterBufferAV1 *slcInfoAV1 = (VASliceParameterBufferAV1 *)data;
616 
617             DDI_CHK_RET(ParseTileParams(mediaCtx, slcInfoAV1, buf->uiNumElements), "ParseTileParams failed!");
618             m_ddiDecodeCtx->DecodeParams.m_numSlices += buf->uiNumElements;
619             m_groupIndex++;
620             break;
621         }
622         case VAPictureParameterBufferType:
623         {
624             VADecPictureParameterBufferAV1 *picParam = (VADecPictureParameterBufferAV1 *)data;
625             DDI_CHK_RET(ParsePicParams(mediaCtx, picParam), "ParsePicParams failed!");
626             break;
627         }
628 
629         case VAProcPipelineParameterBufferType:
630         {
631             DDI_NORMALMESSAGE("ProcPipeline is not supported for AV1 decoding\n");
632             break;
633         }
634         case VADecodeStreamoutBufferType:
635         {
636             DdiMedia_MediaBufferToMosResource(buf, &m_ddiDecodeCtx->BufMgr.resExternalStreamOutBuffer);
637             m_streamOutEnabled = true;
638             break;
639         }
640 
641         default:
642             va = m_ddiDecodeCtx->pCpDdiInterface->RenderCencPicture(ctx, context, buf, data);
643             break;
644         }
645         DdiMedia_UnmapBuffer(ctx, buffers[i]);
646     }
647 
648     DDI_FUNCTION_EXIT(va);
649     return va;
650 }
651 
652 
InitResourceBuffer()653 VAStatus DdiDecodeAV1::InitResourceBuffer()
654 {
655     VAStatus                  vaStatus = VA_STATUS_SUCCESS;
656     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
657 
658     bufMgr->pSliceData = nullptr;
659 
660     bufMgr->ui64BitstreamOrder = 0;
661     bufMgr->dwMaxBsSize = m_width * m_height * 3 / 2; // need consider 2byte case
662     // minimal 10k bytes for some special case. Will refractor this later
663     if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
664     {
665         bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
666     }
667 
668     int32_t i;
669     // init decode bitstream buffer object
670     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
671     {
672         bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
673         if (bufMgr->pBitStreamBuffObject[i] == nullptr)
674         {
675             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
676             goto finish;
677         }
678         bufMgr->pBitStreamBuffObject[i]->iSize = bufMgr->dwMaxBsSize;
679         bufMgr->pBitStreamBuffObject[i]->uiType = VASliceDataBufferType;
680         bufMgr->pBitStreamBuffObject[i]->format = Media_Format_Buffer;
681         bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
682         bufMgr->pBitStreamBuffObject[i]->bo = nullptr;
683         bufMgr->pBitStreamBase[i] = nullptr;
684     }
685 
686     bufMgr->m_maxNumSliceData = av1MaxTileNum;
687     bufMgr->pSliceData = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) * bufMgr->m_maxNumSliceData);
688 
689     if (bufMgr->pSliceData == nullptr)
690     {
691         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
692         goto finish;
693     }
694 
695     bufMgr->dwNumSliceData = 0;
696     bufMgr->dwNumSliceControl = 0;
697     bufMgr->pCodecParamReserved = (DDI_CODEC_BUFFER_PARAM_AV1 *)MOS_AllocAndZeroMemory(sizeof(DDI_CODEC_BUFFER_PARAM_AV1));
698 
699     if (bufMgr->pCodecParamReserved == nullptr)
700     {
701         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
702         goto finish;
703     }
704 
705     bufMgr->pCodecSlcParamReserved = (VASliceParameterBufferAV1 *)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferAV1) * av1MaxTileNum);
706     if (bufMgr->pCodecSlcParamReserved == nullptr)
707     {
708         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
709         goto finish;
710     }
711 
712     {   // need bracket to avoid compile error by jump
713         DDI_CODEC_BUFFER_PARAM_AV1* codec_Param_AV1 = (DDI_CODEC_BUFFER_PARAM_AV1 *)bufMgr->pCodecParamReserved;
714         codec_Param_AV1->pVASliceParameterBufferAV1 = (VASliceParameterBufferAV1 *)bufMgr->pCodecSlcParamReserved;
715     }
716 
717     return VA_STATUS_SUCCESS;
718 
719 finish:
720     FreeResourceBuffer();
721     return vaStatus;
722 }
723 
724 
FreeResourceBuffer()725 void DdiDecodeAV1::FreeResourceBuffer()
726 {
727     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
728 
729     int32_t i;
730     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
731     {
732         if (bufMgr->pBitStreamBase[i])
733         {
734             DdiMediaUtil_UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
735             bufMgr->pBitStreamBase[i] = nullptr;
736         }
737         if (bufMgr->pBitStreamBuffObject[i])
738         {
739             DdiMediaUtil_FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
740             MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
741             bufMgr->pBitStreamBuffObject[i] = nullptr;
742         }
743     }
744 
745     if (bufMgr->pCodecParamReserved)
746     {
747         DDI_CODEC_BUFFER_PARAM_AV1* codec_Param_AV1 =
748             static_cast<DDI_CODEC_BUFFER_PARAM_AV1 *>(bufMgr->pCodecParamReserved);
749          if (codec_Param_AV1->pVASliceParameterBufferAV1)
750          {
751             MOS_FreeMemory(codec_Param_AV1->pVASliceParameterBufferAV1);
752             codec_Param_AV1->pVASliceParameterBufferAV1 = nullptr;
753             bufMgr->pCodecSlcParamReserved = nullptr;
754          }
755          MOS_FreeMemory(bufMgr->pCodecParamReserved);
756          bufMgr->pCodecParamReserved = nullptr;
757     }
758 
759     // free decode bitstream buffer object
760     MOS_FreeMemory(bufMgr->pSliceData);
761     bufMgr->pSliceData = nullptr;
762 }
763 
764 
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)765 uint8_t* DdiDecodeAV1::GetPicParamBuf(
766     DDI_CODEC_COM_BUFFER_MGR    *bufMgr)
767 {
768     DDI_CODEC_BUFFER_PARAM_AV1* codec_Param_AV1 = static_cast<DDI_CODEC_BUFFER_PARAM_AV1 *>(bufMgr->pCodecParamReserved);
769     return (uint8_t*)(&(codec_Param_AV1->PicParamAV1));
770 }
771 
772 
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)773 VAStatus DdiDecodeAV1::AllocSliceControlBuffer(
774     DDI_MEDIA_BUFFER       *buf)
775 {
776     DDI_CODEC_COM_BUFFER_MGR   *bufMgr;
777 
778     bufMgr = &(m_ddiDecodeCtx->BufMgr);
779 
780     DDI_CODEC_BUFFER_PARAM_AV1* codec_Param_AV1 = (DDI_CODEC_BUFFER_PARAM_AV1 *)bufMgr->pCodecParamReserved;
781     codec_Param_AV1->pVASliceParameterBufferAV1 = (VASliceParameterBufferAV1 *)bufMgr->pCodecSlcParamReserved;
782     if (codec_Param_AV1->pVASliceParameterBufferAV1 == nullptr)
783     {
784         return VA_STATUS_ERROR_ALLOCATION_FAILED;
785     }
786     if (buf->uiNumElements > av1MaxTileNum)
787     {
788         DDI_ASSERTMESSAGE("buf->uiNumElements = %d : exceeds av1MaxTileNum = %d",
789                           buf->uiNumElements, av1MaxTileNum);
790         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
791     }
792     buf->pData = (uint8_t*)codec_Param_AV1->pVASliceParameterBufferAV1;
793     buf->uiOffset = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferAV1);
794 
795     bufMgr->dwNumSliceControl += buf->uiNumElements;
796 
797     return VA_STATUS_SUCCESS;
798 }
799 
800 
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)801 VAStatus DdiDecodeAV1::CodecHalInit(
802     DDI_MEDIA_CONTEXT *mediaCtx,
803     void              *ptr)
804 {
805     VAStatus     vaStatus = VA_STATUS_SUCCESS;
806     MOS_CONTEXT *mosCtx = (MOS_CONTEXT *)ptr;
807 
808     CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
809     m_ddiDecodeCtx->pCpDdiInterface->SetCpParams(m_ddiDecodeAttr->uiEncryptionType, m_codechalSettings);
810 
811     CODECHAL_STANDARD_INFO standardInfo;
812     memset(&standardInfo, 0, sizeof(standardInfo));
813 
814     standardInfo.CodecFunction = codecFunction;
815     standardInfo.Mode = (CODECHAL_MODE)m_ddiDecodeCtx->wMode;
816 
817     m_codechalSettings->codecFunction = codecFunction;
818     m_codechalSettings->width = m_width;
819     m_codechalSettings->height = m_height;
820     m_codechalSettings->intelEntrypointInUse = false;
821 
822     //VAProfileAV1Profile0 supports both 420 8bit and 420 10bit
823     m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
824 
825     m_codechalSettings->shortFormatInUse = m_ddiDecodeCtx->bShortFormatInUse;
826 
827     m_codechalSettings->mode = CODECHAL_DECODE_MODE_AV1VLD;
828     m_codechalSettings->standard = CODECHAL_AV1;
829     m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV420;
830 
831     m_ddiDecodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CodecAv1PicParams));
832     if (m_ddiDecodeCtx->DecodeParams.m_picParams == nullptr)
833     {
834         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
835         goto CleanUpandReturn;
836     }
837 
838     m_ddiDecodeCtx->DecodeParams.m_sliceParams = MOS_AllocAndZeroMemory(sizeof(CodecAv1TileParams) * av1MaxTileNum);
839     if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
840     {
841         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
842         goto CleanUpandReturn;
843     }
844 
845     vaStatus = CreateCodecHal(mediaCtx,
846         ptr,
847         &standardInfo);
848 
849     if (vaStatus != VA_STATUS_SUCCESS)
850     {
851         goto CleanUpandReturn;
852     }
853 
854     if (InitResourceBuffer() != VA_STATUS_SUCCESS)
855     {
856         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
857         goto CleanUpandReturn;
858     }
859 
860     return vaStatus;
861 
862 CleanUpandReturn:
863     FreeResourceBuffer();
864 
865     if (m_ddiDecodeCtx->pCodecHal)
866     {
867         m_ddiDecodeCtx->pCodecHal->Destroy();
868         MOS_Delete(m_ddiDecodeCtx->pCodecHal);
869         m_ddiDecodeCtx->pCodecHal = nullptr;
870     }
871 
872     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_picParams);
873     m_ddiDecodeCtx->DecodeParams.m_picParams = nullptr;
874     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
875     m_ddiDecodeCtx->DecodeParams.m_sliceParams = nullptr;
876 
877     return vaStatus;
878 }
879 
880 
InitDecodeParams(VADriverContextP ctx,VAContextID context)881 VAStatus DdiDecodeAV1::InitDecodeParams(
882     VADriverContextP ctx,
883     VAContextID      context)
884 {
885     // skip the mediaCtx check as it is checked in caller
886     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
887     DDI_CHK_RET(DecodeCombineBitstream(mediaCtx), "DecodeCombineBitstream failed!");
888     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
889     bufMgr->dwNumSliceData = 0;
890     bufMgr->dwNumSliceControl = 0;
891     memset(&outputSurface, 0, sizeof(MOS_SURFACE));
892     outputSurface.dwOffset = 0;
893 
894     for(auto i = 0; i < MAX_ANCHOR_FRAME_NUM_AV1; i++)
895     {
896         memset(&anchorFrameList[i], 0, sizeof(MOS_SURFACE));
897         anchorFrameList[i].dwOffset = 0;
898     }
899 
900     DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_ddiDecodeCtx->RTtbl);
901 
902     if ((rtTbl == nullptr) || (rtTbl->pCurrentRT == nullptr))
903     {
904         return VA_STATUS_ERROR_INVALID_PARAMETER;
905     }
906     return VA_STATUS_SUCCESS;
907 }
908 
909 
GetFormat()910 MOS_FORMAT DdiDecodeAV1::GetFormat()
911 {
912     MOS_FORMAT Format = Format_NV12;
913     CodechalDecodeParams *decodeParams = &m_ddiDecodeCtx->DecodeParams;
914 
915     CodecAv1PicParams *picParams = (CodecAv1PicParams *)decodeParams->m_picParams;
916     if (picParams->m_bitDepthIdx > 0)
917     {
918         Format = Format_P010;
919         if(picParams->m_bitDepthIdx > 2)
920         {
921             Format = Format_P016;
922         }
923         if ((picParams->m_seqInfoFlags.m_fields.m_subsamplingX == 1) &&
924             (picParams->m_seqInfoFlags.m_fields.m_subsamplingY == 0))
925         {
926             Format = Format_Y210;
927         }
928         else if ((picParams->m_seqInfoFlags.m_fields.m_subsamplingX == 0) &&
929             (picParams->m_seqInfoFlags.m_fields.m_subsamplingY == 0))
930         {
931             if(picParams->m_bitDepthIdx == 2)
932             {
933                 Format = Format_Y410;
934             }
935             else if(picParams->m_bitDepthIdx > 2)
936             {
937                 Format = Format_Y416;
938             }
939         }
940     }
941     return Format;
942 }
943 
944 
DestroyContext(VADriverContextP ctx)945 void DdiDecodeAV1::DestroyContext(
946     VADriverContextP ctx)
947 {
948     FreeResourceBuffer();
949     // explicitly call the base function to do the further clean-up
950     DdiMediaDecode::DestroyContext(ctx);
951 }
952 
953 
ContextInit(int32_t picWidth,int32_t picHeight)954 void DdiDecodeAV1::ContextInit(
955     int32_t picWidth,
956     int32_t picHeight)
957 {
958     // call the function in base class to initialize it.
959     DdiMediaDecode::ContextInit(picWidth, picHeight);
960 
961     m_ddiDecodeCtx->wMode = CODECHAL_DECODE_MODE_AV1VLD;
962 }
963 
964 extern template class MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>;
965 
966 static bool av1Registered =
967 MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>::RegisterCodec<DdiDecodeAV1>(DECODE_ID_AV1);
968