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_vvc_specific.cpp
24 //! \brief VVC 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_vvc_specific.h"
30 #include "mos_solo_generic.h"
31 #include "media_libva_interface_next.h"
32 #include "codec_def_common_vvc.h"
33
34 namespace decode
35 {
36
ParseTileParams(DDI_MEDIA_CONTEXT * mediaCtx,uint16_t * tileParam,uint32_t numTiles,uint32_t numTileBuffers)37 VAStatus DdiDecodeVvc::ParseTileParams(
38 DDI_MEDIA_CONTEXT *mediaCtx,
39 uint16_t *tileParam,
40 uint32_t numTiles,
41 uint32_t numTileBuffers)
42 {
43 DDI_CODEC_FUNC_ENTER;
44
45 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
46 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(m_decodeCtx->DecodeParams.m_picParams);
47 if ((tileParam == nullptr) || (pVvcPicParams == nullptr))
48 {
49 DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing VVC Tile parameter\n");
50 return VA_STATUS_ERROR_INVALID_PARAMETER;
51 }
52
53 if (vvcMaxTileParamsNum < (numTiles + numTileBuffers))
54 {
55 DDI_CODEC_ASSERTMESSAGE("numTiles = %d exceeds max size = %d", numTiles + numTileBuffers, vvcMaxTileParamsNum);
56 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
57 }
58
59 uint16_t* pVvcTileParams = static_cast<uint16_t*>(m_decodeCtx->DecodeParams.m_tileParams);
60 pVvcTileParams += numTileBuffers;
61 MOS_ZeroMemory(pVvcTileParams, (numTiles * sizeof(uint16_t)));
62 MOS_SecureMemcpy(pVvcTileParams, sizeof(uint16_t) * numTiles, tileParam, sizeof(uint16_t) * numTiles);
63
64 return VA_STATUS_SUCCESS;
65 }
66
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VAPictureParameterBufferVVC * picParam)67 VAStatus DdiDecodeVvc::ParsePicParams(
68 DDI_MEDIA_CONTEXT *mediaCtx,
69 VAPictureParameterBufferVVC *picParam)
70 {
71 DDI_CODEC_FUNC_ENTER;
72
73 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
74 CodechalDecodeParams *decodeParams = &m_decodeCtx->DecodeParams;
75 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(decodeParams->m_picParams);
76 if ((picParam == nullptr) || (pVvcPicParams == nullptr))
77 {
78 DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing VVC Picture parameter\n");
79 return VA_STATUS_ERROR_INVALID_PARAMETER;
80 }
81 MOS_ZeroMemory(pVvcPicParams, sizeof(CodecVvcPicParams));
82
83 // Set up current frame
84 pVvcPicParams->m_picOrderCntVal = picParam->CurrPic.pic_order_cnt;
85 SetupCodecPicture(mediaCtx,
86 &m_decodeCtx->RTtbl,
87 &pVvcPicParams->m_currPic,
88 picParam->CurrPic,
89 VvcPicEntryCurrFrame);
90 if (pVvcPicParams->m_currPic.FrameIdx >= CODEC_MAX_DPB_NUM_VVC)
91 {
92 DDI_CODEC_NORMALMESSAGE("CurrPic.FrameIdx is out of range.");
93 return VA_STATUS_ERROR_INVALID_PARAMETER;
94 }
95
96 // Set up reference frames
97 MOS_ZeroMemory(m_refListFlags, sizeof(m_refListFlags));
98 for (auto i = 0; i < vvcMaxNumRefFrame; i++)
99 {
100 m_refListFlags[i] = picParam->ReferenceFrames[i].flags;
101 pVvcPicParams->m_refFramePocList[i] = picParam->ReferenceFrames[i].pic_order_cnt;
102 SetupCodecPicture(mediaCtx,
103 &m_decodeCtx->RTtbl,
104 &pVvcPicParams->m_refFrameList[i],
105 picParam->ReferenceFrames[i],
106 VvcPicEntryRefFrameList);
107 if(pVvcPicParams->m_refFrameList[i].FrameIdx > CODEC_MAX_DPB_NUM_VVC)
108 {
109 pVvcPicParams->m_refFrameList[i].FrameIdx = CODEC_MAX_DPB_NUM_VVC;
110 }
111 }
112
113 // Set up RefPicList
114 for (auto i = 0; i < 2; i++)
115 {
116 for (auto j = 0; j < vvcMaxNumRefFrame; j++)
117 {
118 pVvcPicParams->m_refPicList[i][j].PicFlags = PICTURE_INVALID;
119 }
120 }
121
122 pVvcPicParams->m_ppsPicWidthInLumaSamples = picParam->pps_pic_width_in_luma_samples;
123 pVvcPicParams->m_ppsPicHeightInLumaSamples = picParam->pps_pic_height_in_luma_samples;
124
125 // slice-level params
126 pVvcPicParams->m_spsPicWidthMaxInLumaSamples = 0;
127 pVvcPicParams->m_spsPicHeightMaxInLumaSamples = 0;
128 pVvcPicParams->m_spsNumSubpicsMinus1 = picParam->sps_num_subpics_minus1;
129 pVvcPicParams->m_spsChromaFormatIdc = picParam->sps_chroma_format_idc;
130 pVvcPicParams->m_spsBitdepthMinus8 = picParam->sps_bitdepth_minus8;
131 pVvcPicParams->m_spsLog2CtuSizeMinus5 = picParam->sps_log2_ctu_size_minus5;
132 pVvcPicParams->m_spsLog2MinLumaCodingBlockSizeMinus2 = picParam->sps_log2_min_luma_coding_block_size_minus2;
133 pVvcPicParams->m_spsLog2TransformSkipMaxSizeMinus2 = picParam->sps_log2_transform_skip_max_size_minus2;
134
135 MOS_SecureMemcpy(&pVvcPicParams->m_chromaQpTable[0], 76 * sizeof(int8_t), &picParam->ChromaQpTable[0], 76 * sizeof(int8_t));
136 MOS_SecureMemcpy(&pVvcPicParams->m_chromaQpTable[1], 76 * sizeof(int8_t), &picParam->ChromaQpTable[1], 76 * sizeof(int8_t));
137 MOS_SecureMemcpy(&pVvcPicParams->m_chromaQpTable[2], 76 * sizeof(int8_t), &picParam->ChromaQpTable[2], 76 * sizeof(int8_t));
138
139 pVvcPicParams->m_spsSixMinusMaxNumMergeCand = picParam->sps_six_minus_max_num_merge_cand;
140 pVvcPicParams->m_spsFiveMinusMaxNumSubblockMergeCand = picParam->sps_five_minus_max_num_subblock_merge_cand;
141 pVvcPicParams->m_spsMaxNumMergeCandMinusMaxNumGpmCand = picParam->sps_max_num_merge_cand_minus_max_num_gpm_cand;
142 pVvcPicParams->m_spsLog2ParallelMergeLevelMinus2 = picParam->sps_log2_parallel_merge_level_minus2;
143 pVvcPicParams->m_spsMinQpPrimeTs = picParam->sps_min_qp_prime_ts;
144 pVvcPicParams->m_spsSixMinusMaxNumIbcMergeCand = picParam->sps_six_minus_max_num_ibc_merge_cand;
145 pVvcPicParams->m_spsNumLadfIntervalsMinus2 = picParam->sps_num_ladf_intervals_minus2;
146 pVvcPicParams->m_spsLadfLowestIntervalQpOffset = picParam->sps_ladf_lowest_interval_qp_offset;
147
148 MOS_SecureMemcpy(pVvcPicParams->m_spsLadfQpOffset, 4 * sizeof(int8_t), picParam->sps_ladf_qp_offset, 4 * sizeof(int8_t));
149 MOS_SecureMemcpy(pVvcPicParams->m_spsLadfDeltaThresholdMinus1, 4 * sizeof(uint16_t), picParam-> sps_ladf_delta_threshold_minus1, 4 * sizeof(uint16_t));
150
151 // this def is not aligned btw VAAPI & HAL, need to parse each to get correct flag
152 // parse spsFlagss0
153 pVvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag = picParam->sps_flags.bits.sps_subpic_info_present_flag;
154 pVvcPicParams->m_spsFlags0.m_fields.m_spsIndependentSubpicsFlag = picParam->sps_flags.bits.sps_independent_subpics_flag;
155 pVvcPicParams->m_spsFlags0.m_fields.m_spsSubpicSameSizeFlag = picParam->sps_flags.bits.sps_subpic_same_size_flag;
156 pVvcPicParams->m_spsFlags0.m_fields.m_spsEntropyCodingSyncEnabledFlag = picParam->sps_flags.bits.sps_entropy_coding_sync_enabled_flag;
157 pVvcPicParams->m_spsFlags0.m_fields.m_spsQtbttDualTreeIntraFlag = picParam->sps_flags.bits.sps_qtbtt_dual_tree_intra_flag;
158 pVvcPicParams->m_spsFlags0.m_fields.m_spsMaxLumaTransformSize64Flag = picParam->sps_flags.bits.sps_max_luma_transform_size_64_flag;
159 pVvcPicParams->m_spsFlags0.m_fields.m_spsTransformSkipEnabledFlag = picParam->sps_flags.bits.sps_transform_skip_enabled_flag;
160 pVvcPicParams->m_spsFlags0.m_fields.m_spsBdpcmEnabledFlag = picParam->sps_flags.bits.sps_bdpcm_enabled_flag;
161 pVvcPicParams->m_spsFlags0.m_fields.m_spsMtsEnabledFlag = picParam->sps_flags.bits.sps_mts_enabled_flag;
162 pVvcPicParams->m_spsFlags0.m_fields.m_spsExplicitMtsIntraEnabledFlag = picParam->sps_flags.bits.sps_explicit_mts_intra_enabled_flag;
163 pVvcPicParams->m_spsFlags0.m_fields.m_spsExplicitMtsInterEnabledFlag = picParam->sps_flags.bits.sps_explicit_mts_inter_enabled_flag;
164 pVvcPicParams->m_spsFlags0.m_fields.m_spsLfnstEnabledFlag = picParam->sps_flags.bits.sps_lfnst_enabled_flag;
165 pVvcPicParams->m_spsFlags0.m_fields.m_spsJointCbcrEnabledFlag = picParam->sps_flags.bits.sps_joint_cbcr_enabled_flag;
166 pVvcPicParams->m_spsFlags0.m_fields.m_spsSameQpTableForChromaFlag = picParam->sps_flags.bits.sps_same_qp_table_for_chroma_flag;
167 pVvcPicParams->m_spsFlags0.m_fields.m_spsSaoEnabledFlag = picParam->sps_flags.bits.sps_sao_enabled_flag;
168 pVvcPicParams->m_spsFlags0.m_fields.m_spsAlfEnabledFlag = picParam->sps_flags.bits.sps_alf_enabled_flag;
169 pVvcPicParams->m_spsFlags0.m_fields.m_spsCcalfEnabledFlag = picParam->sps_flags.bits.sps_ccalf_enabled_flag;
170 pVvcPicParams->m_spsFlags0.m_fields.m_spsLmcsEnabledFlag = picParam->sps_flags.bits.sps_lmcs_enabled_flag;
171
172 // parse spsFlagss1
173 pVvcPicParams->m_spsFlags1.m_fields.m_spsTemporalMvpEnabledFlag = 1;
174 pVvcPicParams->m_spsFlags1.m_fields.m_spsSbtmvpEnabledFlag = picParam->sps_flags.bits.sps_sbtmvp_enabled_flag;
175 pVvcPicParams->m_spsFlags1.m_fields.m_spsAmvrEnabledFlag = picParam->sps_flags.bits.sps_amvr_enabled_flag;
176 pVvcPicParams->m_spsFlags1.m_fields.m_spsBdofEnabledFlag = 0;
177 pVvcPicParams->m_spsFlags1.m_fields.m_spsBdofControlPresentInPhFlag = 0;
178 pVvcPicParams->m_spsFlags1.m_fields.m_spsSmvdEnabledFlag = picParam->sps_flags.bits.sps_smvd_enabled_flag;
179 pVvcPicParams->m_spsFlags1.m_fields.m_spsDmvrEnabledFlag = 0;
180 pVvcPicParams->m_spsFlags1.m_fields.m_spsDmvrControlPresentInPhFlag = 0;
181 pVvcPicParams->m_spsFlags1.m_fields.m_spsMmvdEnabledFlag = picParam->sps_flags.bits.sps_mmvd_enabled_flag;
182 pVvcPicParams->m_spsFlags1.m_fields.m_spsMmvdFullpelOnlyEnabledFlag = 0;
183 pVvcPicParams->m_spsFlags1.m_fields.m_spsSbtEnabledFlag = picParam->sps_flags.bits.sps_sbt_enabled_flag;
184 pVvcPicParams->m_spsFlags1.m_fields.m_spsAffineEnabledFlag = picParam->sps_flags.bits.sps_affine_enabled_flag;
185 pVvcPicParams->m_spsFlags1.m_fields.m_sps6paramAffineEnabledFlag = picParam->sps_flags.bits.sps_6param_affine_enabled_flag;
186 pVvcPicParams->m_spsFlags1.m_fields.m_spsAffineAmvrEnabledFlag = picParam->sps_flags.bits.sps_affine_amvr_enabled_flag;
187 pVvcPicParams->m_spsFlags1.m_fields.m_spsAffineProfEnabledFlag = picParam->sps_flags.bits.sps_affine_prof_enabled_flag;
188 pVvcPicParams->m_spsFlags1.m_fields.m_spsProfControlPresentInPhFlag = 0;
189 pVvcPicParams->m_spsFlags1.m_fields.m_spsBcwEnabledFlag = picParam->sps_flags.bits.sps_bcw_enabled_flag;
190 pVvcPicParams->m_spsFlags1.m_fields.m_spsCiipEnabledFlag = picParam->sps_flags.bits.sps_ciip_enabled_flag;
191 pVvcPicParams->m_spsFlags1.m_fields.m_spsGpmEnabledFlag = picParam->sps_flags.bits.sps_gpm_enabled_flag;
192 pVvcPicParams->m_spsFlags1.m_fields.m_spsIspEnabledFlag = picParam->sps_flags.bits.sps_isp_enabled_flag;
193 pVvcPicParams->m_spsFlags1.m_fields.m_spsMrlEnabledFlag = picParam->sps_flags.bits.sps_mrl_enabled_flag;
194 pVvcPicParams->m_spsFlags1.m_fields.m_spsMipEnabledFlag = picParam->sps_flags.bits.sps_mip_enabled_flag;
195 pVvcPicParams->m_spsFlags1.m_fields.m_spsCclmEnabledFlag = picParam->sps_flags.bits.sps_cclm_enabled_flag;
196 pVvcPicParams->m_spsFlags1.m_fields.m_spsChromaHorizontalCollocatedFlag = picParam->sps_flags.bits.sps_chroma_horizontal_collocated_flag;
197 pVvcPicParams->m_spsFlags1.m_fields.m_spsChromaVerticalCollocatedFlag = picParam->sps_flags.bits.sps_chroma_vertical_collocated_flag;
198
199 // parse spsFlagss2
200 pVvcPicParams->m_spsFlags2.m_fields.m_spsPaletteEnabledFlag = picParam->sps_flags.bits.sps_palette_enabled_flag;
201 pVvcPicParams->m_spsFlags2.m_fields.m_spsActEnabledFlag = picParam->sps_flags.bits.sps_act_enabled_flag;
202 pVvcPicParams->m_spsFlags2.m_fields.m_spsIbcEnabledFlag = picParam->sps_flags.bits.sps_ibc_enabled_flag;
203 pVvcPicParams->m_spsFlags2.m_fields.m_spsLadfEnabledFlag = picParam->sps_flags.bits.sps_ladf_enabled_flag;
204 pVvcPicParams->m_spsFlags2.m_fields.m_spsExplicitScalingListEnabledFlag = picParam->sps_flags.bits.sps_explicit_scaling_list_enabled_flag;
205 pVvcPicParams->m_spsFlags2.m_fields.m_spsScalingMatrixForLfnstDisabledFlag = picParam->sps_flags.bits.sps_scaling_matrix_for_lfnst_disabled_flag;
206 pVvcPicParams->m_spsFlags2.m_fields.m_spsScalingMatrixForAlternativeColourSpaceDisabledFlag = picParam->sps_flags.bits.sps_scaling_matrix_for_alternative_colour_space_disabled_flag;
207 pVvcPicParams->m_spsFlags2.m_fields.m_spsScalingMatrixDesignatedColourSpaceFlag = picParam->sps_flags.bits.sps_scaling_matrix_designated_colour_space_flag;
208 pVvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesEnabledFlag = picParam->sps_flags.bits.sps_virtual_boundaries_enabled_flag;
209 pVvcPicParams->m_spsFlags2.m_fields.m_spsVirtualBoundariesPresentFlag = picParam->sps_flags.bits.sps_virtual_boundaries_present_flag;
210
211 // picure-level params
212 pVvcPicParams->m_numVerVirtualBoundaries = picParam->NumVerVirtualBoundaries;
213 pVvcPicParams->m_numHorVirtualBoundaries = picParam->NumHorVirtualBoundaries;
214
215 MOS_SecureMemcpy(pVvcPicParams->m_virtualBoundaryPosX, 3 * sizeof(uint16_t), picParam->VirtualBoundaryPosX, 3 * sizeof(uint16_t));
216 MOS_SecureMemcpy(pVvcPicParams->m_virtualBoundaryPosY, 3 * sizeof(uint16_t), picParam->VirtualBoundaryPosY, 3 * sizeof(uint16_t));
217
218 pVvcPicParams->m_ppsScalingWinLeftOffset = picParam->pps_scaling_win_left_offset;
219 pVvcPicParams->m_ppsScalingWinRightOffset = picParam->pps_scaling_win_right_offset;
220 pVvcPicParams->m_ppsScalingWinTopOffset = picParam->pps_scaling_win_top_offset;
221 pVvcPicParams->m_ppsScalingWinBottomOffset = picParam->pps_scaling_win_bottom_offset;
222 pVvcPicParams->m_ppsNumExpTileColumnsMinus1 = picParam->pps_num_exp_tile_columns_minus1;
223 pVvcPicParams->m_ppsNumExpTileRowsMinus1 = picParam->pps_num_exp_tile_rows_minus1;
224 pVvcPicParams->m_ppsNumSlicesInPicMinus1 = picParam->pps_num_slices_in_pic_minus1;
225 pVvcPicParams->m_ppsPicWidthMinusWraparoundOffset = picParam->pps_pic_width_minus_wraparound_offset;
226 pVvcPicParams->m_ppsCbQpOffset = picParam->pps_cb_qp_offset;
227 pVvcPicParams->m_ppsCrQpOffset = picParam->pps_cr_qp_offset;
228 pVvcPicParams->m_ppsJointCbcrQpOffsetValue = picParam->pps_joint_cbcr_qp_offset_value;
229 pVvcPicParams->m_ppsChromaQpOffsetListLenMinus1 = picParam->pps_chroma_qp_offset_list_len_minus1;
230
231 MOS_SecureMemcpy(pVvcPicParams->m_ppsCbQpOffsetList, 6 * sizeof(int8_t), picParam->pps_cb_qp_offset_list, 6 * sizeof(int8_t));
232 MOS_SecureMemcpy(pVvcPicParams->m_ppsCrQpOffsetList, 6 * sizeof(int8_t), picParam->pps_cr_qp_offset_list, 6 * sizeof(int8_t));
233 MOS_SecureMemcpy(pVvcPicParams->m_ppsJointCbcrQpOffsetList, 6 * sizeof(int8_t), picParam->pps_joint_cbcr_qp_offset_list, 6 * sizeof(int8_t));
234
235 // this def is not aligned btw VAAPI & HAL, need to parse each to get correct flag
236 pVvcPicParams->m_ppsFlags.m_fields.m_ppsLoopFilterAcrossTilesEnabledFlag = picParam->pps_flags.bits.pps_loop_filter_across_tiles_enabled_flag;
237 pVvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag = picParam->pps_flags.bits.pps_rect_slice_flag;
238 pVvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag = picParam->pps_flags.bits.pps_single_slice_per_subpic_flag;
239 pVvcPicParams->m_ppsFlags.m_fields.m_ppsLoopFilterAcrossSlicesEnabledFlag = picParam->pps_flags.bits.pps_loop_filter_across_slices_enabled_flag;
240 pVvcPicParams->m_ppsFlags.m_fields.m_ppsWeightedPredFlag = picParam->pps_flags.bits.pps_weighted_pred_flag;
241 pVvcPicParams->m_ppsFlags.m_fields.m_ppsWeightedBipredFlag = picParam->pps_flags.bits.pps_weighted_bipred_flag;
242 pVvcPicParams->m_ppsFlags.m_fields.m_ppsRefWraparoundEnabledFlag = picParam->pps_flags.bits.pps_ref_wraparound_enabled_flag;
243 pVvcPicParams->m_ppsFlags.m_fields.m_ppsCuQpDeltaEnabledFlag = picParam->pps_flags.bits.pps_cu_qp_delta_enabled_flag;
244 pVvcPicParams->m_ppsFlags.m_fields.m_ppsChroma_toolOffsetsPresentFlag = 0;
245 pVvcPicParams->m_ppsFlags.m_fields.m_ppsSliceChromaQpOffsetsPresentFlag = 0;
246 pVvcPicParams->m_ppsFlags.m_fields.m_ppsCuChromaQpOffsetListEnabledFlag = picParam->pps_flags.bits.pps_cu_chroma_qp_offset_list_enabled_flag;
247 pVvcPicParams->m_ppsFlags.m_fields.m_ppsDeblockingFilterOverrideEnabledFlag = picParam->pps_flags.bits.pps_deblocking_filter_override_enabled_flag;
248 pVvcPicParams->m_ppsFlags.m_fields.m_ppsDeblockingFilterDisabledFlag = picParam->pps_flags.bits.pps_deblocking_filter_disabled_flag;
249 pVvcPicParams->m_ppsFlags.m_fields.m_ppsDbfInfoInPhFlag = picParam->pps_flags.bits.pps_dbf_info_in_ph_flag;
250 pVvcPicParams->m_ppsFlags.m_fields.m_ppsRplInfoInPhFlag = 0;
251 pVvcPicParams->m_ppsFlags.m_fields.m_ppsSaoInfoInPhFlag = picParam->pps_flags.bits.pps_sao_info_in_ph_flag;
252 pVvcPicParams->m_ppsFlags.m_fields.m_ppsAlfInfoInPhFlag = picParam->pps_flags.bits.pps_alf_info_in_ph_flag;
253 pVvcPicParams->m_ppsFlags.m_fields.m_ppsWpInfoInPhFlag = 0;
254
255 pVvcPicParams->m_phLmcsApsId = picParam->ph_lmcs_aps_id;
256 pVvcPicParams->m_phScalingListApsId = picParam->ph_scaling_list_aps_id;
257 pVvcPicParams->m_phLog2DiffMinQtMinCbIntraSliceLuma = picParam->ph_log2_diff_min_qt_min_cb_intra_slice_luma;
258 pVvcPicParams->m_phMaxMtt_hierarchyDepthIntraSliceLuma = picParam->ph_max_mtt_hierarchy_depth_intra_slice_luma;
259 pVvcPicParams->m_phLog2DiffMaxBtMinQtIntraSliceLuma = picParam->ph_log2_diff_max_bt_min_qt_intra_slice_luma;
260 pVvcPicParams->m_phLog2DiffMax_ttMinQtIntraSliceLuma = picParam->ph_log2_diff_max_tt_min_qt_intra_slice_luma;
261 pVvcPicParams->m_phLog2DiffMinQtMinCbIntraSliceChroma = picParam->ph_log2_diff_min_qt_min_cb_intra_slice_chroma;
262 pVvcPicParams->m_phMaxMtt_hierarchyDepthIntraSliceChroma = picParam->ph_max_mtt_hierarchy_depth_intra_slice_chroma;
263 pVvcPicParams->m_phLog2DiffMaxBtMinQtIntraSliceChroma = picParam->ph_log2_diff_max_bt_min_qt_intra_slice_chroma;
264 pVvcPicParams->m_phLog2DiffMax_ttMinQtIntraSliceChroma = picParam->ph_log2_diff_max_tt_min_qt_intra_slice_chroma;
265 pVvcPicParams->m_phCuQpDeltaSubdivIntraSlice = picParam->ph_cu_qp_delta_subdiv_intra_slice;
266 pVvcPicParams->m_phCuChromaQpOffsetSubdivIntraSlice = picParam->ph_cu_chroma_qp_offset_subdiv_intra_slice;
267 pVvcPicParams->m_phLog2DiffMinQtMinCbInterSlice = picParam->ph_log2_diff_min_qt_min_cb_inter_slice;
268 pVvcPicParams->m_phMaxMtt_hierarchyDepthInterSlice = picParam->ph_max_mtt_hierarchy_depth_inter_slice;
269 pVvcPicParams->m_phLog2DiffMaxBtMinQtInterSlice = picParam->ph_log2_diff_max_bt_min_qt_inter_slice;
270 pVvcPicParams->m_phLog2DiffMax_ttMinQtInterSlice = picParam->ph_log2_diff_max_tt_min_qt_inter_slice;
271 pVvcPicParams->m_phCuQpDeltaSubdivInterSlice = picParam->ph_cu_qp_delta_subdiv_inter_slice;
272 pVvcPicParams->m_phCuChromaQpOffsetSubdivInterSlice = picParam->ph_cu_chroma_qp_offset_subdiv_inter_slice;
273 pVvcPicParams->m_phLumaBetaOffsetDiv2 = 0;
274 pVvcPicParams->m_phLumaTcOffsetDiv2 = 0;
275 pVvcPicParams->m_phCbBetaOffsetDiv2 = 0;
276 pVvcPicParams->m_phCbTcOffsetDiv2 = 0;
277 pVvcPicParams->m_phCrBetaOffsetDiv2 = 0;
278 pVvcPicParams->m_phCrTcOffsetDiv2 = 0;
279
280 // this def is not aligned btw VAAPI & HAL, need to parse each to get correct flag
281 pVvcPicParams->m_phFlags.m_fields.m_phNonRefPicFlag = picParam->ph_flags.bits.ph_non_ref_pic_flag;
282 pVvcPicParams->m_phFlags.m_fields.m_phAlfEnabledFlag = picParam->ph_flags.bits.ph_alf_enabled_flag;
283 pVvcPicParams->m_phFlags.m_fields.m_phAlfCbEnabledFlag = picParam->ph_flags.bits.ph_alf_cb_enabled_flag;
284 pVvcPicParams->m_phFlags.m_fields.m_phAlfCrEnabledFlag = picParam->ph_flags.bits.ph_alf_cr_enabled_flag;
285 pVvcPicParams->m_phFlags.m_fields.m_phAlfCcCbEnabledFlag = picParam->ph_flags.bits.ph_alf_cc_cb_enabled_flag;
286 pVvcPicParams->m_phFlags.m_fields.m_phAlfCcCrEnabledFlag = picParam->ph_flags.bits.ph_alf_cc_cr_enabled_flag;
287 pVvcPicParams->m_phFlags.m_fields.m_phLmcsEnabledFlag = picParam->ph_flags.bits.ph_lmcs_enabled_flag;
288 pVvcPicParams->m_phFlags.m_fields.m_phChromaResidualScaleFlag = picParam->ph_flags.bits.ph_chroma_residual_scale_flag;
289 pVvcPicParams->m_phFlags.m_fields.m_phExplicitScalingListEnabledFlag = picParam->ph_flags.bits.ph_explicit_scaling_list_enabled_flag;
290 pVvcPicParams->m_phFlags.m_fields.m_phVirtualBoundariesPresentFlag = picParam->ph_flags.bits.ph_virtual_boundaries_present_flag;
291 pVvcPicParams->m_phFlags.m_fields.m_phTemporalMvpEnabledFlag = picParam->ph_flags.bits.ph_temporal_mvp_enabled_flag;
292 pVvcPicParams->m_phFlags.m_fields.m_numRefEntries0RplIdx0LargerThan0 = 0;
293 pVvcPicParams->m_phFlags.m_fields.m_numRefEntries1RplIdx1LargerThan0 = 0;
294 pVvcPicParams->m_phFlags.m_fields.m_phCollocatedFromL0Flag = 0;
295 pVvcPicParams->m_phFlags.m_fields.m_phMmvdFullpelOnlyFlag = picParam->ph_flags.bits.ph_mmvd_fullpel_only_flag;
296 pVvcPicParams->m_phFlags.m_fields.m_phMvdL1ZeroFlag = picParam->ph_flags.bits.ph_mvd_l1_zero_flag;
297 pVvcPicParams->m_phFlags.m_fields.m_phBdofDisabledFlag = picParam->ph_flags.bits.ph_bdof_disabled_flag;
298 pVvcPicParams->m_phFlags.m_fields.m_phDmvrDisabledFlag = picParam->ph_flags.bits.ph_dmvr_disabled_flag;
299 pVvcPicParams->m_phFlags.m_fields.m_phProfDisabledFlag = picParam->ph_flags.bits.ph_prof_disabled_flag;
300 pVvcPicParams->m_phFlags.m_fields.m_phJointCbcrSignFlag = picParam->ph_flags.bits.ph_joint_cbcr_sign_flag;
301 pVvcPicParams->m_phFlags.m_fields.m_phSaoLumaEnabledFlag = picParam->ph_flags.bits.ph_sao_luma_enabled_flag;
302 pVvcPicParams->m_phFlags.m_fields.m_phSaoChromaEnabledFlag = picParam->ph_flags.bits.ph_sao_chroma_enabled_flag;
303 pVvcPicParams->m_phFlags.m_fields.m_phDeblockingFilterDisabledFlag = picParam->ph_flags.bits.ph_deblocking_filter_disabled_flag;
304 pVvcPicParams->m_picMiscFlags.m_fields.m_intraPicFlag = picParam->PicMiscFlags.fields.IntraPicFlag;
305
306 return VA_STATUS_SUCCESS;
307 }
308
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)309 VAStatus DdiDecodeVvc::RenderPicture(
310 VADriverContextP ctx,
311 VAContextID context,
312 VABufferID *buffers,
313 int32_t numBuffers)
314 {
315 VAStatus va = VA_STATUS_SUCCESS;
316 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
317
318 DDI_CODEC_FUNC_ENTER;
319
320 void *data = nullptr;
321 for (int i = 0; i < numBuffers; i++)
322 {
323 if (!buffers || (buffers[i] == VA_INVALID_ID))
324 {
325 return VA_STATUS_ERROR_INVALID_BUFFER;
326 }
327
328 DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, buffers[i]);
329 if (nullptr == buf)
330 {
331 return VA_STATUS_ERROR_INVALID_BUFFER;
332 }
333
334 uint32_t dataSize = buf->iSize;
335 MediaLibvaInterfaceNext::MapBuffer(ctx, buffers[i], &data);
336
337 if (data == nullptr)
338 {
339 return VA_STATUS_ERROR_INVALID_BUFFER;
340 }
341
342 switch ((int32_t)buf->uiType)
343 {
344 case VASliceDataBufferType:
345 {
346 // decode bitsream buffer
347 int32_t index = GetBitstreamBufIndexFromBuffer(&m_decodeCtx->BufMgr, buf);
348 if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
349 {
350 return VA_STATUS_ERROR_INVALID_BUFFER;
351 }
352 MediaLibvaCommonNext::MediaBufferToMosResource(m_decodeCtx->BufMgr.pBitStreamBuffObject[index], &m_decodeCtx->BufMgr.resBitstreamBuffer);
353 m_decodeCtx->DecodeParams.m_dataSize += dataSize;
354 break;
355 }
356 case VASliceParameterBufferType:
357 {
358 // VVC slice control data
359 if (buf->uiNumElements == 0)
360 {
361 return VA_STATUS_ERROR_INVALID_BUFFER;
362 }
363 uint32_t numSlices = buf->uiNumElements;
364 VASliceParameterBufferVVC *slcInfoVVC = (VASliceParameterBufferVVC *)data;
365 DDI_CODEC_CHK_RET(ParseSliceParams(mediaCtx, slcInfoVVC, numSlices), "ParseSliceParams failed!");
366 m_decodeCtx->DecodeParams.m_numSlices += numSlices;
367 m_groupIndex++;
368 break;
369 }
370 case VAPictureParameterBufferType:
371 {
372 // VVC pic param
373 VAPictureParameterBufferVVC *picParam = (VAPictureParameterBufferVVC *)data;
374 DDI_CODEC_CHK_RET(ParsePicParams(mediaCtx, picParam), "ParsePicParams failed!");
375 subpic_buffer_nums = 0;
376 alf_buffer_nums = 0;
377 lmcs_buffer_nums = 0;
378 scaling_list_buffer_nums = 0;
379 tile_buffer_nums = 0;
380 slice_struct_nums = 0;
381 break;
382 }
383 case VAIQMatrixBufferType:
384 {
385 // VVC scaling list
386 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(m_decodeCtx->DecodeParams.m_picParams);
387 pVvcPicParams->m_numScalingMatrixBuffers = buf->uiNumElements;
388 if (vvcMaxScalingMatrixNum < (pVvcPicParams->m_numScalingMatrixBuffers + scaling_list_buffer_nums))
389 {
390 DDI_CODEC_ASSERTMESSAGE("numScalingListBuffers = %d exceeds max size = %d", pVvcPicParams->m_numScalingMatrixBuffers + scaling_list_buffer_nums, vvcMaxScalingMatrixNum);
391 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
392 }
393 m_decodeCtx->DecodeParams.m_iqMatrixSize = dataSize + scaling_list_buffer_nums * sizeof(CodecVvcQmData);
394 CodecVvcQmData *pVvcScalingData = (CodecVvcQmData*)(m_decodeCtx->DecodeParams.m_iqMatrixBuffer);
395 pVvcScalingData += scaling_list_buffer_nums;
396 scaling_list_buffer_nums += buf->uiNumElements;
397 MOS_SecureMemcpy(pVvcScalingData,
398 buf->uiNumElements * sizeof(CodecVvcQmData),
399 data, dataSize);
400 break;
401 }
402 case VAAlfBufferType:
403 {
404 // VVC ALF array
405 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(m_decodeCtx->DecodeParams.m_picParams);
406 pVvcPicParams->m_numAlfBuffers = buf->uiNumElements;
407 m_decodeCtx->DecodeParams.m_deblockDataSize = dataSize + alf_buffer_nums * sizeof(CodecVvcAlfData);
408 VAAlfDataVVC *alfDatas = static_cast<VAAlfDataVVC*>(data);
409 DDI_CODEC_CHK_RET(ParseAlfDatas(m_decodeCtx, alfDatas, pVvcPicParams->m_numAlfBuffers, alf_buffer_nums), "ParseAlfDatas failed!");
410 alf_buffer_nums += buf->uiNumElements;
411 break;
412 }
413 case VALmcsBufferType:
414 {
415 // VVC LMCS array
416 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(m_decodeCtx->DecodeParams.m_picParams);
417 pVvcPicParams->m_numLmcsBuffers = buf->uiNumElements;
418 VALmcsDataVVC *lmcsDatas = static_cast<VALmcsDataVVC*>(data);
419 DDI_CHK_RET(ParseLmcsDatas(m_decodeCtx, lmcsDatas, pVvcPicParams->m_numLmcsBuffers, lmcs_buffer_nums), "ParseLmcsDatas failed!");
420 m_decodeCtx->DecodeParams.m_numMacroblocks = buf->uiNumElements + lmcs_buffer_nums;
421 lmcs_buffer_nums += buf->uiNumElements;
422 break;
423 }
424 case VASubPicBufferType:
425 {
426 // VVC SubPic buffer
427 VASubPicVVC *subPicParam = static_cast<VASubPicVVC *>(data);
428 DDI_CODEC_CHK_RET(ParseSubPicParams(mediaCtx, subPicParam, buf->uiNumElements, subpic_buffer_nums), "ParseSubPicParams failed!");
429 subpic_buffer_nums += buf->uiNumElements;
430 break;
431 }
432 case VATileBufferType:
433 {
434 // VVC Tile buffer
435 uint16_t *tileParam = static_cast<uint16_t *>(data);
436 DDI_CODEC_CHK_RET(ParseTileParams(mediaCtx, tileParam, buf->uiNumElements, tile_buffer_nums), "ParseTileParams failed!");
437 tile_buffer_nums += buf->uiNumElements;
438 break;
439 }
440 case VASliceStructBufferType:
441 {
442 // VVC SliceStruct buffer
443 VASliceStructVVC *sliceStructParam = static_cast<VASliceStructVVC *>(data);
444 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(m_decodeCtx->DecodeParams.m_picParams);
445 if ((sliceStructParam == nullptr) || (pVvcPicParams == nullptr))
446 {
447 DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing VVC SliceStruct parameter\n");
448 return VA_STATUS_ERROR_INVALID_PARAMETER;
449 }
450
451 // assume PicParam is always parsed before this buffer
452 if (!pVvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
453 {
454 DDI_CODEC_NORMALMESSAGE("No Slice Struct buffer indicated by Pic Params buffer, just ignore the Slice Struct Buffer.");
455 return VA_STATUS_SUCCESS;
456 }
457 DDI_CODEC_CHK_RET(ParseSliceStructParams(mediaCtx, sliceStructParam, buf->uiNumElements, slice_struct_nums), "ParseSliceStructParams failed!");
458 slice_struct_nums += buf->uiNumElements;
459 pVvcPicParams->m_numSliceStructsMinus1 = slice_struct_nums - 1;
460 break;
461 }
462 default:
463 va = m_decodeCtx->pCpDdiInterfaceNext->RenderCencPicture(ctx, context, buf, data);
464 break;
465 }
466 MediaLibvaInterfaceNext::UnmapBuffer(ctx, buffers[i]);
467 }
468
469 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(m_decodeCtx->DecodeParams.m_picParams);
470 // for slice struct buffers check
471 if(vvcMaxSliceNum < slice_struct_nums)
472 {
473 DDI_CODEC_ASSERTMESSAGE("numSliceStructs = %d exceeds max size = %d", slice_struct_nums, vvcMaxSliceNum);
474 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
475 }
476
477 // for subpic buffers check
478 if(vvcMaxSliceNum < subpic_buffer_nums)
479 {
480 DDI_CODEC_ASSERTMESSAGE("numSubPics = %d exceeds max size = %d", subpic_buffer_nums, vvcMaxSliceNum);
481 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
482 }
483
484 if (pVvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && pVvcPicParams->m_spsNumSubpicsMinus1 > 0)
485 {
486 if (subpic_buffer_nums && ((pVvcPicParams->m_spsNumSubpicsMinus1 + 1) != subpic_buffer_nums))
487 {
488 DDI_CODEC_ASSERTMESSAGE("SubPic number inconsistent between Pic Params buffer and SubPic buffer.");
489 return VA_STATUS_ERROR_INVALID_BUFFER;
490 }
491 }
492
493 // for tile buffers check
494 if(vvcMaxSliceNum < tile_buffer_nums)
495 {
496 DDI_CODEC_ASSERTMESSAGE("numTiles = %d exceeds max size = %d", tile_buffer_nums, vvcMaxSliceNum);
497 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
498 }
499
500 if (tile_buffer_nums && (pVvcPicParams->m_ppsNumExpTileColumnsMinus1 +
501 pVvcPicParams->m_ppsNumExpTileRowsMinus1 + 2 != tile_buffer_nums))
502 {
503 DDI_CODEC_ASSERTMESSAGE("Tile Params number inconsistent between Pic Params buffer and Tile params buffer.");
504 return VA_STATUS_ERROR_INVALID_BUFFER;
505 }
506
507 DDI_FUNCTION_EXIT(va);
508 return va;
509 }
510
ParseAlfDatas(DDI_DECODE_CONTEXT * decodeCtx,VAAlfDataVVC * alfDatas,uint32_t numAlfDatas,uint32_t numAlfBuffers)511 VAStatus DdiDecodeVvc::ParseAlfDatas(
512 DDI_DECODE_CONTEXT *decodeCtx,
513 VAAlfDataVVC *alfDatas,
514 uint32_t numAlfDatas,
515 uint32_t numAlfBuffers)
516 {
517 DDI_CHK_NULL(decodeCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
518 if (vvcMaxAlfNum < (numAlfDatas + numAlfBuffers))
519 {
520 DDI_CODEC_ASSERTMESSAGE("numAlfBuffers = %d exceeds max size = %d", numAlfDatas + numAlfBuffers, vvcMaxAlfNum);
521 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
522 }
523 CodecVvcAlfData *pVvcAlfData = (CodecVvcAlfData*)(decodeCtx->DecodeParams.m_deblockData);
524 pVvcAlfData += numAlfBuffers;
525 if ((alfDatas == nullptr) || (pVvcAlfData == nullptr))
526 {
527 DDI_ASSERTMESSAGE("Invalid Parameter for Parsing VVC ALF Datas\n");
528 return VA_STATUS_ERROR_INVALID_PARAMETER;
529 }
530
531 for (uint32_t iDataCount = 0; iDataCount < numAlfDatas; iDataCount++)
532 {
533 pVvcAlfData->m_apsAdaptationParameterSetId = alfDatas->aps_adaptation_parameter_set_id;
534 pVvcAlfData->m_alfLumaNumFiltersSignalledMinus1 = alfDatas->alf_luma_num_filters_signalled_minus1;
535 pVvcAlfData->m_alfChromaNumAltFiltersMinus1 = alfDatas->alf_chroma_num_alt_filters_minus1;
536 pVvcAlfData->m_alfCcCbFiltersSignalledMinus1 = alfDatas->alf_cc_cb_filters_signalled_minus1;
537 pVvcAlfData->m_alfCcCrFiltersSignalledMinus1 = alfDatas->alf_cc_cr_filters_signalled_minus1;
538 pVvcAlfData->m_alfFlags.m_fields.m_alfLumaFilterSignalFlag = alfDatas->alf_flags.bits.alf_luma_filter_signal_flag;
539 pVvcAlfData->m_alfFlags.m_fields.m_alfChromaFilterSignalFlag = alfDatas->alf_flags.bits.alf_chroma_filter_signal_flag;
540 pVvcAlfData->m_alfFlags.m_fields.m_alfCcCbFilterSignalFlag = alfDatas->alf_flags.bits.alf_cc_cb_filter_signal_flag;
541 pVvcAlfData->m_alfFlags.m_fields.m_alfCcCrFilterSignalFlag = alfDatas->alf_flags.bits.alf_cc_cr_filter_signal_flag;
542 pVvcAlfData->m_alfFlags.m_fields.m_alfLumaClipFlag = alfDatas->alf_flags.bits.alf_luma_clip_flag;
543 pVvcAlfData->m_alfFlags.m_fields.m_alfChromaClipFlag = alfDatas->alf_flags.bits.alf_chroma_clip_flag;
544 pVvcAlfData->m_alfFlags.m_fields.m_reservedBits = alfDatas->alf_flags.bits.reserved;
545 for (int i = 0; i < 25; i++)
546 {
547 for (int j = 0; j < 12; j++)
548 {
549 pVvcAlfData->m_alfCoeffL[i][j] = alfDatas->filtCoeff[i][j];
550 pVvcAlfData->m_alfLumaClipIdx[i][j] = alfDatas->alf_luma_clip_idx[i][j];
551 }
552 }
553 for (int i = 0; i < 8; i++)
554 {
555 for (int j = 0; j < 6; j++)
556 {
557 pVvcAlfData->m_alfCoeffC[i][j] = alfDatas->AlfCoeffC[i][j];
558 pVvcAlfData->m_alfChromaClipIdx[i][j] = alfDatas->alf_chroma_clip_idx[i][j];
559 }
560 }
561 for (int i = 0; i < 4; i++)
562 {
563 for (int j = 0; j < 7; j++)
564 {
565 pVvcAlfData->m_ccAlfApsCoeffCb[i][j] = alfDatas->CcAlfApsCoeffCb[i][j];
566 pVvcAlfData->m_ccAlfApsCoeffCr[i][j] = alfDatas->CcAlfApsCoeffCr[i][j];
567 }
568 }
569 MOS_SecureMemcpy(pVvcAlfData->m_alfLumaCoeffDeltaIdx, 25, alfDatas->alf_luma_coeff_delta_idx, 25);
570 MOS_SecureMemcpy(pVvcAlfData->m_reserved32b, VA_PADDING_MEDIUM, alfDatas->va_reserved, VA_PADDING_MEDIUM);
571 alfDatas++;
572 pVvcAlfData++;
573 }
574 return VA_STATUS_SUCCESS;
575 }
576
ParseLmcsDatas(DDI_DECODE_CONTEXT * decodeCtx,VALmcsDataVVC * LmcsDatas,uint32_t numLmcsDatas,uint32_t numLMCSBuffers)577 VAStatus DdiDecodeVvc::ParseLmcsDatas(
578 DDI_DECODE_CONTEXT *decodeCtx,
579 VALmcsDataVVC *LmcsDatas,
580 uint32_t numLmcsDatas,
581 uint32_t numLMCSBuffers)
582 {
583 DDI_CHK_NULL(decodeCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
584 if (vvcMaxLmcsNum < (numLmcsDatas + numLMCSBuffers))
585 {
586 DDI_CODEC_ASSERTMESSAGE("numLMCSBuffers = %d exceeds max size = %d", numLmcsDatas + numLMCSBuffers, vvcMaxLmcsNum);
587 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
588 }
589 CodecVvcLmcsData* pVvcLmcsData = (CodecVvcLmcsData*)(decodeCtx->DecodeParams.m_macroblockParams);
590 pVvcLmcsData += numLMCSBuffers;
591 if ((LmcsDatas == nullptr) || (pVvcLmcsData == nullptr))
592 {
593 DDI_ASSERTMESSAGE("Invalid Parameter for Parsing LMCS Datas\n");
594 return VA_STATUS_ERROR_INVALID_PARAMETER;
595 }
596
597 for (uint32_t iDataCount = 0; iDataCount < numLmcsDatas; iDataCount++)
598 {
599 pVvcLmcsData->m_apsAdaptationParameterSetId = LmcsDatas->aps_adaptation_parameter_set_id;
600 pVvcLmcsData->m_lmcsMinBinIdx = LmcsDatas->lmcs_min_bin_idx;
601 pVvcLmcsData->m_lmcsDeltaMaxBinIdx = LmcsDatas->lmcs_delta_max_bin_idx;
602 pVvcLmcsData->m_lmcsDeltaCrs = LmcsDatas->lmcsDeltaCrs;
603 MOS_SecureMemcpy(pVvcLmcsData->m_lmcsDeltaCW, 16 * sizeof(uint16_t), LmcsDatas->lmcsDeltaCW, 16 * sizeof(uint16_t));
604 LmcsDatas++;
605 pVvcLmcsData++;
606 }
607 return VA_STATUS_SUCCESS;
608 }
609
ParseWeightedPredInfo(CodecVvcSliceParams * sliceParams,VAWeightedPredInfo * wpInfoParams)610 VAStatus DdiDecodeVvc::ParseWeightedPredInfo(
611 CodecVvcSliceParams* sliceParams,
612 VAWeightedPredInfo* wpInfoParams)
613 {
614 if ((sliceParams == nullptr) || (wpInfoParams == nullptr))
615 {
616 DDI_ASSERTMESSAGE("Invalid Parameter for Parsing Weighted Info Params\n");
617 return VA_STATUS_ERROR_INVALID_PARAMETER;
618 }
619 sliceParams->m_wpInfo.m_lumaLog2WeightDenom = wpInfoParams->luma_log2_weight_denom;
620 sliceParams->m_wpInfo.m_deltaChromaLog2WeightDenom = wpInfoParams->delta_chroma_log2_weight_denom;
621 sliceParams->m_wpInfo.m_numL0Weights = wpInfoParams->num_l0_weights;
622 sliceParams->m_wpInfo.m_numL1Weights = wpInfoParams->num_l1_weights;
623 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_lumaWeightL0Flag, 15 * sizeof(uint8_t), wpInfoParams->luma_weight_l0_flag, 15 * sizeof(uint8_t));
624 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_chromaWeightL0Flag, 15 * sizeof(uint8_t), wpInfoParams->chroma_weight_l0_flag, 15 * sizeof(uint8_t));
625 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_deltaLumaWeightL0, 15 * sizeof(int8_t), wpInfoParams->delta_luma_weight_l0, 15 * sizeof(int8_t));
626 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_lumaOffsetL0, 15 * sizeof(int8_t), wpInfoParams->luma_offset_l0, 15 * sizeof(int8_t));
627 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_deltaChromaWeightL0, 15 * 2 * sizeof(int8_t), wpInfoParams->delta_chroma_weight_l0, 15 * 2 * sizeof(int8_t));
628 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_deltaChromaOffsetL0, 15 * 2 * sizeof(int16_t), wpInfoParams->delta_chroma_offset_l0, 15 * 2 * sizeof(int16_t));
629 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_lumaWeightL1Flag, 15 * sizeof(uint8_t), wpInfoParams->luma_weight_l1_flag, 15 * sizeof(uint8_t));
630 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_chromaWeightL1Flag, 15 * sizeof(uint8_t), wpInfoParams->chroma_weight_l1_flag, 15 * sizeof(uint8_t));
631 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_deltaLumaWeightL1, 15 * sizeof(int8_t), wpInfoParams->delta_luma_weight_l1, 15 * sizeof(int8_t));
632 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_lumaOffsetL1, 15 * sizeof(int8_t), wpInfoParams->luma_offset_l1, 15 * sizeof(int8_t));
633 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_deltaChromaWeightL1, 15 * 2 * sizeof(int8_t), wpInfoParams->delta_chroma_weight_l1, 15 * 2 * sizeof(int8_t));
634 MOS_SecureMemcpy(sliceParams->m_wpInfo.m_deltaChromaOffsetL1, 15 * 2 * sizeof(int16_t), wpInfoParams->delta_chroma_offset_l1, 15 * 2 * sizeof(int16_t));
635
636 return VA_STATUS_SUCCESS;
637 }
638
InitResourceBuffer()639 VAStatus DdiDecodeVvc::InitResourceBuffer()
640 {
641 DDI_CODEC_FUNC_ENTER;
642
643 DDI_CODEC_BUFFER_PARAM_VVC *Codec_Param_VVC = nullptr;
644 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_decodeCtx->BufMgr);
645 bufMgr->pSliceData = nullptr;
646 bufMgr->ui64BitstreamOrder = 0;
647 bufMgr->dwMaxBsSize = m_width * m_height * 3 / 2; // need consider 2byte case
648 // minimal 10k bytes for some special case. Will refractor this later
649 if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
650 {
651 bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
652 }
653
654 // init decode bitstream buffer object
655 for (uint32_t i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
656 {
657 bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
658 if (bufMgr->pBitStreamBuffObject[i] == nullptr)
659 {
660 FreeResourceBuffer();
661 return VA_STATUS_ERROR_ALLOCATION_FAILED;
662 }
663 bufMgr->pBitStreamBuffObject[i]->iSize = bufMgr->dwMaxBsSize;
664 bufMgr->pBitStreamBuffObject[i]->uiType = VASliceDataBufferType;
665 bufMgr->pBitStreamBuffObject[i]->format = Media_Format_Buffer;
666 bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
667 bufMgr->pBitStreamBuffObject[i]->bo = nullptr;
668 bufMgr->pBitStreamBase[i] = nullptr;
669 }
670
671 bufMgr->m_maxNumSliceData = vvcMaxSliceNum;
672 bufMgr->pSliceData = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) * bufMgr->m_maxNumSliceData);
673
674 if (bufMgr->pSliceData == nullptr)
675 {
676 FreeResourceBuffer();
677 return VA_STATUS_ERROR_ALLOCATION_FAILED;
678 }
679
680 bufMgr->dwNumSliceData = 0;
681 bufMgr->dwNumSliceControl = 0;
682 bufMgr->pCodecParamReserved = (DDI_CODEC_BUFFER_PARAM_VVC *)MOS_AllocAndZeroMemory(sizeof(DDI_CODEC_BUFFER_PARAM_VVC));
683
684 if (bufMgr->pCodecParamReserved == nullptr)
685 {
686 FreeResourceBuffer();
687 return VA_STATUS_ERROR_ALLOCATION_FAILED;
688 }
689
690 bufMgr->pCodecSlcParamReserved = (VASliceParameterBufferVVC *)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferVVC) * vvcMaxSliceNum);
691 Codec_Param_VVC = (DDI_CODEC_BUFFER_PARAM_VVC *)bufMgr->pCodecParamReserved;
692 Codec_Param_VVC->pVASliceParameterBufferVVC = (VASliceParameterBufferVVC *)bufMgr->pCodecSlcParamReserved;
693
694 if (bufMgr->pCodecSlcParamReserved == nullptr)
695 {
696 FreeResourceBuffer();
697 return VA_STATUS_ERROR_ALLOCATION_FAILED;
698 }
699
700 return VA_STATUS_SUCCESS;
701 }
702
FreeResourceBuffer()703 void DdiDecodeVvc::FreeResourceBuffer()
704 {
705 DDI_CODEC_FUNC_ENTER;
706
707 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_decodeCtx->BufMgr);
708
709 // free decode bitstream buffer
710 for (uint32_t i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
711 {
712 if (bufMgr->pBitStreamBase[i])
713 {
714 MediaLibvaUtilNext::UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
715 bufMgr->pBitStreamBase[i] = nullptr;
716 }
717 if (bufMgr->pBitStreamBuffObject[i])
718 {
719 MediaLibvaUtilNext::FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
720 MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
721 bufMgr->pBitStreamBuffObject[i] = nullptr;
722 }
723 }
724
725 if (bufMgr->pCodecParamReserved)
726 {
727 DDI_CODEC_BUFFER_PARAM_VVC* Codec_Param_VVC =
728 static_cast<DDI_CODEC_BUFFER_PARAM_VVC *>(bufMgr->pCodecParamReserved);
729 if (Codec_Param_VVC->pVASliceParameterBufferVVC)
730 {
731 MOS_FreeMemory(Codec_Param_VVC->pVASliceParameterBufferVVC);
732 Codec_Param_VVC->pVASliceParameterBufferVVC = nullptr;
733 bufMgr->pCodecSlcParamReserved = nullptr;
734 }
735 MOS_FreeMemory(bufMgr->pCodecParamReserved);
736 bufMgr->pCodecParamReserved = nullptr;
737 }
738
739 // free decode bitstream buffer object
740 MOS_FreeMemory(bufMgr->pSliceData);
741 bufMgr->pSliceData = nullptr;
742
743 return;
744 }
745
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)746 uint8_t* DdiDecodeVvc::GetPicParamBuf(
747 DDI_CODEC_COM_BUFFER_MGR *bufMgr)
748 {
749 DDI_CODEC_FUNC_ENTER;
750
751 DDI_CODEC_BUFFER_PARAM_VVC* Codec_Param_VVC = static_cast<DDI_CODEC_BUFFER_PARAM_VVC *>(bufMgr->pCodecParamReserved);
752 return (uint8_t*)(&(Codec_Param_VVC->PicParamVVC));
753 }
754
CreateBuffer(VABufferType type,uint32_t size,uint32_t numElements,void * data,VABufferID * bufId)755 VAStatus DdiDecodeVvc::CreateBuffer(
756 VABufferType type,
757 uint32_t size,
758 uint32_t numElements,
759 void *data,
760 VABufferID *bufId)
761 {
762 DDI_CODEC_FUNC_ENTER;
763
764 DDI_MEDIA_BUFFER *buf;
765 PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufferHeapElement;
766 MOS_STATUS status = MOS_STATUS_SUCCESS;
767 VAStatus va = VA_STATUS_SUCCESS;
768
769 buf = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
770 if (buf == nullptr)
771 {
772 return VA_STATUS_ERROR_ALLOCATION_FAILED;
773 }
774 buf->iSize = size * numElements;
775 buf->uiNumElements = numElements;
776 buf->uiType = type;
777 buf->format = Media_Format_Buffer;
778 buf->uiOffset = 0;
779 buf->bCFlushReq = false;
780 buf->pMediaCtx = m_decodeCtx->pMediaCtx;
781
782 switch ((int32_t)type)
783 {
784 case VASliceDataBufferType:
785 case VAProtectedSliceDataBufferType:
786 va = AllocBsBuffer(&(m_decodeCtx->BufMgr), buf);
787 if(va != VA_STATUS_SUCCESS)
788 {
789 if(buf)
790 {
791 MOS_FreeMemory(buf->pData);
792 MOS_FreeMemory(buf);
793 }
794 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
795 }
796 break;
797 case VASliceParameterBufferType:
798 va = AllocSliceControlBuffer(buf);
799 if(va != VA_STATUS_SUCCESS)
800 {
801 if(buf)
802 {
803 MOS_FreeMemory(buf->pData);
804 MOS_FreeMemory(buf);
805 }
806 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
807 }
808 buf->format = Media_Format_CPU;
809 break;
810 case VAPictureParameterBufferType:
811 buf->pData = GetPicParamBuf(&(m_decodeCtx->BufMgr));
812 buf->format = Media_Format_CPU;
813 break;
814 case VAIQMatrixBufferType:
815 case VAAlfBufferType:
816 case VALmcsBufferType:
817 case VASubPicBufferType:
818 case VATileBufferType:
819 case VASliceStructBufferType:
820 buf->pData = (uint8_t*)MOS_AllocAndZeroMemory(size * numElements);
821 buf->format = Media_Format_CPU;
822 break;
823 default:
824 va = m_decodeCtx->pCpDdiInterface->CreateBuffer(type, buf, size, numElements);
825 if (va == VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE)
826 {
827 DDI_CODEC_ASSERTMESSAGE("DDI:Decode CreateBuffer unsuppoted buffer type.");
828 buf->pData = (uint8_t*)MOS_AllocAndZeroMemory(size * numElements);
829 buf->format = Media_Format_CPU;
830 if(buf->pData != nullptr)
831 {
832 va = VA_STATUS_SUCCESS;
833 }
834 }
835 break;
836 }
837
838 bufferHeapElement = MediaLibvaUtilNext::AllocPMediaBufferFromHeap(m_decodeCtx->pMediaCtx->pBufferHeap);
839 if (nullptr == bufferHeapElement)
840 {
841 if(buf)
842 {
843 MOS_FreeMemory(buf->pData);
844 MOS_FreeMemory(buf);
845 }
846 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
847 }
848 bufferHeapElement->pBuffer = buf;
849 bufferHeapElement->pCtx = (void*)m_decodeCtx;
850 bufferHeapElement->uiCtxType = DDI_MEDIA_CONTEXT_TYPE_DECODER;
851 *bufId = bufferHeapElement->uiVaBufferID;
852
853 m_decodeCtx->pMediaCtx->uiNumBufs++;
854
855 if(data == nullptr)
856 {
857 return va;
858 }
859
860 if(true == buf->bCFlushReq && mos_bo_busy(buf->bo))
861 {
862 mos_bo_wait_rendering(buf->bo);
863 }
864 status = MOS_SecureMemcpy((void *)(buf->pData + buf->uiOffset), size * numElements, data, size * numElements);
865 DDI_CHK_CONDITION((status != MOS_STATUS_SUCCESS), "DDI:Failed to copy buffer data!", VA_STATUS_ERROR_OPERATION_FAILED);
866 return va;
867 }
868
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)869 VAStatus DdiDecodeVvc::AllocSliceControlBuffer(
870 DDI_MEDIA_BUFFER *buf)
871 {
872 DDI_CODEC_FUNC_ENTER;
873
874 DDI_CODEC_COM_BUFFER_MGR *bufMgr;
875 bufMgr = &(m_decodeCtx->BufMgr);
876
877 DDI_CODEC_BUFFER_PARAM_VVC* Codec_Param_VVC =
878 static_cast<DDI_CODEC_BUFFER_PARAM_VVC *>(bufMgr->pCodecParamReserved);
879 Codec_Param_VVC->pVASliceParameterBufferVVC =
880 static_cast<VASliceParameterBufferVVC *>(bufMgr->pCodecSlcParamReserved);
881 if (Codec_Param_VVC->pVASliceParameterBufferVVC == nullptr)
882 {
883 return VA_STATUS_ERROR_ALLOCATION_FAILED;
884 }
885
886 if (buf->uiNumElements > vvcMaxSliceNum)
887 {
888 DDI_CODEC_ASSERTMESSAGE("buf->uiNumElements = %d : exceeds vvcMaxSliceNum = %d",
889 buf->uiNumElements, vvcMaxSliceNum);
890 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
891 }
892 buf->pData = (uint8_t*)Codec_Param_VVC->pVASliceParameterBufferVVC;
893 buf->uiOffset = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferVVC);
894
895 bufMgr->dwNumSliceControl += buf->uiNumElements;
896
897 return VA_STATUS_SUCCESS;
898 }
899
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)900 VAStatus DdiDecodeVvc::CodecHalInit(
901 DDI_MEDIA_CONTEXT *mediaCtx,
902 void *ptr)
903 {
904 DDI_CODEC_FUNC_ENTER;
905
906 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
907 DDI_CODEC_CHK_NULL(ptr, "nullptr", VA_STATUS_ERROR_INVALID_PARAMETER);
908 VAStatus vaStatus = VA_STATUS_SUCCESS;
909
910 CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
911 m_decodeCtx->pCpDdiInterfaceNext->SetCpParams(m_ddiDecodeAttr->componentData.data.encryptType, m_codechalSettings);
912
913 CODECHAL_STANDARD_INFO standardInfo;
914 memset(&standardInfo, 0, sizeof(standardInfo));
915
916 standardInfo.CodecFunction = codecFunction;
917 standardInfo.Mode = (CODECHAL_MODE)m_decodeCtx->wMode;
918
919 m_codechalSettings->codecFunction = codecFunction;
920 m_codechalSettings->width = m_width;
921 m_codechalSettings->height = m_height;
922 m_codechalSettings->intelEntrypointInUse = false;
923
924 // VAProfileVVCMain10 and VAProfileVVCMultilayerMain10 supports both 420 8bit and 420 10bit
925 m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
926
927 if (static_cast<int>(m_ddiDecodeAttr->profile) == VAProfileVVCMain10 ||
928 static_cast<int>(m_ddiDecodeAttr->profile) == VAProfileVVCMultilayerMain10) //todo: opensource issue here
929 {
930 m_codechalSettings->lumaChromaDepth |= CODECHAL_LUMA_CHROMA_DEPTH_10_BITS;
931 }
932
933 m_codechalSettings->shortFormatInUse = m_decodeCtx->bShortFormatInUse;
934 m_codechalSettings->mode = CODECHAL_DECODE_MODE_VVCVLD;
935 m_codechalSettings->standard = CODECHAL_VVC;
936 m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV420;
937
938 m_decodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CodecVvcPicParams));
939 if (m_decodeCtx->DecodeParams.m_picParams == nullptr)
940 {
941 FreeResource();
942 return VA_STATUS_ERROR_ALLOCATION_FAILED;
943 }
944
945 m_decodeCtx->DecodeParams.m_extPicParams = MOS_AllocAndZeroMemory(vvcMaxSubpicNum * sizeof(CodecVvcSubpicParam));
946 if (m_decodeCtx->DecodeParams.m_extPicParams == nullptr)
947 {
948 FreeResource();
949 return VA_STATUS_ERROR_ALLOCATION_FAILED;
950 }
951
952 m_decodeCtx->DecodeParams.m_sliceParams = MOS_AllocAndZeroMemory(vvcMaxSliceNum * sizeof(CodecVvcSliceParams));
953 if (m_decodeCtx->DecodeParams.m_sliceParams == nullptr)
954 {
955 FreeResource();
956 return VA_STATUS_ERROR_ALLOCATION_FAILED;
957 }
958
959 m_decodeCtx->DecodeParams.m_extSliceParams = MOS_AllocAndZeroMemory(vvcMaxSliceNum * sizeof(CodecVvcSliceStructure));
960 if (m_decodeCtx->DecodeParams.m_extSliceParams == nullptr)
961 {
962 FreeResource();
963 return VA_STATUS_ERROR_ALLOCATION_FAILED;
964 }
965
966 m_decodeCtx->DecodeParams.m_tileParams = MOS_AllocAndZeroMemory(vvcMaxTileParamsNum * sizeof(uint16_t));
967 if (m_decodeCtx->DecodeParams.m_tileParams == nullptr)
968 {
969 FreeResource();
970 return VA_STATUS_ERROR_ALLOCATION_FAILED;
971 }
972
973 m_decodeCtx->DecodeParams.m_iqMatrixBuffer = MOS_AllocAndZeroMemory(vvcMaxScalingMatrixNum * sizeof(CodecVvcQmData));
974 if (m_decodeCtx->DecodeParams.m_iqMatrixBuffer == nullptr)
975 {
976 FreeResource();
977 return VA_STATUS_ERROR_ALLOCATION_FAILED;
978 }
979
980 m_decodeCtx->DecodeParams.m_deblockData = (uint8_t *)MOS_AllocAndZeroMemory(vvcMaxAlfNum * sizeof(CodecVvcAlfData));
981 if (m_decodeCtx->DecodeParams.m_deblockData == nullptr)
982 {
983 FreeResource();
984 return VA_STATUS_ERROR_ALLOCATION_FAILED;
985 }
986
987 m_decodeCtx->DecodeParams.m_macroblockParams = MOS_AllocAndZeroMemory(vvcMaxLmcsNum * sizeof(CodecVvcLmcsData));
988 if (m_decodeCtx->DecodeParams.m_macroblockParams == nullptr)
989 {
990 FreeResource();
991 return VA_STATUS_ERROR_ALLOCATION_FAILED;
992 }
993
994 vaStatus = CreateCodecHal(mediaCtx,
995 ptr,
996 &standardInfo);
997
998 if (vaStatus != VA_STATUS_SUCCESS)
999 {
1000 FreeResource();
1001 return vaStatus;
1002 }
1003
1004 if (InitResourceBuffer() != VA_STATUS_SUCCESS)
1005 {
1006 FreeResource();
1007 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1008 }
1009
1010 return vaStatus;
1011 }
1012
FreeResource()1013 void DdiDecodeVvc::FreeResource()
1014 {
1015 DDI_CODEC_FUNC_ENTER;
1016
1017 FreeResourceBuffer();
1018
1019 if (m_decodeCtx->pCodecHal)
1020 {
1021 m_decodeCtx->pCodecHal->Destroy();
1022 MOS_Delete(m_decodeCtx->pCodecHal);
1023 m_decodeCtx->pCodecHal = nullptr;
1024 }
1025
1026 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_picParams);
1027 m_decodeCtx->DecodeParams.m_picParams = nullptr;
1028 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_picParams);
1029 m_decodeCtx->DecodeParams.m_extPicParams = nullptr;
1030 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_sliceParams);
1031 m_decodeCtx->DecodeParams.m_sliceParams = nullptr;
1032 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_extSliceParams);
1033 m_decodeCtx->DecodeParams.m_extSliceParams = nullptr;
1034 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_tileParams);
1035 m_decodeCtx->DecodeParams.m_tileParams = nullptr;
1036 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_iqMatrixBuffer);
1037 m_decodeCtx->DecodeParams.m_iqMatrixBuffer = nullptr;
1038 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_deblockData);
1039 m_decodeCtx->DecodeParams.m_deblockData = nullptr;
1040 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_macroblockParams);
1041 m_decodeCtx->DecodeParams.m_macroblockParams = nullptr;
1042
1043 return;
1044 }
1045
GetFormat()1046 MOS_FORMAT DdiDecodeVvc::GetFormat()
1047 {
1048 DDI_CODEC_FUNC_ENTER;
1049
1050 MOS_FORMAT format = Format_Invalid;
1051 CodechalDecodeParams *decodeParams = &m_decodeCtx->DecodeParams;
1052 DDI_CODEC_CHK_NULL(decodeParams, "nullptr params", Format_Invalid);
1053 CodecVvcPicParams *picParams = static_cast<CodecVvcPicParams*>(decodeParams->m_picParams);
1054 DDI_CODEC_CHK_NULL(picParams, "nullptr params", Format_Invalid);
1055
1056 if (picParams->m_spsBitdepthMinus8 == 0)
1057 {
1058 if (picParams->m_spsChromaFormatIdc == 1) // 4:2:0 8bit surface
1059 {
1060 format = Format_NV12;
1061 }
1062 }
1063 else if (picParams->m_spsBitdepthMinus8 == 2)
1064 {
1065 if (picParams->m_spsChromaFormatIdc == 1) // 4:2:0 10bit surface
1066 {
1067 format = Format_P010;
1068 }
1069 }
1070 return format;
1071 }
1072
DestroyContext(VADriverContextP ctx)1073 void DdiDecodeVvc::DestroyContext(
1074 VADriverContextP ctx)
1075 {
1076 DDI_CODEC_FUNC_ENTER;
1077
1078 FreeResourceBuffer();
1079
1080 // release VVC specific buffers that are not covered in base function
1081 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_deblockData);
1082 m_decodeCtx->DecodeParams.m_deblockData = nullptr;
1083
1084 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_macroblockParams);
1085 m_decodeCtx->DecodeParams.m_macroblockParams = nullptr;
1086
1087 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_tileParams);
1088 m_decodeCtx->DecodeParams.m_tileParams = nullptr;
1089
1090 // explicitly call the base function to do the further clean-up
1091 DdiDecodeBase::DestroyContext(ctx);
1092
1093 return;
1094 }
1095
ContextInit(int32_t picWidth,int32_t picHeight)1096 void DdiDecodeVvc::ContextInit(
1097 int32_t picWidth,
1098 int32_t picHeight)
1099 {
1100 DDI_CODEC_FUNC_ENTER;
1101
1102 // call the function in base class to initialize it.
1103 DdiDecodeBase::ContextInit(picWidth, picHeight);
1104 m_decodeCtx->wMode = CODECHAL_DECODE_MODE_VVCVLD;
1105
1106 return;
1107 }
1108
SetupCodecPicture(DDI_MEDIA_CONTEXT * mediaCtx,DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,PCODEC_PICTURE pCodecHalPic,VAPictureVVC vaPic,VvcPicEntryType bSurfaceType)1109 void DdiDecodeVvc::SetupCodecPicture(
1110 DDI_MEDIA_CONTEXT *mediaCtx,
1111 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl,
1112 PCODEC_PICTURE pCodecHalPic,
1113 VAPictureVVC vaPic,
1114 VvcPicEntryType bSurfaceType)
1115 {
1116 DDI_CODEC_FUNC_ENTER;
1117
1118 if (bSurfaceType != VvcPicEntryRefPicList)
1119 {
1120 if (vaPic.picture_id != VA_INVALID_SURFACE)
1121 {
1122 if(vaPic.flags & VA_PICTURE_VVC_UNAVAILABLE_REFERENCE)
1123 {
1124 pCodecHalPic->FrameIdx = vaPic.picture_id;
1125 }
1126 else
1127 {
1128 DDI_MEDIA_SURFACE *surface = MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, vaPic.picture_id);
1129 pCodecHalPic->FrameIdx = GetRenderTargetID(rtTbl, surface);
1130 }
1131 }
1132 else
1133 {
1134 pCodecHalPic->FrameIdx = (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX;
1135 }
1136 }
1137
1138 switch (bSurfaceType)
1139 {
1140 case VvcPicEntryCurrFrame:
1141 if (pCodecHalPic->FrameIdx < CODEC_MAX_DPB_NUM_VVC)
1142 {
1143 pCodecHalPic->PicFlags = PICTURE_FRAME;
1144 }
1145 break;
1146 case VvcPicEntryRefFrameList:
1147 if (pCodecHalPic->FrameIdx >= CODEC_MAX_DPB_NUM_VVC ||
1148 vaPic.flags & VA_PICTURE_VVC_INVALID)
1149 {
1150 pCodecHalPic->PicFlags = PICTURE_INVALID;
1151 }
1152 else
1153 {
1154 // Check unavailable frame flag
1155 if (vaPic.flags & VA_PICTURE_VVC_UNAVAILABLE_REFERENCE)
1156 {
1157 pCodecHalPic->PicFlags = PICTURE_UNAVAILABLE_FRAME;
1158 }
1159 else
1160 {
1161 pCodecHalPic->PicFlags = PICTURE_FRAME;
1162 }
1163 }
1164 break;
1165 case VvcPicEntryRefPicList:
1166 if (pCodecHalPic->FrameIdx >= vvcMaxNumRefFrame)
1167 {
1168 pCodecHalPic->PicFlags = PICTURE_INVALID;
1169 }
1170 else
1171 {
1172 // Check long/short reference flag
1173 if (vaPic.flags & VA_PICTURE_VVC_LONG_TERM_REFERENCE)
1174 {
1175 pCodecHalPic->PicFlags = PICTURE_LONG_TERM_REFERENCE;
1176 }
1177 else
1178 {
1179 pCodecHalPic->PicFlags = PICTURE_SHORT_TERM_REFERENCE;
1180 }
1181 }
1182 break;
1183 default:
1184 DDI_CODEC_ASSERTMESSAGE("Unsupported VVC PicEntry type.")
1185 break;
1186 }
1187 }
1188
1189
ParseSliceParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferVVC * slcParam,uint32_t numSlices)1190 VAStatus DdiDecodeVvc::ParseSliceParams(
1191 DDI_MEDIA_CONTEXT *mediaCtx,
1192 VASliceParameterBufferVVC *slcParam,
1193 uint32_t numSlices)
1194 {
1195 DDI_CODEC_FUNC_ENTER;
1196
1197 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
1198 CodechalDecodeParams *decodeParams = &m_decodeCtx->DecodeParams;
1199 CodecVvcSliceParams *pVvcSliceParams = static_cast<CodecVvcSliceParams*>(decodeParams->m_sliceParams);
1200 pVvcSliceParams += m_decodeCtx->DecodeParams.m_numSlices;
1201 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(decodeParams->m_picParams);
1202 if ((slcParam == nullptr) || (pVvcSliceParams == nullptr) || (pVvcPicParams == nullptr))
1203 {
1204 DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing VVC Slice parameter\n");
1205 return VA_STATUS_ERROR_INVALID_PARAMETER;
1206 }
1207
1208 if(vvcMaxSliceNum < numSlices)
1209 {
1210 DDI_CODEC_ASSERTMESSAGE("numSlices = %d exceeds max size = %d", numSlices, vvcMaxSliceNum);
1211 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1212 }
1213
1214 MOS_ZeroMemory(pVvcSliceParams, (numSlices * sizeof(CodecVvcSliceParams)));
1215
1216 uint32_t sliceBaseOffset = GetBsBufOffset(m_groupIndex);
1217 for (uint32_t iSlcCount = 0; iSlcCount < numSlices; iSlcCount++)
1218 {
1219 pVvcSliceParams->m_bSNALunitDataLocation = sliceBaseOffset + slcParam->slice_data_offset;
1220 pVvcSliceParams->m_sliceBytesInBuffer = slcParam->slice_data_size;
1221 pVvcSliceParams->m_shSubpicId = slcParam->sh_subpic_id;
1222 pVvcSliceParams->m_shSliceAddress = slcParam->sh_slice_address;
1223 pVvcSliceParams->m_shNumTilesInSliceMinus1 = slcParam->sh_num_tiles_in_slice_minus1;
1224 pVvcSliceParams->m_shSliceType = slcParam->sh_slice_type;
1225 pVvcSliceParams->m_shNumAlfApsIdsLuma = slcParam->sh_num_alf_aps_ids_luma;
1226
1227 MOS_SecureMemcpy(pVvcSliceParams->m_shAlfApsIdLuma, 7, slcParam->sh_alf_aps_id_luma, 7);
1228
1229 pVvcSliceParams->m_shAlfApsIdChroma = slcParam->sh_alf_aps_id_chroma;
1230 pVvcSliceParams->m_shAlfCcCbApsId = slcParam->sh_alf_cc_cb_aps_id;
1231 pVvcSliceParams->m_shAlfCcCrApsId = slcParam->sh_alf_cc_cr_aps_id;
1232
1233 MOS_SecureMemcpy(pVvcSliceParams->m_numRefIdxActive, 2, slcParam->NumRefIdxActive, 2);
1234
1235 pVvcSliceParams->m_shCollocatedRefIdx = slcParam->sh_collocated_ref_idx;
1236 pVvcSliceParams->m_sliceQpY = slcParam->SliceQpY;
1237 pVvcSliceParams->m_shCbQpOffset = slcParam->sh_cb_qp_offset;
1238 pVvcSliceParams->m_shCrQpOffset = slcParam->sh_cr_qp_offset;
1239 pVvcSliceParams->m_shJointCbcrQpOffset = slcParam->sh_joint_cbcr_qp_offset;
1240 pVvcSliceParams->m_shLumaBetaOffsetDiv2 = slcParam->sh_luma_beta_offset_div2;
1241 pVvcSliceParams->m_shLumaTcOffsetDiv2 = slcParam->sh_luma_tc_offset_div2;
1242 pVvcSliceParams->m_shCbBetaOffsetDiv2 = slcParam->sh_cb_beta_offset_div2;
1243 pVvcSliceParams->m_shCbTcOffsetDiv2 = slcParam->sh_cb_tc_offset_div2;
1244 pVvcSliceParams->m_shCrBetaOffsetDiv2 = slcParam->sh_cr_beta_offset_div2;
1245 pVvcSliceParams->m_shCrTcOffsetDiv2 = slcParam->sh_cr_tc_offset_div2;
1246 pVvcSliceParams->m_byteOffsetToSliceData = slcParam->slice_data_byte_offset;
1247
1248 // Set up RefPicList[2][vvcMaxNumRefFrame]
1249 for (auto i = 0; i < 2; i++)
1250 {
1251 for (auto j = 0; j < vvcMaxNumRefFrame; j++)
1252 {
1253 PCODEC_PICTURE pCodecHalPic = &pVvcSliceParams->m_refPicList[i][j];
1254 pCodecHalPic->FrameIdx = (slcParam->RefPicList[i][j] == 0xff) ? CODEC_MAX_DPB_NUM_VVC : slcParam->RefPicList[i][j];
1255 if (pCodecHalPic->FrameIdx >= vvcMaxNumRefFrame)
1256 {
1257 pCodecHalPic->PicFlags = PICTURE_INVALID;
1258 }
1259 else
1260 {
1261 VAPictureVVC vaPic = {};
1262 vaPic.flags = m_refListFlags[pCodecHalPic->FrameIdx];
1263 SetupCodecPicture(mediaCtx,
1264 &m_decodeCtx->RTtbl,
1265 pCodecHalPic,
1266 vaPic,
1267 VvcPicEntryRefPicList);
1268 }
1269 }
1270 }
1271
1272 DDI_CODEC_CHK_RET(ParseWeightedPredInfo(pVvcSliceParams,&slcParam->WPInfo), "Parse Weighted Pred Info failed");
1273 pVvcSliceParams->m_longSliceFlags.m_value = slcParam->sh_flags.value;
1274
1275 bool noBackWardPredFlag = true;
1276 uint8_t refIdx = 0;
1277 if (pVvcSliceParams->m_shSliceType != vvcSliceI)
1278 {
1279 for (refIdx = 0; refIdx < pVvcSliceParams->m_numRefIdxActive[0] && noBackWardPredFlag; refIdx++)
1280 {
1281 uint8_t refPicIdx = pVvcSliceParams->m_refPicList[0][refIdx].FrameIdx;
1282
1283 if (refPicIdx < vvcMaxNumRefFrame && pVvcPicParams->m_refFramePocList[refPicIdx] > pVvcPicParams->m_picOrderCntVal)
1284 {
1285 noBackWardPredFlag = false;
1286 }
1287 }
1288 if (pVvcSliceParams->m_shSliceType == vvcSliceB)
1289 {
1290 for (refIdx = 0; refIdx < pVvcSliceParams->m_numRefIdxActive[1] && noBackWardPredFlag; refIdx++)
1291 {
1292 uint8_t refPicIdx = pVvcSliceParams->m_refPicList[1][refIdx].FrameIdx;
1293 if (refPicIdx < vvcMaxNumRefFrame && pVvcPicParams->m_refFramePocList[refPicIdx] > pVvcPicParams->m_picOrderCntVal)
1294 {
1295 noBackWardPredFlag = false;
1296 }
1297 }
1298 }
1299 }
1300 else
1301 {
1302 noBackWardPredFlag = false;
1303 }
1304 pVvcSliceParams->m_longSliceFlags.m_fields.m_noBackwardPredFlag = noBackWardPredFlag;
1305 slcParam++;
1306 pVvcSliceParams++;
1307 }
1308
1309 return VA_STATUS_SUCCESS;
1310 }
1311
1312
ParseSubPicParams(DDI_MEDIA_CONTEXT * mediaCtx,VASubPicVVC * subPicParam,uint32_t numSubPics,uint32_t numSubPicbuffers)1313 VAStatus DdiDecodeVvc::ParseSubPicParams(
1314 DDI_MEDIA_CONTEXT *mediaCtx,
1315 VASubPicVVC *subPicParam,
1316 uint32_t numSubPics,
1317 uint32_t numSubPicbuffers)
1318 {
1319 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
1320 CodecVvcPicParams *pVvcPicParams = static_cast<CodecVvcPicParams*>(m_decodeCtx->DecodeParams.m_picParams);
1321 if ((subPicParam == nullptr) || (pVvcPicParams == nullptr))
1322 {
1323 DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing VVC SubPic parameter\n");
1324 return VA_STATUS_ERROR_INVALID_PARAMETER;
1325 }
1326
1327 // assume PicParam is always parsed before this buffer
1328 if (!pVvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag || (pVvcPicParams->m_spsNumSubpicsMinus1 == 0))
1329 {
1330 DDI_CODEC_NORMALMESSAGE("No SubPic number indicated by Pic Params buffer, just ignore the SubPic Buffer.");
1331 return VA_STATUS_SUCCESS;
1332 }
1333
1334 if(vvcMaxSubpicNum < (numSubPics + numSubPicbuffers))
1335 {
1336 DDI_CODEC_ASSERTMESSAGE("numSubPics = %d exceeds max size = %d", numSubPics + numSubPicbuffers, vvcMaxSubpicNum);
1337 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1338 }
1339
1340 // Actual parsing
1341 CodecVvcSubpicParam* pVvcSubPicParams =
1342 static_cast<CodecVvcSubpicParam*>(m_decodeCtx->DecodeParams.m_extPicParams);
1343 pVvcSubPicParams += numSubPicbuffers;
1344 MOS_ZeroMemory(pVvcSubPicParams, (numSubPics * sizeof(CodecVvcSubpicParam)));
1345 for (uint32_t iSubPicCount = 0; iSubPicCount < numSubPics; iSubPicCount++)
1346 {
1347 pVvcSubPicParams->m_spsSubpicCtuTopLeftX = subPicParam->sps_subpic_ctu_top_left_x;
1348 pVvcSubPicParams->m_spsSubpicCtuTopLeftY = subPicParam->sps_subpic_ctu_top_left_y;
1349 pVvcSubPicParams->m_spsSubpicWidthMinus1 = subPicParam->sps_subpic_width_minus1;
1350 pVvcSubPicParams->m_spsSubpicHeightMinus1 = subPicParam->sps_subpic_height_minus1;
1351 pVvcSubPicParams->m_subpicIdVal = subPicParam->SubpicIdVal;
1352 pVvcSubPicParams->m_subPicFlags.m_value = subPicParam->subpic_flags.value;
1353
1354 subPicParam++;
1355 pVvcSubPicParams++;
1356 }
1357
1358 return VA_STATUS_SUCCESS;
1359 }
1360
ParseSliceStructParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceStructVVC * sliceStructParam,uint32_t numSliceStructs,uint32_t numSliceStructBuffers)1361 VAStatus DdiDecodeVvc::ParseSliceStructParams(
1362 DDI_MEDIA_CONTEXT *mediaCtx,
1363 VASliceStructVVC *sliceStructParam,
1364 uint32_t numSliceStructs,
1365 uint32_t numSliceStructBuffers)
1366 {
1367 DDI_CODEC_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER);
1368 if(vvcMaxSliceNum < (numSliceStructs + numSliceStructBuffers))
1369 {
1370 DDI_CODEC_ASSERTMESSAGE("numSliceStructs = %d exceeds max size = %d", numSliceStructs + numSliceStructBuffers, vvcMaxSliceNum);
1371 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1372 }
1373
1374 CodecVvcSliceStructure* pVvcSliceStructParams =
1375 static_cast<CodecVvcSliceStructure*>(m_decodeCtx->DecodeParams.m_extSliceParams);
1376 pVvcSliceStructParams += numSliceStructBuffers;
1377 MOS_ZeroMemory(pVvcSliceStructParams, (numSliceStructs * sizeof(CodecVvcSliceStructure)));
1378 for(int iDataCount = 0 ; iDataCount < numSliceStructs; iDataCount++)
1379 {
1380 pVvcSliceStructParams->m_sliceTopLeftTileIdx = sliceStructParam->SliceTopLeftTileIdx;
1381 pVvcSliceStructParams->m_ppsSliceWidthInTilesMinus1 = sliceStructParam->pps_slice_width_in_tiles_minus1;
1382 pVvcSliceStructParams->m_ppsSliceHeightInTilesMinus1 = sliceStructParam->pps_slice_height_in_tiles_minus1;
1383 pVvcSliceStructParams->m_ppsExpSliceHeightInCtusMinus1 = sliceStructParam->pps_exp_slice_height_in_ctus_minus1;
1384 sliceStructParam++;
1385 pVvcSliceStructParams++;
1386 }
1387
1388 return VA_STATUS_SUCCESS;
1389 }
1390
1391 } // namespace decode
1392