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