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