1 /*
2 * Copyright (c) 2015-2023, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     media_ddi_decode_hevc_g12.cpp
24 //! \brief    The class implementation of DdiDecodeHEVCG12  for HEVC decode
25 //!
26 
27 #include "media_libva_decoder.h"
28 #include "media_libva_util.h"
29 
30 #include "media_ddi_decode_hevc_g12.h"
31 #include "mos_solo_generic.h"
32 #include "codechal_memdecomp.h"
33 #include "media_ddi_decode_const.h"
34 #include "media_ddi_decode_const_g12.h"
35 #include "media_ddi_factory.h"
36 #include "media_libva_common.h"
37 #include "codec_def_decode_hevc.h"
38 
ParseSliceParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferHEVC * slcParam,uint32_t numSlices)39 VAStatus DdiDecodeHEVCG12::ParseSliceParams(
40     DDI_MEDIA_CONTEXT           *mediaCtx,
41     VASliceParameterBufferHEVC  *slcParam,
42     uint32_t                     numSlices)
43 {
44     VASliceParameterBufferHEVC *slc     = slcParam;
45     VASliceParameterBufferBase *slcBase = (VASliceParameterBufferBase *)slcParam;
46     bool isHevcRext = IsRextProfile();
47     bool isHevcScc  = IsSccProfile();
48 
49     PCODEC_HEVC_SLICE_PARAMS codecSlcParams = (PCODEC_HEVC_SLICE_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
50     codecSlcParams += m_ddiDecodeCtx->DecodeParams.m_numSlices;
51     PCODEC_HEVC_EXT_SLICE_PARAMS codecSclParamsRext = nullptr;
52     VASliceParameterBufferHEVCExtension *slcExtension = nullptr;
53     VASliceParameterBufferHEVCRext *slcRext = nullptr;
54 
55     if(isHevcRext)
56     {
57         codecSclParamsRext = (PCODEC_HEVC_EXT_SLICE_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_extSliceParams);
58         codecSclParamsRext += m_ddiDecodeCtx->DecodeParams.m_numSlices;
59         slcExtension = (VASliceParameterBufferHEVCExtension *)slcParam;
60         slc     = &slcExtension->base;
61         slcRext = &slcExtension->rext;
62     }
63 
64     if ((slcParam == nullptr) || (codecSlcParams == nullptr) || (isHevcRext && (codecSclParamsRext == nullptr || slcRext == nullptr)))
65     {
66         DDI_ASSERTMESSAGE("Invalid Parameter for Parsing HEVC Slice parameter\n");
67         return VA_STATUS_ERROR_INVALID_PARAMETER;
68     }
69 
70     memset(codecSlcParams, 0, numSlices * sizeof(CODEC_HEVC_SLICE_PARAMS));
71     if(isHevcRext)
72     {
73         memset(codecSclParamsRext, 0, numSlices * sizeof(CODEC_HEVC_EXT_SLICE_PARAMS));
74     }
75 
76     uint32_t sliceBaseOffset = GetBsBufOffset(m_groupIndex);
77     uint32_t i, j, slcCount;
78     for (slcCount = 0; slcCount < numSlices; slcCount++)
79     {
80         if (m_ddiDecodeCtx->bShortFormatInUse)
81         {
82             codecSlcParams->slice_data_size   = slcBase->slice_data_size;
83             codecSlcParams->slice_data_offset = sliceBaseOffset + slcBase->slice_data_offset;
84             if (slcBase->slice_data_flag)
85             {
86                 DDI_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
87             }
88             slcBase++;
89         }
90         else
91         {
92             if (m_decodeErrorFlag)
93             {
94                 /* If error occurs in current GOP (m_decodeErrorFlag is true), set slice_temporal_mvp_enabled_flag = 0 to avoid GPU hang */
95                 codecSlcParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag = 0;
96             }
97             codecSlcParams->slice_data_size   = slc->slice_data_size;
98             codecSlcParams->slice_data_offset = sliceBaseOffset + slc->slice_data_offset;
99             if (slcBase->slice_data_flag)
100             {
101                 DDI_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
102             }
103 
104             codecSlcParams->ByteOffsetToSliceData = slc->slice_data_byte_offset;
105             codecSlcParams->NumEmuPrevnBytesInSliceHdr = slc->slice_data_num_emu_prevn_bytes;
106             codecSlcParams->slice_segment_address = slc->slice_segment_address;
107 
108             for (i = 0; i < 2; i++)
109             {
110                 for (j = 0; j < CODEC_MAX_NUM_REF_FRAME_HEVC; j++)
111                 {
112                     codecSlcParams->RefPicList[i][j].FrameIdx = (slc->RefPicList[i][j] == 0xff) ? 0x7f : slc->RefPicList[i][j];
113                 }
114             }
115 
116             codecSlcParams->LongSliceFlags.value           = slc->LongSliceFlags.value;
117             codecSlcParams->collocated_ref_idx             = slc->collocated_ref_idx;
118             codecSlcParams->num_ref_idx_l0_active_minus1   = slc->num_ref_idx_l0_active_minus1;
119             codecSlcParams->num_ref_idx_l1_active_minus1   = slc->num_ref_idx_l1_active_minus1;
120             codecSlcParams->slice_qp_delta                 = slc->slice_qp_delta;
121             codecSlcParams->slice_cb_qp_offset             = slc->slice_cb_qp_offset;
122             codecSlcParams->slice_cr_qp_offset             = slc->slice_cr_qp_offset;
123             codecSlcParams->slice_beta_offset_div2         = slc->slice_beta_offset_div2;
124             codecSlcParams->slice_tc_offset_div2           = slc->slice_tc_offset_div2;
125             codecSlcParams->luma_log2_weight_denom         = slc->luma_log2_weight_denom;
126             codecSlcParams->delta_chroma_log2_weight_denom = slc->delta_chroma_log2_weight_denom;
127 
128             MOS_SecureMemcpy(codecSlcParams->delta_luma_weight_l0,
129                 15,
130                 slc->delta_luma_weight_l0,
131                 15);
132             MOS_SecureMemcpy(codecSlcParams->delta_luma_weight_l1,
133                 15,
134                 slc->delta_luma_weight_l1,
135                 15);
136 
137             MOS_SecureMemcpy(codecSlcParams->delta_chroma_weight_l0,
138                 15 * 2,
139                 slc->delta_chroma_weight_l0,
140                 15 * 2);
141             MOS_SecureMemcpy(codecSlcParams->delta_chroma_weight_l1,
142                 15 * 2,
143                 slc->delta_chroma_weight_l1,
144                 15 * 2);
145             codecSlcParams->five_minus_max_num_merge_cand = slc->five_minus_max_num_merge_cand;
146             codecSlcParams->num_entry_point_offsets       = slc->num_entry_point_offsets;
147             codecSlcParams->EntryOffsetToSubsetArray      = slc->entry_offset_to_subset_array;
148 
149             if(!isHevcRext)
150             {
151                 MOS_SecureMemcpy(codecSlcParams->luma_offset_l0,
152                     15,
153                     slc->luma_offset_l0,
154                     15);
155                 MOS_SecureMemcpy(codecSlcParams->luma_offset_l1,
156                     15,
157                     slc->luma_offset_l1,
158                     15);
159                 MOS_SecureMemcpy(codecSlcParams->ChromaOffsetL0,
160                     15 * 2,
161                     slc->ChromaOffsetL0,
162                     15 * 2);
163                 MOS_SecureMemcpy(codecSlcParams->ChromaOffsetL1,
164                     15 * 2,
165                     slc->ChromaOffsetL1,
166                     15 * 2);
167 
168                 slc++;
169             }
170             else
171             {
172                 MOS_SecureMemcpy(codecSclParamsRext->luma_offset_l0,
173                     15 * sizeof(int16_t),
174                     slcRext->luma_offset_l0,
175                     15 * sizeof(int16_t));
176                 MOS_SecureMemcpy(codecSclParamsRext->luma_offset_l1,
177                     15 * sizeof(int16_t),
178                     slcRext->luma_offset_l1,
179                     15 * sizeof(int16_t));
180                 MOS_SecureMemcpy(codecSclParamsRext->ChromaOffsetL0,
181                     15 * 2 * sizeof(int16_t),
182                     slcRext->ChromaOffsetL0,
183                     15 * 2 * sizeof(int16_t));
184                 MOS_SecureMemcpy(codecSclParamsRext->ChromaOffsetL1,
185                     15 * 2 * sizeof(int16_t),
186                     slcRext->ChromaOffsetL1,
187                     15 * 2 * sizeof(int16_t));
188 
189                 codecSclParamsRext->cu_chroma_qp_offset_enabled_flag = slcRext->slice_ext_flags.bits.cu_chroma_qp_offset_enabled_flag;
190 
191                 if(isHevcScc)
192                 {
193                     codecSclParamsRext->use_integer_mv_flag    = slcRext->slice_ext_flags.bits.use_integer_mv_flag;
194                     codecSclParamsRext->slice_act_y_qp_offset  = slcRext->slice_act_y_qp_offset;
195                     codecSclParamsRext->slice_act_cb_qp_offset = slcRext->slice_act_cb_qp_offset;
196                     codecSclParamsRext->slice_act_cr_qp_offset = slcRext->slice_act_cr_qp_offset;
197                 }
198 
199                 codecSclParamsRext++;
200                 slcExtension++;
201                 slc     = &slcExtension->base;
202                 slcRext = &slcExtension->rext;
203             }
204         }
205         codecSlcParams++;
206     }
207 
208     return VA_STATUS_SUCCESS;
209 }
210 
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VAPictureParameterBufferHEVC * picParam)211 VAStatus DdiDecodeHEVCG12::ParsePicParams(
212     DDI_MEDIA_CONTEXT            *mediaCtx,
213     VAPictureParameterBufferHEVC *picParam)
214 {
215     PCODEC_HEVC_PIC_PARAMS                codecPicParams    = (PCODEC_HEVC_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_picParams);
216     PCODEC_HEVC_EXT_PIC_PARAMS            codecPicParamsExt = nullptr;
217     PCODEC_HEVC_SCC_PIC_PARAMS            codecPicParamsScc = nullptr;
218 
219     VAPictureParameterBufferHEVC          *picParamBase     = nullptr;
220     VAPictureParameterBufferHEVCRext      *picParamRext     = nullptr;
221     VAPictureParameterBufferHEVCScc       *picParamScc      = nullptr;
222     bool bIsHevcRext                                        = IsRextProfile();
223     bool bIsHevcScc                                         = IsSccProfile();
224 
225     if(!bIsHevcRext)
226     {
227         picParamBase = picParam;
228     }
229     else
230     {
231         codecPicParamsExt = (PCODEC_HEVC_EXT_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_extPicParams);
232         picParamBase     = &((VAPictureParameterBufferHEVCExtension *)picParam)->base;
233         picParamRext      = &((VAPictureParameterBufferHEVCExtension *)picParam)->rext;
234 
235         if(bIsHevcScc)
236         {
237             codecPicParamsScc = (PCODEC_HEVC_SCC_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_advPicParams);;
238             picParamScc = &((VAPictureParameterBufferHEVCExtension *)picParam)->scc;
239         }
240     }
241 
242     if ((picParamBase == nullptr) || (codecPicParams == nullptr) ||
243         (bIsHevcRext && (picParamRext == nullptr || codecPicParamsExt == nullptr)) ||
244         (bIsHevcScc && (picParamScc == nullptr || codecPicParamsScc == nullptr)))
245     {
246         DDI_ASSERTMESSAGE("Invalid Parameter for Parsing HEVC Picture parameter\n");
247         return VA_STATUS_ERROR_INVALID_PARAMETER;
248     }
249 
250     SetupCodecPicture(
251         mediaCtx,
252         &m_ddiDecodeCtx->RTtbl,
253         &codecPicParams->CurrPic,
254         picParamBase->CurrPic,
255         0,  //picParam->pic_fields.bits.FieldPicFlag,
256         0,  //picParam->pic_fields.bits.FieldPicFlag,
257         false);
258     if (codecPicParams->CurrPic.FrameIdx == (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX)
259     {
260         return VA_STATUS_ERROR_INVALID_PARAMETER;
261     }
262 
263     uint32_t i, j, k, l;
264     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
265     {
266         if (picParamBase->ReferenceFrames[i].picture_id != VA_INVALID_SURFACE)
267         {
268             UpdateRegisteredRTSurfaceFlag(&(m_ddiDecodeCtx->RTtbl),
269                 DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParamBase->ReferenceFrames[i].picture_id));
270         }
271         SetupCodecPicture(
272             mediaCtx,
273             &m_ddiDecodeCtx->RTtbl,
274             &(codecPicParams->RefFrameList[i]),
275             picParamBase->ReferenceFrames[i],
276             0,  //picParam->pic_fields.bits.FieldPicFlag,
277             0,  //picParam->pic_fields.bits.FieldPicFlag,
278             true);
279         if (codecPicParams->RefFrameList[i].FrameIdx == (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX)
280         {
281             //in case the ref frame sent from App is wrong, set it to invalid ref frame index in codechal.
282             codecPicParams->RefFrameList[i].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC;
283         }
284     }
285 
286     codecPicParams->PicWidthInMinCbsY  = picParamBase->pic_width_in_luma_samples / (1 << (picParamBase->log2_min_luma_coding_block_size_minus3 + 3));
287     codecPicParams->PicHeightInMinCbsY = picParamBase->pic_height_in_luma_samples / (1 << (picParamBase->log2_min_luma_coding_block_size_minus3 + 3));
288 
289     codecPicParams->chroma_format_idc                 = picParamBase->pic_fields.bits.chroma_format_idc;
290     codecPicParams->separate_colour_plane_flag        = picParamBase->pic_fields.bits.separate_colour_plane_flag;
291     codecPicParams->bit_depth_luma_minus8             = picParamBase->bit_depth_luma_minus8;
292     codecPicParams->bit_depth_chroma_minus8           = picParamBase->bit_depth_chroma_minus8;
293     codecPicParams->log2_max_pic_order_cnt_lsb_minus4 = picParamBase->log2_max_pic_order_cnt_lsb_minus4;
294     codecPicParams->NoPicReorderingFlag               = picParamBase->pic_fields.bits.NoPicReorderingFlag;
295     codecPicParams->NoBiPredFlag                      = picParamBase->pic_fields.bits.NoBiPredFlag;
296 
297     codecPicParams->sps_max_dec_pic_buffering_minus1         = picParamBase->sps_max_dec_pic_buffering_minus1;
298     codecPicParams->log2_min_luma_coding_block_size_minus3   = picParamBase->log2_min_luma_coding_block_size_minus3;
299     codecPicParams->log2_diff_max_min_luma_coding_block_size = picParamBase->log2_diff_max_min_luma_coding_block_size;
300     codecPicParams->log2_min_transform_block_size_minus2     = picParamBase->log2_min_transform_block_size_minus2;
301     codecPicParams->log2_diff_max_min_transform_block_size   = picParamBase->log2_diff_max_min_transform_block_size;
302     codecPicParams->max_transform_hierarchy_depth_inter      = picParamBase->max_transform_hierarchy_depth_inter;
303     codecPicParams->max_transform_hierarchy_depth_intra      = picParamBase->max_transform_hierarchy_depth_intra;
304     codecPicParams->num_short_term_ref_pic_sets              = picParamBase->num_short_term_ref_pic_sets;
305     codecPicParams->num_long_term_ref_pic_sps                = picParamBase->num_long_term_ref_pic_sps;
306     codecPicParams->num_ref_idx_l0_default_active_minus1     = picParamBase->num_ref_idx_l0_default_active_minus1;
307     codecPicParams->num_ref_idx_l1_default_active_minus1     = picParamBase->num_ref_idx_l1_default_active_minus1;
308     codecPicParams->init_qp_minus26                          = picParamBase->init_qp_minus26;
309     codecPicParams->ucNumDeltaPocsOfRefRpsIdx                = 0;  //redundant parameter, decoder may ignore
310     codecPicParams->wNumBitsForShortTermRPSInSlice           = picParamBase->st_rps_bits;
311 
312     //dwCodingParamToolFlags
313     codecPicParams->scaling_list_enabled_flag                    = picParamBase->pic_fields.bits.scaling_list_enabled_flag;
314     codecPicParams->amp_enabled_flag                             = picParamBase->pic_fields.bits.amp_enabled_flag;
315     codecPicParams->sample_adaptive_offset_enabled_flag          = picParamBase->slice_parsing_fields.bits.sample_adaptive_offset_enabled_flag;
316     codecPicParams->pcm_enabled_flag                             = picParamBase->pic_fields.bits.pcm_enabled_flag;
317     codecPicParams->pcm_sample_bit_depth_luma_minus1             = picParamBase->pcm_sample_bit_depth_luma_minus1;
318     codecPicParams->pcm_sample_bit_depth_chroma_minus1           = picParamBase->pcm_sample_bit_depth_chroma_minus1;
319     codecPicParams->log2_min_pcm_luma_coding_block_size_minus3   = picParamBase->log2_min_pcm_luma_coding_block_size_minus3;
320     codecPicParams->log2_diff_max_min_pcm_luma_coding_block_size = picParamBase->log2_diff_max_min_pcm_luma_coding_block_size;
321     codecPicParams->pcm_loop_filter_disabled_flag                = picParamBase->pic_fields.bits.pcm_loop_filter_disabled_flag;
322     codecPicParams->long_term_ref_pics_present_flag              = picParamBase->slice_parsing_fields.bits.long_term_ref_pics_present_flag;
323     codecPicParams->sps_temporal_mvp_enabled_flag                = picParamBase->slice_parsing_fields.bits.sps_temporal_mvp_enabled_flag;
324     codecPicParams->strong_intra_smoothing_enabled_flag          = picParamBase->pic_fields.bits.strong_intra_smoothing_enabled_flag;
325     codecPicParams->dependent_slice_segments_enabled_flag        = picParamBase->slice_parsing_fields.bits.dependent_slice_segments_enabled_flag;
326     codecPicParams->output_flag_present_flag                     = picParamBase->slice_parsing_fields.bits.output_flag_present_flag;
327     codecPicParams->num_extra_slice_header_bits                  = picParamBase->num_extra_slice_header_bits;
328     codecPicParams->sign_data_hiding_enabled_flag                = picParamBase->pic_fields.bits.sign_data_hiding_enabled_flag;
329     codecPicParams->cabac_init_present_flag                      = picParamBase->slice_parsing_fields.bits.cabac_init_present_flag;
330 
331     codecPicParams->constrained_intra_pred_flag              = picParamBase->pic_fields.bits.constrained_intra_pred_flag;
332     codecPicParams->transform_skip_enabled_flag              = picParamBase->pic_fields.bits.transform_skip_enabled_flag;
333     codecPicParams->cu_qp_delta_enabled_flag                 = picParamBase->pic_fields.bits.cu_qp_delta_enabled_flag;
334     codecPicParams->pps_slice_chroma_qp_offsets_present_flag = picParamBase->slice_parsing_fields.bits.pps_slice_chroma_qp_offsets_present_flag;
335     codecPicParams->weighted_pred_flag                       = picParamBase->pic_fields.bits.weighted_pred_flag;
336     codecPicParams->weighted_bipred_flag                     = picParamBase->pic_fields.bits.weighted_bipred_flag;
337     codecPicParams->transquant_bypass_enabled_flag           = picParamBase->pic_fields.bits.transquant_bypass_enabled_flag;
338     codecPicParams->tiles_enabled_flag                       = picParamBase->pic_fields.bits.tiles_enabled_flag;
339     codecPicParams->entropy_coding_sync_enabled_flag         = picParamBase->pic_fields.bits.entropy_coding_sync_enabled_flag;
340     /*For va, uniform_spacing_flag==1, application should populate
341          column_width_minus[], and row_height_minus1[] with approperiate values. */
342     codecPicParams->uniform_spacing_flag                        = 0;
343     codecPicParams->loop_filter_across_tiles_enabled_flag       = picParamBase->pic_fields.bits.loop_filter_across_tiles_enabled_flag;
344     codecPicParams->pps_loop_filter_across_slices_enabled_flag  = picParamBase->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag;
345     codecPicParams->deblocking_filter_override_enabled_flag     = picParamBase->slice_parsing_fields.bits.deblocking_filter_override_enabled_flag;
346     codecPicParams->pps_deblocking_filter_disabled_flag         = picParamBase->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag;
347     codecPicParams->lists_modification_present_flag             = picParamBase->slice_parsing_fields.bits.lists_modification_present_flag;
348     codecPicParams->slice_segment_header_extension_present_flag = picParamBase->slice_parsing_fields.bits.slice_segment_header_extension_present_flag;
349     codecPicParams->IrapPicFlag                                 = picParamBase->slice_parsing_fields.bits.RapPicFlag;
350     codecPicParams->IdrPicFlag                                  = picParamBase->slice_parsing_fields.bits.IdrPicFlag;
351     codecPicParams->IntraPicFlag                                = picParamBase->slice_parsing_fields.bits.IntraPicFlag;
352 
353     codecPicParams->pps_cb_qp_offset        = picParamBase->pps_cb_qp_offset;
354     codecPicParams->pps_cr_qp_offset        = picParamBase->pps_cr_qp_offset;
355     codecPicParams->num_tile_columns_minus1 = picParamBase->num_tile_columns_minus1;
356     codecPicParams->num_tile_rows_minus1    = picParamBase->num_tile_rows_minus1;
357 
358     if (codecPicParams->IdrPicFlag)
359     {
360         /* Initiate m_decodeErrorFlag to false when it's an IDR picture */
361         m_decodeErrorFlag = false;
362     }
363 
364     for (i = 0; i < HEVC_NUM_MAX_TILE_COLUMN - 1; i++)
365     {
366         codecPicParams->column_width_minus1[i] = picParamBase->column_width_minus1[i];
367     }
368     for (i = 0; i < HEVC_NUM_MAX_TILE_ROW - 1; i++)
369     {
370         codecPicParams->row_height_minus1[i] = picParamBase->row_height_minus1[i];
371     }
372 
373     codecPicParams->diff_cu_qp_delta_depth           = picParamBase->diff_cu_qp_delta_depth;
374     codecPicParams->pps_beta_offset_div2             = picParamBase->pps_beta_offset_div2;
375     codecPicParams->pps_tc_offset_div2               = picParamBase->pps_tc_offset_div2;
376     codecPicParams->log2_parallel_merge_level_minus2 = picParamBase->log2_parallel_merge_level_minus2;
377     codecPicParams->CurrPicOrderCntVal               = picParamBase->CurrPic.pic_order_cnt;
378 
379     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
380     {
381         codecPicParams->PicOrderCntValList[i] = picParamBase->ReferenceFrames[i].pic_order_cnt;
382     }
383 
384     for (i = 0; i < 8; i++)
385     {
386         codecPicParams->RefPicSetStCurrBefore[i] = 0xff;
387         codecPicParams->RefPicSetStCurrAfter[i]  = 0xff;
388         codecPicParams->RefPicSetLtCurr[i]       = 0xff;
389     }
390 
391     j = k = l = 0;
392 
393     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
394     {
395         if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE)
396         {
397             DDI_CHK_LESS(j, 8, "RefPicSetStCurrBefore[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
398             codecPicParams->RefPicSetStCurrBefore[j++] = i;
399         }
400         else if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_AFTER)
401         {
402             DDI_CHK_LESS(k, 8, "RefPicSetStCurrAfter[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
403             codecPicParams->RefPicSetStCurrAfter[k++] = i;
404         }
405         else if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_LT_CURR)
406         {
407             DDI_CHK_LESS(l, 8, "RefPicSetLtCurr[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
408             codecPicParams->RefPicSetLtCurr[l++] = i;
409         }
410     }
411 
412     codecPicParams->RefFieldPicFlag            = 0;
413     codecPicParams->RefBottomFieldFlag         = 0;
414     codecPicParams->StatusReportFeedbackNumber = 0;
415 
416     if (bIsHevcRext)
417     {
418         codecPicParamsExt->PicRangeExtensionFlags.dwRangeExtensionPropertyFlags    = picParamRext->range_extension_pic_fields.value;
419         codecPicParamsExt->diff_cu_chroma_qp_offset_depth                          = picParamRext->diff_cu_chroma_qp_offset_depth;
420         codecPicParamsExt->chroma_qp_offset_list_len_minus1                        = picParamRext->chroma_qp_offset_list_len_minus1;
421         codecPicParamsExt->log2_sao_offset_scale_luma                              = picParamRext->log2_sao_offset_scale_luma;
422         codecPicParamsExt->log2_sao_offset_scale_chroma                            = picParamRext->log2_sao_offset_scale_chroma;
423         codecPicParamsExt->log2_max_transform_skip_block_size_minus2               = picParamRext->log2_max_transform_skip_block_size_minus2;
424 
425         for (i = 0; i < 6; i++)
426         {
427             codecPicParamsExt->cb_qp_offset_list[i] = picParamRext->cb_qp_offset_list[i];
428             codecPicParamsExt->cr_qp_offset_list[i] = picParamRext->cr_qp_offset_list[i];
429         }
430     }
431 
432     if(bIsHevcScc)
433     {
434         codecPicParamsScc->PicSCCExtensionFlags.dwScreenContentCodingPropertyFlags = picParamScc->screen_content_pic_fields.value;
435         codecPicParamsScc->palette_max_size                                        = picParamScc->palette_max_size;
436         codecPicParamsScc->delta_palette_max_predictor_size                        = picParamScc->delta_palette_max_predictor_size;
437         codecPicParamsScc->PredictorPaletteSize                                    = picParamScc->predictor_palette_size;
438         codecPicParamsScc->pps_act_y_qp_offset_plus5                               = picParamScc->pps_act_y_qp_offset_plus5;
439         codecPicParamsScc->pps_act_cb_qp_offset_plus5                              = picParamScc->pps_act_cb_qp_offset_plus5;
440         codecPicParamsScc->pps_act_cr_qp_offset_plus3                              = picParamScc->pps_act_cr_qp_offset_plus3;
441         uint32_t uiCopySize = sizeof(codecPicParamsScc->PredictorPaletteEntries);
442         MOS_SecureMemcpy(&codecPicParamsScc->PredictorPaletteEntries, uiCopySize, &picParamScc->predictor_palette_entries, uiCopySize);
443     }
444 
445 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
446     // Picture Info
447     DECODE_EVENTDATA_INFO_PICTUREVA eventData = {0};
448     uint32_t minCtbSize        = 1 << (codecPicParams->log2_min_luma_coding_block_size_minus3 + 3);
449     eventData.CodecFormat                   = m_ddiDecodeCtx->wMode;
450     eventData.FrameType                     = codecPicParams->IntraPicFlag == 1 ? I_TYPE : MIXED_TYPE;
451     eventData.PicStruct                     = FRAME_PICTURE;
452     eventData.Width                         = codecPicParams->PicWidthInMinCbsY * minCtbSize;
453     eventData.Height                        = codecPicParams->PicHeightInMinCbsY * minCtbSize;
454     eventData.Bitdepth                      = codecPicParams->bit_depth_luma_minus8 + 8;
455     eventData.ChromaFormat                  = codecPicParams->chroma_format_idc;  // 0-4:0:0; 1-4:2:0; 2-4:2:2; 3-4:4:4
456     MOS_TraceEvent(EVENT_DECODE_INFO_PICTUREVA, EVENT_TYPE_INFO, &eventData, sizeof(eventData), NULL, 0);
457 #endif
458 
459     return VA_STATUS_SUCCESS;
460 }
461 
GetFormat()462 MOS_FORMAT DdiDecodeHEVCG12::GetFormat()
463 {
464     MOS_FORMAT Format = Format_NV12;
465     DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_ddiDecodeCtx->RTtbl);
466     CodechalDecodeParams *decodeParams = &m_ddiDecodeCtx->DecodeParams;
467     CODEC_HEVC_PIC_PARAMS *picParams = (CODEC_HEVC_PIC_PARAMS *)decodeParams->m_picParams;
468     if ((m_ddiDecodeAttr->profile == VAProfileHEVCMain10) &&
469         ((picParams->bit_depth_luma_minus8 ||
470         picParams->bit_depth_chroma_minus8)))
471     {
472         Format = Format_P010;
473         if (picParams->chroma_format_idc == 2)
474         {
475             Format = Format_Y210;
476         }
477         else if (picParams->chroma_format_idc == 3)
478         {
479             Format = Format_Y410;
480         }
481     }
482     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain10
483         && picParams->bit_depth_luma_minus8 == 0
484         && picParams->bit_depth_chroma_minus8 == 0
485         && rtTbl->pCurrentRT->format == Media_Format_P010)
486     {
487         // for hevc deocde 8bit in 10bit, the app will pass the render
488         // target surface with the P010.
489         Format = Format_P010;
490     }
491     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain12)
492     {
493         Format = Format_P016;
494     }
495     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10
496         || m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12
497         || m_ddiDecodeAttr->profile == VAProfileHEVCMain444
498         || m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10
499         || m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12)
500     {
501         Format = Format_NV12;
502         if(picParams->bit_depth_luma_minus8 == 0
503             && picParams->bit_depth_chroma_minus8 == 0)               //8bit
504         {
505             if (picParams->chroma_format_idc == 1)                   //420
506             {
507                 Format = Format_NV12;
508                 if(rtTbl->pCurrentRT->format == Media_Format_P010)
509                 {
510                     Format = Format_P010;
511                 }
512                 else if(rtTbl->pCurrentRT->format == Media_Format_P016 || rtTbl->pCurrentRT->format == Media_Format_P012)
513                 {
514                     Format = Format_P016;
515                 }
516             }
517             else if (picParams->chroma_format_idc == 2)              //422
518             {
519                 Format = Format_YUY2;
520                 if(rtTbl->pCurrentRT->format == Media_Format_Y210)
521                 {
522                     Format = Format_Y210;
523                 }
524 #if VA_CHECK_VERSION(1, 9, 0)
525                 else if(rtTbl->pCurrentRT->format == Media_Format_Y216 || rtTbl->pCurrentRT->format == Media_Format_Y212)
526 #else
527                 else if(rtTbl->pCurrentRT->format == Media_Format_Y216)
528 #endif
529                 {
530                     Format = Format_Y216;
531                 }
532             }
533             else                                                    //444
534             {
535                 Format = Format_AYUV;
536                  if(rtTbl->pCurrentRT->format == Media_Format_Y410)
537                 {
538                     Format = Format_Y410;
539                 }
540 #if VA_CHECK_VERSION(1, 9, 0)
541                 else if(rtTbl->pCurrentRT->format == Media_Format_Y416 || rtTbl->pCurrentRT->format == Media_Format_Y412)
542 #else
543                 else if(rtTbl->pCurrentRT->format == Media_Format_Y416)
544 #endif
545                 {
546                     Format = Format_Y416;
547                 }
548             }
549         }
550         else if(picParams->bit_depth_luma_minus8 == 1
551             || picParams->bit_depth_chroma_minus8 == 1
552             || picParams->bit_depth_luma_minus8 == 2
553             || picParams->bit_depth_chroma_minus8 == 2)            //10bit
554         {
555             if (picParams->chroma_format_idc == 1)                 //420
556             {
557                 Format = Format_P010;
558                 if(rtTbl->pCurrentRT->format == Media_Format_P016 || rtTbl->pCurrentRT->format == Media_Format_P012)
559                 {
560                     Format = Format_P016;
561                 }
562             }
563             else if (picParams->chroma_format_idc == 2)           //422
564             {
565                 Format = Format_Y210;
566 #if VA_CHECK_VERSION(1, 9, 0)
567                 if(rtTbl->pCurrentRT->format == Media_Format_Y216 || rtTbl->pCurrentRT->format == Media_Format_Y212)
568 #else
569                 if(rtTbl->pCurrentRT->format == Media_Format_Y216)
570 #endif
571                 {
572                     Format = Format_Y216;
573                 }
574             }
575             else                                                  //444
576             {
577                 Format = Format_Y410;
578 #if VA_CHECK_VERSION(1, 9, 0)
579                 if(rtTbl->pCurrentRT->format == Media_Format_Y416 || rtTbl->pCurrentRT->format == Media_Format_Y412)
580 #else
581                 if(rtTbl->pCurrentRT->format == Media_Format_Y416)
582 #endif
583                 {
584                     Format = Format_Y416;
585                 }
586             }
587         }
588         else if(picParams->bit_depth_luma_minus8 >= 3
589             || picParams->bit_depth_chroma_minus8 >= 3)            //12bit
590         {
591             if (picParams->chroma_format_idc == 1)                 //420
592             {
593                 Format = Format_P016;
594             }
595             else if (picParams->chroma_format_idc == 2)           //422
596             {
597                 Format = Format_Y216;
598             }
599             else                                                  //444
600             {
601                 Format = Format_Y416;
602             }
603         }
604     }
605     else if(m_ddiDecodeAttr->profile == VAProfileHEVCSccMain10)
606     {
607         //420 10bit
608         Format = Format_P010;
609     }
610     else if (m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444 ||
611              m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444_10)
612     {
613         //420/422/444 8bit
614         if((picParams->bit_depth_luma_minus8 == 0) &&
615             (picParams->bit_depth_chroma_minus8 == 0))
616         {
617             if (picParams->chroma_format_idc == 2)
618             {
619                 Format = Format_YUY2;
620             }
621             else if (picParams->chroma_format_idc == 3)
622             {
623                 Format = Format_AYUV;
624             }
625             else
626             {
627                 Format = Format_NV12;
628             }
629         }
630         else
631         {
632             //10bit
633             if (picParams->chroma_format_idc == 2)
634             {
635                 Format = Format_Y210;
636             }
637             else if (picParams->chroma_format_idc == 3)
638             {
639                 Format = Format_Y410;
640             }
641             else
642             {
643                 Format = Format_P010;
644             }
645         }
646     }
647 
648     return Format;
649 }
650 
AllocSliceParamContext(uint32_t numSlices)651 VAStatus DdiDecodeHEVCG12::AllocSliceParamContext(
652     uint32_t numSlices)
653 {
654     uint32_t baseSize = sizeof(CODEC_HEVC_SLICE_PARAMS);
655 
656     if (m_sliceParamBufNum < (m_ddiDecodeCtx->DecodeParams.m_numSlices + numSlices))
657     {
658         // in order to avoid that the buffer is reallocated multi-times,
659         // extra 10 slices are added.
660         uint32_t extraSlices = numSlices + 10;
661 
662         m_ddiDecodeCtx->DecodeParams.m_sliceParams = realloc(m_ddiDecodeCtx->DecodeParams.m_sliceParams,
663             baseSize * (m_sliceParamBufNum + extraSlices));
664 
665         if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
666         {
667             return VA_STATUS_ERROR_ALLOCATION_FAILED;
668         }
669 
670         memset((void *)((uint8_t *)m_ddiDecodeCtx->DecodeParams.m_sliceParams + baseSize * m_sliceParamBufNum), 0, baseSize * extraSlices);
671 
672         if(IsRextProfile())
673         {
674             uint32_t rextSize = sizeof(CODEC_HEVC_EXT_SLICE_PARAMS);
675             m_ddiDecodeCtx->DecodeParams.m_extSliceParams = realloc(m_ddiDecodeCtx->DecodeParams.m_extSliceParams,
676             rextSize * (m_sliceParamBufNum + extraSlices));
677 
678             if (m_ddiDecodeCtx->DecodeParams.m_extSliceParams == nullptr)
679             {
680                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
681             }
682 
683             memset((void *)((uint8_t *)m_ddiDecodeCtx->DecodeParams.m_extSliceParams + rextSize * m_sliceParamBufNum), 0, rextSize * extraSlices);
684         }
685 
686         m_sliceParamBufNum += extraSlices;
687     }
688 
689     return VA_STATUS_SUCCESS;
690 }
691 
InitResourceBuffer()692 VAStatus DdiDecodeHEVCG12::InitResourceBuffer()
693 {
694     VAStatus vaStatus = VA_STATUS_SUCCESS;
695 
696     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
697     bufMgr->pSliceData               = nullptr;
698 
699     bufMgr->ui64BitstreamOrder = 0;
700 
701     if(m_width * m_height < CODEC_720P_MAX_PIC_WIDTH * CODEC_720P_MAX_PIC_HEIGHT)
702     {
703         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 2;
704     }
705     else if(m_width * m_height < CODEC_4K_MAX_PIC_WIDTH * CODEC_4K_MAX_PIC_HEIGHT)
706     {
707         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 8;
708     }
709     else
710     {
711         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 16;
712     }
713 
714     // minimal 10k bytes for some special case. Will refractor this later
715     if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
716     {
717         bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
718     }
719 
720     int32_t i;
721     // init decode bitstream buffer object
722     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
723     {
724         bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
725         if (bufMgr->pBitStreamBuffObject[i] == nullptr)
726         {
727             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
728             goto finish;
729         }
730         bufMgr->pBitStreamBuffObject[i]->iSize    = bufMgr->dwMaxBsSize;
731         bufMgr->pBitStreamBuffObject[i]->uiType   = VASliceDataBufferType;
732         bufMgr->pBitStreamBuffObject[i]->format   = Media_Format_Buffer;
733         bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
734         bufMgr->pBitStreamBuffObject[i]->bo       = nullptr;
735         bufMgr->pBitStreamBase[i]                 = nullptr;
736     }
737 
738     // The pSliceData can be allocated on demand. So the default size is wPicHeightInLCU.
739     // Currently the LCU32 is used.
740     bufMgr->m_maxNumSliceData = MOS_ALIGN_CEIL(m_height, 32) / 32;
741     bufMgr->pSliceData        = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) *
742                                                                                    bufMgr->m_maxNumSliceData);
743 
744     if (bufMgr->pSliceData == nullptr)
745     {
746         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
747         goto finish;
748     }
749 
750     bufMgr->dwNumSliceData    = 0;
751     bufMgr->dwNumSliceControl = 0;
752 
753     /* as it can be increased on demand, the initial number will be based on LCU32 */
754     m_sliceCtrlBufNum = MOS_ALIGN_CEIL(m_height, 32) / 32;
755 
756     if (m_ddiDecodeCtx->bShortFormatInUse)
757     {
758         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC = (VASliceParameterBufferBase *)
759             MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferBase) * m_sliceCtrlBufNum);
760         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC == nullptr)
761         {
762             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
763             goto finish;
764         }
765     }
766     else if(!IsRextProfile())
767     {
768         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC = (VASliceParameterBufferHEVC *)
769             MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferHEVC) * m_sliceCtrlBufNum);
770         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC == nullptr)
771         {
772             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
773             goto finish;
774         }
775     }
776     else
777     {
778         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext= (VASliceParameterBufferHEVCExtension*)
779             MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferHEVCExtension) * m_sliceCtrlBufNum);
780         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext== nullptr)
781         {
782             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
783             goto finish;
784         }
785     }
786 
787     return VA_STATUS_SUCCESS;
788 
789 finish:
790     FreeResourceBuffer();
791     return vaStatus;
792 }
793 
FreeResourceBuffer()794 void DdiDecodeHEVCG12::FreeResourceBuffer()
795 {
796     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
797 
798     int32_t i;
799     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
800     {
801         if (bufMgr->pBitStreamBase[i])
802         {
803             DdiMediaUtil_UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
804             bufMgr->pBitStreamBase[i] = nullptr;
805         }
806         if (bufMgr->pBitStreamBuffObject[i])
807         {
808             DdiMediaUtil_FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
809             MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
810             bufMgr->pBitStreamBuffObject[i] = nullptr;
811         }
812     }
813 
814     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC)
815     {
816         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC);
817         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC = nullptr;
818     }
819     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC)
820     {
821         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC);
822         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC = nullptr;
823     }
824     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext)
825     {
826         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext);
827         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext = nullptr;
828     }
829 
830     // free decode bitstream buffer object
831     MOS_FreeMemory(bufMgr->pSliceData);
832     bufMgr->pSliceData = nullptr;
833 
834     return;
835 }
836 
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)837 uint8_t* DdiDecodeHEVCG12::GetPicParamBuf(
838     DDI_CODEC_COM_BUFFER_MGR    *bufMgr)
839 {
840     if(!IsRextProfile())
841     {
842         return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_HEVC.PicParamHEVC));
843     }
844     else
845     {
846         return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_HEVC.PicParamHEVCRext));
847     }
848 }
849 
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)850 VAStatus DdiDecodeHEVCG12::AllocSliceControlBuffer(
851     DDI_MEDIA_BUFFER       *buf)
852 {
853     DDI_CODEC_COM_BUFFER_MGR   *bufMgr;
854     uint32_t                    availSize;
855     uint32_t                    newSize;
856 
857     bufMgr     = &(m_ddiDecodeCtx->BufMgr);
858     availSize = m_sliceCtrlBufNum - bufMgr->dwNumSliceControl;
859 
860     if(buf->uiNumElements < 1 || buf->iSize < 1)
861         return VA_STATUS_ERROR_ALLOCATION_FAILED;
862 
863     if(m_ddiDecodeCtx->bShortFormatInUse)
864     {
865         if(availSize < buf->uiNumElements)
866         {
867             if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferBase))
868                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
869 
870             newSize   = sizeof(VASliceParameterBufferBase) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
871             bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC = (VASliceParameterBufferBase *)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC, newSize);
872             if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC == nullptr)
873             {
874                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
875             }
876             MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferBase) * (buf->uiNumElements - availSize));
877             m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
878         }
879         buf->pData      = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC;
880         buf->uiOffset   = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferBase);
881     }
882     else
883     {
884         if(!IsRextProfile())
885         {
886             if(availSize < buf->uiNumElements)
887             {
888                 if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferHEVC))
889                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
890 
891                 newSize   = sizeof(VASliceParameterBufferHEVC) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
892                 bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC = (VASliceParameterBufferHEVC *)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC, newSize);
893                 if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC == nullptr)
894                 {
895                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
896                 }
897                 MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferHEVC) * (buf->uiNumElements - availSize));
898                 m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
899             }
900             buf->pData      = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC;
901             buf->uiOffset   = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferHEVC);
902         }
903         else
904         {
905             if(availSize < buf->uiNumElements)
906             {
907                 if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferHEVCExtension))
908                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
909 
910                 newSize   = sizeof(VASliceParameterBufferHEVCExtension) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
911                 bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext= (VASliceParameterBufferHEVCExtension*)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext, newSize);
912                 if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext== nullptr)
913                 {
914                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
915                 }
916                 MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext+ m_sliceCtrlBufNum, sizeof(VASliceParameterBufferHEVCExtension) * (buf->uiNumElements - availSize));
917                 m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
918             }
919             buf->pData      = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext;
920             buf->uiOffset   = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferHEVCExtension);
921         }
922     }
923 
924     bufMgr->dwNumSliceControl += buf->uiNumElements;
925 
926     return VA_STATUS_SUCCESS;
927 }
928 
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)929 VAStatus DdiDecodeHEVCG12::CodecHalInit(
930     DDI_MEDIA_CONTEXT *mediaCtx,
931     void              *ptr)
932 {
933     VAStatus     vaStatus = VA_STATUS_SUCCESS;
934     MOS_CONTEXT *mosCtx   = (MOS_CONTEXT *)ptr;
935 
936     CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
937     m_ddiDecodeCtx->pCpDdiInterface->SetCpParams(m_ddiDecodeAttr->uiEncryptionType, m_codechalSettings);
938 
939     CODECHAL_STANDARD_INFO standardInfo;
940     memset(&standardInfo, 0, sizeof(standardInfo));
941 
942     standardInfo.CodecFunction = codecFunction;
943     standardInfo.Mode          = (CODECHAL_MODE)m_ddiDecodeCtx->wMode;
944 
945     m_codechalSettings->codecFunction = codecFunction;
946     m_codechalSettings->width       = m_width;
947     m_codechalSettings->height      = m_height;
948     m_codechalSettings->intelEntrypointInUse = false;
949 
950     m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
951     if (m_ddiDecodeAttr->profile == VAProfileHEVCMain10 ||
952         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 ||
953         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10 ||
954         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain10 ||
955         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10)
956     {
957         m_codechalSettings->lumaChromaDepth |= CODECHAL_LUMA_CHROMA_DEPTH_10_BITS;
958     }
959 
960     m_codechalSettings->shortFormatInUse = m_ddiDecodeCtx->bShortFormatInUse;
961 
962     m_codechalSettings->mode           = CODECHAL_DECODE_MODE_HEVCVLD;
963     m_codechalSettings->standard       = CODECHAL_HEVC;
964     m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV420;
965 
966     if(m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 ||
967        m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12)
968     {
969         m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV422;
970     }
971 
972     if(m_ddiDecodeAttr->profile == VAProfileHEVCMain444 ||
973        m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10 ||
974        m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12 ||
975        m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444 ||
976        m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444_10)
977     {
978         m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV444;
979     }
980 
981     m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer = MOS_AllocAndZeroMemory(sizeof(CODECHAL_HEVC_IQ_MATRIX_PARAMS));
982     if (m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer == nullptr)
983     {
984         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
985         goto CleanUpandReturn;
986     }
987     m_ddiDecodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_PIC_PARAMS));
988     if (m_ddiDecodeCtx->DecodeParams.m_picParams == nullptr)
989     {
990         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
991         goto CleanUpandReturn;
992     }
993     if(IsRextProfile())
994     {
995         m_ddiDecodeCtx->DecodeParams.m_extPicParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_EXT_PIC_PARAMS));
996         if (m_ddiDecodeCtx->DecodeParams.m_extPicParams == nullptr)
997         {
998             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
999             goto CleanUpandReturn;
1000         }
1001 
1002         if(IsSccProfile())
1003         {
1004             m_ddiDecodeCtx->DecodeParams.m_advPicParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_SCC_PIC_PARAMS));
1005             if (m_ddiDecodeCtx->DecodeParams.m_advPicParams == nullptr)
1006             {
1007                 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1008                 goto CleanUpandReturn;
1009             }
1010         }
1011     }
1012 
1013     m_sliceParamBufNum         = m_picHeightInMB;
1014     m_ddiDecodeCtx->DecodeParams.m_sliceParams = MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_HEVC_SLICE_PARAMS));
1015     if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
1016     {
1017         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1018         goto CleanUpandReturn;
1019     }
1020 
1021     if(IsRextProfile())
1022     {
1023         m_ddiDecodeCtx->DecodeParams.m_extSliceParams = MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_HEVC_EXT_SLICE_PARAMS));
1024         if (m_ddiDecodeCtx->DecodeParams.m_extSliceParams == nullptr)
1025         {
1026             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1027             goto CleanUpandReturn;
1028         }
1029     }
1030 
1031 #ifdef _DECODE_PROCESSING_SUPPORTED
1032     if (m_decProcessingType == VA_DEC_PROCESSING)
1033     {
1034         DecodeProcessingParams *procParams = nullptr;
1035 
1036         m_codechalSettings->downsamplingHinted = true;
1037 
1038         procParams = (DecodeProcessingParams *)MOS_AllocAndZeroMemory(sizeof(DecodeProcessingParams));
1039         if (procParams == nullptr)
1040         {
1041             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1042             goto CleanUpandReturn;
1043         }
1044 
1045         m_ddiDecodeCtx->DecodeParams.m_procParams = procParams;
1046         procParams->m_outputSurface = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
1047         if (procParams->m_outputSurface == nullptr)
1048         {
1049             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1050             goto CleanUpandReturn;
1051         }
1052     }
1053 #endif
1054 
1055     vaStatus = CreateCodecHal(mediaCtx,
1056         ptr,
1057         &standardInfo);
1058 
1059     if (vaStatus != VA_STATUS_SUCCESS)
1060     {
1061         goto CleanUpandReturn;
1062     }
1063 
1064     if (InitResourceBuffer() != VA_STATUS_SUCCESS)
1065     {
1066         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1067         goto CleanUpandReturn;
1068     }
1069 
1070     return vaStatus;
1071 
1072 CleanUpandReturn:
1073     FreeResourceBuffer();
1074 
1075     if (m_ddiDecodeCtx->pCodecHal)
1076     {
1077         m_ddiDecodeCtx->pCodecHal->Destroy();
1078         MOS_Delete(m_ddiDecodeCtx->pCodecHal);
1079         m_ddiDecodeCtx->pCodecHal = nullptr;
1080     }
1081 
1082     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer);
1083     m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer = nullptr;
1084     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_picParams);
1085     m_ddiDecodeCtx->DecodeParams.m_picParams = nullptr;
1086     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_huffmanTable);
1087     m_ddiDecodeCtx->DecodeParams.m_huffmanTable = nullptr;
1088     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
1089     m_ddiDecodeCtx->DecodeParams.m_sliceParams = nullptr;
1090 
1091 #ifdef _DECODE_PROCESSING_SUPPORTED
1092     if (m_ddiDecodeCtx->DecodeParams.m_procParams)
1093     {
1094         auto procParams =
1095             (DecodeProcessingParams *)m_ddiDecodeCtx->DecodeParams.m_procParams;
1096         MOS_FreeMemory(procParams->m_outputSurface);
1097 
1098         MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_procParams);
1099         m_ddiDecodeCtx->DecodeParams.m_procParams = nullptr;
1100     }
1101 #endif
1102     return vaStatus;
1103 }
1104 
IsRextProfile()1105 bool DdiDecodeHEVCG12::IsRextProfile()
1106 {
1107     return (                                                   \
1108         m_ddiDecodeAttr->profile == VAProfileHEVCMain12     || \
1109         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 || \
1110         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12 || \
1111         m_ddiDecodeAttr->profile == VAProfileHEVCMain444    || \
1112         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10 || \
1113         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12 || \
1114         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain    || \
1115         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain10  || \
1116         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444 || \
1117         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444_10 \
1118         );
1119 }
1120 
IsSccProfile()1121 bool DdiDecodeHEVCG12::IsSccProfile()
1122 {
1123     return (                                                   \
1124         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain    || \
1125         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain10  || \
1126         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444 || \
1127         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444_10 \
1128         );
1129 }
1130 
1131 
1132 extern template class MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>;
1133 
1134 static bool hevcRegistered =
1135     MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>::RegisterCodec<DdiDecodeHEVCG12>(DECODE_ID_HEVC_REXT);
1136