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