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