1 /*
2 * Copyright (c) 2015-2020, 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_g11.cpp
24 //! \brief    The class implementation of DdiDecodeHEVCG11  for HEVC decode
25 //!
26 
27 #include "media_libva_decoder.h"
28 #include "media_libva_util.h"
29 
30 #include "media_ddi_decode_hevc_g11.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_g11.h"
35 #include "media_ddi_factory.h"
36 #include "media_libva_common.h"
37 
38 
ParseSliceParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferHEVC * slcParam,uint32_t numSlices)39 VAStatus DdiDecodeHEVCG11::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 
48     PCODEC_HEVC_SLICE_PARAMS codecSlcParams = (PCODEC_HEVC_SLICE_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
49     codecSlcParams += m_ddiDecodeCtx->DecodeParams.m_numSlices;
50     PCODEC_HEVC_EXT_SLICE_PARAMS codecSclParamsRext = nullptr;
51     VASliceParameterBufferHEVCExtension *slcExtension = nullptr;
52     VASliceParameterBufferHEVCRext *slcRext = nullptr;
53 
54     if(isHevcRext)
55     {
56         codecSclParamsRext = (PCODEC_HEVC_EXT_SLICE_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_extSliceParams);
57         codecSclParamsRext += m_ddiDecodeCtx->DecodeParams.m_numSlices;
58         slcExtension = (VASliceParameterBufferHEVCExtension *)slcParam;
59         slc     = &slcExtension->base;
60         slcRext = &slcExtension->rext;
61     }
62 
63     if ((slcParam == nullptr) || (codecSlcParams == nullptr) || (isHevcRext && (codecSclParamsRext == nullptr || slcRext == nullptr)))
64     {
65         DDI_ASSERTMESSAGE("Invalid Parameter for Parsing HEVC Slice parameter\n");
66         return VA_STATUS_ERROR_INVALID_PARAMETER;
67     }
68 
69     memset(codecSlcParams, 0, numSlices * sizeof(CODEC_HEVC_SLICE_PARAMS));
70     if(isHevcRext)
71     {
72         memset(codecSclParamsRext, 0, numSlices * sizeof(CODEC_HEVC_EXT_SLICE_PARAMS));
73     }
74 
75     uint32_t sliceBaseOffset = GetBsBufOffset(m_groupIndex);
76     uint32_t i, j, slcCount;
77     for (slcCount = 0; slcCount < numSlices; slcCount++)
78     {
79         if (m_ddiDecodeCtx->bShortFormatInUse)
80         {
81             codecSlcParams->slice_data_size   = slcBase->slice_data_size;
82             codecSlcParams->slice_data_offset = sliceBaseOffset + slcBase->slice_data_offset;
83             if (slcBase->slice_data_flag)
84             {
85                 DDI_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
86             }
87             slcBase++;
88         }
89         else
90         {
91             codecSlcParams->slice_data_size   = slc->slice_data_size;
92             codecSlcParams->slice_data_offset = sliceBaseOffset + slc->slice_data_offset;
93             if (slcBase->slice_data_flag)
94             {
95                 DDI_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
96             }
97 
98             codecSlcParams->ByteOffsetToSliceData = slc->slice_data_byte_offset;
99             codecSlcParams->slice_segment_address = slc->slice_segment_address;
100 
101             for (i = 0; i < 2; i++)
102             {
103                 for (j = 0; j < CODEC_MAX_NUM_REF_FRAME_HEVC; j++)
104                 {
105                     codecSlcParams->RefPicList[i][j].FrameIdx = (slc->RefPicList[i][j] == 0xff) ? 0x7f : slc->RefPicList[i][j];
106                 }
107             }
108 
109             codecSlcParams->LongSliceFlags.value           = slc->LongSliceFlags.value;
110             codecSlcParams->collocated_ref_idx             = slc->collocated_ref_idx;
111             codecSlcParams->num_ref_idx_l0_active_minus1   = slc->num_ref_idx_l0_active_minus1;
112             codecSlcParams->num_ref_idx_l1_active_minus1   = slc->num_ref_idx_l1_active_minus1;
113             codecSlcParams->slice_qp_delta                 = slc->slice_qp_delta;
114             codecSlcParams->slice_cb_qp_offset             = slc->slice_cb_qp_offset;
115             codecSlcParams->slice_cr_qp_offset             = slc->slice_cr_qp_offset;
116             codecSlcParams->slice_beta_offset_div2         = slc->slice_beta_offset_div2;
117             codecSlcParams->slice_tc_offset_div2           = slc->slice_tc_offset_div2;
118             codecSlcParams->luma_log2_weight_denom         = slc->luma_log2_weight_denom;
119             codecSlcParams->delta_chroma_log2_weight_denom = slc->delta_chroma_log2_weight_denom;
120 
121             MOS_SecureMemcpy(codecSlcParams->delta_luma_weight_l0,
122                 15,
123                 slc->delta_luma_weight_l0,
124                 15);
125             MOS_SecureMemcpy(codecSlcParams->delta_luma_weight_l1,
126                 15,
127                 slc->delta_luma_weight_l1,
128                 15);
129 
130             MOS_SecureMemcpy(codecSlcParams->delta_chroma_weight_l0,
131                 15 * 2,
132                 slc->delta_chroma_weight_l0,
133                 15 * 2);
134             MOS_SecureMemcpy(codecSlcParams->delta_chroma_weight_l1,
135                 15 * 2,
136                 slc->delta_chroma_weight_l1,
137                 15 * 2);
138             codecSlcParams->five_minus_max_num_merge_cand = slc->five_minus_max_num_merge_cand;
139 
140             if(!isHevcRext)
141             {
142                 MOS_SecureMemcpy(codecSlcParams->luma_offset_l0,
143                     15,
144                     slc->luma_offset_l0,
145                     15);
146                 MOS_SecureMemcpy(codecSlcParams->luma_offset_l1,
147                     15,
148                     slc->luma_offset_l1,
149                     15);
150                 MOS_SecureMemcpy(codecSlcParams->ChromaOffsetL0,
151                     15 * 2,
152                     slc->ChromaOffsetL0,
153                     15 * 2);
154                 MOS_SecureMemcpy(codecSlcParams->ChromaOffsetL1,
155                     15 * 2,
156                     slc->ChromaOffsetL1,
157                     15 * 2);
158 
159                 slc++;
160             }
161             else
162             {
163                 MOS_SecureMemcpy(codecSclParamsRext->luma_offset_l0,
164                     15 * sizeof(int16_t),
165                     slcRext->luma_offset_l0,
166                     15 * sizeof(int16_t));
167                 MOS_SecureMemcpy(codecSclParamsRext->luma_offset_l1,
168                     15 * sizeof(int16_t),
169                     slcRext->luma_offset_l1,
170                     15 * sizeof(int16_t));
171                 MOS_SecureMemcpy(codecSclParamsRext->ChromaOffsetL0,
172                     15 * 2 * sizeof(int16_t),
173                     slcRext->ChromaOffsetL0,
174                     15 * 2 * sizeof(int16_t));
175                 MOS_SecureMemcpy(codecSclParamsRext->ChromaOffsetL1,
176                     15 * 2 * sizeof(int16_t),
177                     slcRext->ChromaOffsetL1,
178                     15 * 2 * sizeof(int16_t));
179 
180                 codecSclParamsRext->cu_chroma_qp_offset_enabled_flag = slcRext->slice_ext_flags.bits.cu_chroma_qp_offset_enabled_flag;
181                 codecSclParamsRext++;
182                 slcExtension++;
183                 slc     = &slcExtension->base;
184                 slcRext = &slcExtension->rext;
185             }
186         }
187         codecSlcParams++;
188     }
189     return VA_STATUS_SUCCESS;
190 }
191 
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VAPictureParameterBufferHEVC * picParam)192 VAStatus DdiDecodeHEVCG11::ParsePicParams(
193     DDI_MEDIA_CONTEXT            *mediaCtx,
194     VAPictureParameterBufferHEVC *picParam)
195 {
196     PCODEC_HEVC_PIC_PARAMS                codecPicParams    = (PCODEC_HEVC_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_picParams);
197     PCODEC_HEVC_EXT_PIC_PARAMS            codecPicParamsExt = nullptr;
198 
199     VAPictureParameterBufferHEVC          *picParamBase     = nullptr;
200     VAPictureParameterBufferHEVCRext      *picParamRext     = nullptr;
201     bool bIsHevcRext                                        = IsRextProfile();
202 
203     if(!bIsHevcRext)
204     {
205         picParamBase = picParam;
206     }
207     else
208     {
209         codecPicParamsExt = (PCODEC_HEVC_EXT_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_extPicParams);
210         picParamBase     = &((VAPictureParameterBufferHEVCExtension *)picParam)->base;
211         picParamRext      = &((VAPictureParameterBufferHEVCExtension *)picParam)->rext;
212     }
213 
214     if ((picParamBase == nullptr) || (codecPicParams == nullptr) ||
215         (bIsHevcRext && (picParamRext == nullptr || codecPicParamsExt == nullptr)))
216     {
217         DDI_ASSERTMESSAGE("Invalid Parameter for Parsing HEVC Picture parameter\n");
218         return VA_STATUS_ERROR_INVALID_PARAMETER;
219     }
220 
221     SetupCodecPicture(
222         mediaCtx,
223         &m_ddiDecodeCtx->RTtbl,
224         &codecPicParams->CurrPic,
225         picParamBase->CurrPic,
226         0,  //picParam->pic_fields.bits.FieldPicFlag,
227         0,  //picParam->pic_fields.bits.FieldPicFlag,
228         false);
229     if (codecPicParams->CurrPic.FrameIdx == (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX)
230     {
231         return VA_STATUS_ERROR_INVALID_PARAMETER;
232     }
233 
234     uint32_t i, j, k, l;
235     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
236     {
237         if (picParamBase->ReferenceFrames[i].picture_id != VA_INVALID_SURFACE)
238         {
239             UpdateRegisteredRTSurfaceFlag(&(m_ddiDecodeCtx->RTtbl),
240                 DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParamBase->ReferenceFrames[i].picture_id));
241         }
242         SetupCodecPicture(
243             mediaCtx,
244             &m_ddiDecodeCtx->RTtbl,
245             &(codecPicParams->RefFrameList[i]),
246             picParamBase->ReferenceFrames[i],
247             0,  //picParam->pic_fields.bits.FieldPicFlag,
248             0,  //picParam->pic_fields.bits.FieldPicFlag,
249             true);
250         if (codecPicParams->RefFrameList[i].FrameIdx == (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX)
251         {
252             //in case the ref frame sent from App is wrong, set it to invalid ref frame index in codechal.
253             codecPicParams->RefFrameList[i].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC;
254         }
255     }
256 
257     codecPicParams->PicWidthInMinCbsY  = picParamBase->pic_width_in_luma_samples / (1 << (picParamBase->log2_min_luma_coding_block_size_minus3 + 3));
258     codecPicParams->PicHeightInMinCbsY = picParamBase->pic_height_in_luma_samples / (1 << (picParamBase->log2_min_luma_coding_block_size_minus3 + 3));
259 
260     codecPicParams->chroma_format_idc                 = picParamBase->pic_fields.bits.chroma_format_idc;
261     codecPicParams->separate_colour_plane_flag        = picParamBase->pic_fields.bits.separate_colour_plane_flag;
262     codecPicParams->bit_depth_luma_minus8             = picParamBase->bit_depth_luma_minus8;
263     codecPicParams->bit_depth_chroma_minus8           = picParamBase->bit_depth_chroma_minus8;
264     codecPicParams->log2_max_pic_order_cnt_lsb_minus4 = picParamBase->log2_max_pic_order_cnt_lsb_minus4;
265     codecPicParams->NoPicReorderingFlag               = picParamBase->pic_fields.bits.NoPicReorderingFlag;
266     codecPicParams->NoBiPredFlag                      = picParamBase->pic_fields.bits.NoBiPredFlag;
267 
268     codecPicParams->sps_max_dec_pic_buffering_minus1         = picParamBase->sps_max_dec_pic_buffering_minus1;
269     codecPicParams->log2_min_luma_coding_block_size_minus3   = picParamBase->log2_min_luma_coding_block_size_minus3;
270     codecPicParams->log2_diff_max_min_luma_coding_block_size = picParamBase->log2_diff_max_min_luma_coding_block_size;
271     codecPicParams->log2_min_transform_block_size_minus2     = picParamBase->log2_min_transform_block_size_minus2;
272     codecPicParams->log2_diff_max_min_transform_block_size   = picParamBase->log2_diff_max_min_transform_block_size;
273     codecPicParams->max_transform_hierarchy_depth_inter      = picParamBase->max_transform_hierarchy_depth_inter;
274     codecPicParams->max_transform_hierarchy_depth_intra      = picParamBase->max_transform_hierarchy_depth_intra;
275     codecPicParams->num_short_term_ref_pic_sets              = picParamBase->num_short_term_ref_pic_sets;
276     codecPicParams->num_long_term_ref_pic_sps                = picParamBase->num_long_term_ref_pic_sps;
277     codecPicParams->num_ref_idx_l0_default_active_minus1     = picParamBase->num_ref_idx_l0_default_active_minus1;
278     codecPicParams->num_ref_idx_l1_default_active_minus1     = picParamBase->num_ref_idx_l1_default_active_minus1;
279     codecPicParams->init_qp_minus26                          = picParamBase->init_qp_minus26;
280     codecPicParams->ucNumDeltaPocsOfRefRpsIdx                = 0;  //redundant parameter, decoder may ignore
281     codecPicParams->wNumBitsForShortTermRPSInSlice           = picParamBase->st_rps_bits;
282 
283     //dwCodingParamToolFlags
284     codecPicParams->scaling_list_enabled_flag                    = picParamBase->pic_fields.bits.scaling_list_enabled_flag;
285     codecPicParams->amp_enabled_flag                             = picParamBase->pic_fields.bits.amp_enabled_flag;
286     codecPicParams->sample_adaptive_offset_enabled_flag          = picParamBase->slice_parsing_fields.bits.sample_adaptive_offset_enabled_flag;
287     codecPicParams->pcm_enabled_flag                             = picParamBase->pic_fields.bits.pcm_enabled_flag;
288     codecPicParams->pcm_sample_bit_depth_luma_minus1             = picParamBase->pcm_sample_bit_depth_luma_minus1;
289     codecPicParams->pcm_sample_bit_depth_chroma_minus1           = picParamBase->pcm_sample_bit_depth_chroma_minus1;
290     codecPicParams->log2_min_pcm_luma_coding_block_size_minus3   = picParamBase->log2_min_pcm_luma_coding_block_size_minus3;
291     codecPicParams->log2_diff_max_min_pcm_luma_coding_block_size = picParamBase->log2_diff_max_min_pcm_luma_coding_block_size;
292     codecPicParams->pcm_loop_filter_disabled_flag                = picParamBase->pic_fields.bits.pcm_loop_filter_disabled_flag;
293     codecPicParams->long_term_ref_pics_present_flag              = picParamBase->slice_parsing_fields.bits.long_term_ref_pics_present_flag;
294     codecPicParams->sps_temporal_mvp_enabled_flag                = picParamBase->slice_parsing_fields.bits.sps_temporal_mvp_enabled_flag;
295     codecPicParams->strong_intra_smoothing_enabled_flag          = picParamBase->pic_fields.bits.strong_intra_smoothing_enabled_flag;
296     codecPicParams->dependent_slice_segments_enabled_flag        = picParamBase->slice_parsing_fields.bits.dependent_slice_segments_enabled_flag;
297     codecPicParams->output_flag_present_flag                     = picParamBase->slice_parsing_fields.bits.output_flag_present_flag;
298     codecPicParams->num_extra_slice_header_bits                  = picParamBase->num_extra_slice_header_bits;
299     codecPicParams->sign_data_hiding_enabled_flag                = picParamBase->pic_fields.bits.sign_data_hiding_enabled_flag;
300     codecPicParams->cabac_init_present_flag                      = picParamBase->slice_parsing_fields.bits.cabac_init_present_flag;
301 
302     codecPicParams->constrained_intra_pred_flag              = picParamBase->pic_fields.bits.constrained_intra_pred_flag;
303     codecPicParams->transform_skip_enabled_flag              = picParamBase->pic_fields.bits.transform_skip_enabled_flag;
304     codecPicParams->cu_qp_delta_enabled_flag                 = picParamBase->pic_fields.bits.cu_qp_delta_enabled_flag;
305     codecPicParams->pps_slice_chroma_qp_offsets_present_flag = picParamBase->slice_parsing_fields.bits.pps_slice_chroma_qp_offsets_present_flag;
306     codecPicParams->weighted_pred_flag                       = picParamBase->pic_fields.bits.weighted_pred_flag;
307     codecPicParams->weighted_bipred_flag                     = picParamBase->pic_fields.bits.weighted_bipred_flag;
308     codecPicParams->transquant_bypass_enabled_flag           = picParamBase->pic_fields.bits.transquant_bypass_enabled_flag;
309     codecPicParams->tiles_enabled_flag                       = picParamBase->pic_fields.bits.tiles_enabled_flag;
310     codecPicParams->entropy_coding_sync_enabled_flag         = picParamBase->pic_fields.bits.entropy_coding_sync_enabled_flag;
311     /*For va, uniform_spacing_flag==1, application should populate
312          column_width_minus[], and row_height_minus1[] with approperiate values. */
313     codecPicParams->uniform_spacing_flag                        = 0;
314     codecPicParams->loop_filter_across_tiles_enabled_flag       = picParamBase->pic_fields.bits.loop_filter_across_tiles_enabled_flag;
315     codecPicParams->pps_loop_filter_across_slices_enabled_flag  = picParamBase->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag;
316     codecPicParams->deblocking_filter_override_enabled_flag     = picParamBase->slice_parsing_fields.bits.deblocking_filter_override_enabled_flag;
317     codecPicParams->pps_deblocking_filter_disabled_flag         = picParamBase->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag;
318     codecPicParams->lists_modification_present_flag             = picParamBase->slice_parsing_fields.bits.lists_modification_present_flag;
319     codecPicParams->slice_segment_header_extension_present_flag = picParamBase->slice_parsing_fields.bits.slice_segment_header_extension_present_flag;
320     codecPicParams->IrapPicFlag                                 = picParamBase->slice_parsing_fields.bits.RapPicFlag;
321     codecPicParams->IdrPicFlag                                  = picParamBase->slice_parsing_fields.bits.IdrPicFlag;
322     codecPicParams->IntraPicFlag                                = picParamBase->slice_parsing_fields.bits.IntraPicFlag;
323 
324     codecPicParams->pps_cb_qp_offset        = picParamBase->pps_cb_qp_offset;
325     codecPicParams->pps_cr_qp_offset        = picParamBase->pps_cr_qp_offset;
326     codecPicParams->num_tile_columns_minus1 = picParamBase->num_tile_columns_minus1;
327     codecPicParams->num_tile_rows_minus1    = picParamBase->num_tile_rows_minus1;
328 
329     for (i = 0; i < HEVC_NUM_MAX_TILE_COLUMN - 1; i++)
330     {
331         codecPicParams->column_width_minus1[i] = picParamBase->column_width_minus1[i];
332     }
333     for (i = 0; i < HEVC_NUM_MAX_TILE_ROW - 1; i++)
334     {
335         codecPicParams->row_height_minus1[i] = picParamBase->row_height_minus1[i];
336     }
337 
338     codecPicParams->diff_cu_qp_delta_depth           = picParamBase->diff_cu_qp_delta_depth;
339     codecPicParams->pps_beta_offset_div2             = picParamBase->pps_beta_offset_div2;
340     codecPicParams->pps_tc_offset_div2               = picParamBase->pps_tc_offset_div2;
341     codecPicParams->log2_parallel_merge_level_minus2 = picParamBase->log2_parallel_merge_level_minus2;
342     codecPicParams->CurrPicOrderCntVal               = picParamBase->CurrPic.pic_order_cnt;
343 
344     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
345     {
346         codecPicParams->PicOrderCntValList[i] = picParamBase->ReferenceFrames[i].pic_order_cnt;
347     }
348 
349     for (i = 0; i < 8; i++)
350     {
351         codecPicParams->RefPicSetStCurrBefore[i] = 0xff;
352         codecPicParams->RefPicSetStCurrAfter[i]  = 0xff;
353         codecPicParams->RefPicSetLtCurr[i]       = 0xff;
354     }
355 
356     j = k = l = 0;
357 
358     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
359     {
360         if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE)
361         {
362             DDI_CHK_LESS(j, 8, "RefPicSetStCurrBefore[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
363             codecPicParams->RefPicSetStCurrBefore[j++] = i;
364         }
365         else if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_AFTER)
366         {
367             DDI_CHK_LESS(k, 8, "RefPicSetStCurrAfter[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
368             codecPicParams->RefPicSetStCurrAfter[k++] = i;
369         }
370         else if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_LT_CURR)
371         {
372             DDI_CHK_LESS(l, 8, "RefPicSetLtCurr[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
373             codecPicParams->RefPicSetLtCurr[l++] = i;
374         }
375     }
376 
377     codecPicParams->RefFieldPicFlag            = 0;
378     codecPicParams->RefBottomFieldFlag         = 0;
379     codecPicParams->StatusReportFeedbackNumber = 0;
380 
381     if (bIsHevcRext)
382     {
383         codecPicParamsExt->PicRangeExtensionFlags.dwRangeExtensionPropertyFlags    = picParamRext->range_extension_pic_fields.value;
384         codecPicParamsExt->diff_cu_chroma_qp_offset_depth                          = picParamRext->diff_cu_chroma_qp_offset_depth;
385         codecPicParamsExt->chroma_qp_offset_list_len_minus1                        = picParamRext->chroma_qp_offset_list_len_minus1;
386         codecPicParamsExt->log2_sao_offset_scale_luma                              = picParamRext->log2_sao_offset_scale_luma;
387         codecPicParamsExt->log2_sao_offset_scale_chroma                            = picParamRext->log2_sao_offset_scale_chroma;
388         codecPicParamsExt->log2_max_transform_skip_block_size_minus2               = picParamRext->log2_max_transform_skip_block_size_minus2;
389 
390         for (i = 0; i < 6; i++)
391         {
392             codecPicParamsExt->cb_qp_offset_list[i] = picParamRext->cb_qp_offset_list[i];
393             codecPicParamsExt->cr_qp_offset_list[i] = picParamRext->cr_qp_offset_list[i];
394         }
395     }
396 
397     return VA_STATUS_SUCCESS;
398 }
399 
GetFormat()400 MOS_FORMAT DdiDecodeHEVCG11::GetFormat()
401 {
402     MOS_FORMAT Format = Format_NV12;
403     DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_ddiDecodeCtx->RTtbl);
404     CodechalDecodeParams *decodeParams = &m_ddiDecodeCtx->DecodeParams;
405     CODEC_HEVC_PIC_PARAMS *picParams = (CODEC_HEVC_PIC_PARAMS *)decodeParams->m_picParams;
406     if ((m_ddiDecodeAttr->profile == VAProfileHEVCMain10) &&
407         ((picParams->bit_depth_luma_minus8 ||
408         picParams->bit_depth_chroma_minus8)))
409     {
410         Format = Format_P010;
411         if (picParams->chroma_format_idc == 2)
412         {
413             Format = Format_Y210;
414         }
415         else if (picParams->chroma_format_idc == 3)
416         {
417             Format = Format_Y410;
418         }
419     }
420     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain10
421         && picParams->bit_depth_luma_minus8 == 0
422         && picParams->bit_depth_chroma_minus8 == 0
423         && rtTbl->pCurrentRT->format == Media_Format_P010)
424     {
425         // for hevc deocde 8bit in 10bit, the app will pass the render
426         // target surface with the P010.
427         Format = Format_P010;
428     }
429     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain12)
430     {
431         Format = Format_P016;
432     }
433     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10)
434     {
435         //8bit
436         Format = Format_YUY2;
437         if (picParams->chroma_format_idc == 1)
438         {
439             Format = Format_NV12;
440         }
441         //10bit
442         if(picParams->bit_depth_luma_minus8 || picParams->bit_depth_chroma_minus8)
443         {
444             Format = Format_Y210;
445             if (picParams->chroma_format_idc == 1)
446             {
447                 Format = Format_P010;
448             }
449         }
450     }
451     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12)
452     {
453         Format = Format_Y216;
454         if (picParams->chroma_format_idc == 1)
455         {
456             Format = Format_P016;
457         }
458     }
459     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain444)
460     {
461         Format = Format_AYUV;
462         if (picParams->chroma_format_idc == 1)
463         {
464             Format = Format_NV12;
465         }
466         else if (picParams->chroma_format_idc == 2)
467         {
468             Format = Format_YUY2;
469         }
470     }
471     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10)
472     {
473         Format = Format_Y410;
474         if (picParams->chroma_format_idc == 1)
475         {
476             Format = Format_P010;
477         }
478         else if (picParams->chroma_format_idc == 2)
479         {
480             Format = Format_Y210;
481         }
482     }
483     else if(m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12)
484     {
485         Format = Format_Y416;
486         if (picParams->chroma_format_idc == 1)
487         {
488             Format = Format_P016;
489         }
490         else if (picParams->chroma_format_idc == 2)
491         {
492             Format = Format_Y216;
493         }
494     }
495     return Format;
496 
497 }
498 
AllocSliceParamContext(uint32_t numSlices)499 VAStatus DdiDecodeHEVCG11::AllocSliceParamContext(
500     uint32_t numSlices)
501 {
502     uint32_t baseSize = sizeof(CODEC_HEVC_SLICE_PARAMS);
503 
504     if (m_sliceParamBufNum < (m_ddiDecodeCtx->DecodeParams.m_numSlices + numSlices))
505     {
506         // in order to avoid that the buffer is reallocated multi-times,
507         // extra 10 slices are added.
508         uint32_t extraSlices = numSlices + 10;
509 
510         m_ddiDecodeCtx->DecodeParams.m_sliceParams = realloc(m_ddiDecodeCtx->DecodeParams.m_sliceParams,
511             baseSize * (m_sliceParamBufNum + extraSlices));
512 
513         if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
514         {
515             return VA_STATUS_ERROR_ALLOCATION_FAILED;
516         }
517 
518         memset((void *)((uint8_t *)m_ddiDecodeCtx->DecodeParams.m_sliceParams + baseSize * m_sliceParamBufNum), 0, baseSize * extraSlices);
519 
520         if(IsRextProfile())
521         {
522             uint32_t rextSize = sizeof(CODEC_HEVC_EXT_SLICE_PARAMS);
523             m_ddiDecodeCtx->DecodeParams.m_extSliceParams = realloc(m_ddiDecodeCtx->DecodeParams.m_extSliceParams,
524             rextSize * (m_sliceParamBufNum + extraSlices));
525 
526             if (m_ddiDecodeCtx->DecodeParams.m_extSliceParams == nullptr)
527             {
528                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
529             }
530 
531             memset((void *)((uint8_t *)m_ddiDecodeCtx->DecodeParams.m_extSliceParams + rextSize * m_sliceParamBufNum), 0, rextSize * extraSlices);
532         }
533 
534         m_sliceParamBufNum += extraSlices;
535     }
536 
537     return VA_STATUS_SUCCESS;
538 }
539 
InitResourceBuffer()540 VAStatus DdiDecodeHEVCG11::InitResourceBuffer()
541 {
542     VAStatus vaStatus = VA_STATUS_SUCCESS;
543 
544     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
545     bufMgr->pSliceData               = nullptr;
546 
547     bufMgr->ui64BitstreamOrder = 0;
548 
549     if(m_width * m_height < CODEC_720P_MAX_PIC_WIDTH * CODEC_720P_MAX_PIC_HEIGHT)
550     {
551         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 2;
552     }
553     else if(m_width * m_height < CODEC_4K_MAX_PIC_WIDTH * CODEC_4K_MAX_PIC_HEIGHT)
554     {
555         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 8;
556     }
557     else
558     {
559         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 16;
560     }
561 
562     // minimal 10k bytes for some special case. Will refractor this later
563     if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
564     {
565         bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
566     }
567 
568     int32_t i;
569     // init decode bitstream buffer object
570     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
571     {
572         bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
573         if (bufMgr->pBitStreamBuffObject[i] == nullptr)
574         {
575             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
576             goto finish;
577         }
578         bufMgr->pBitStreamBuffObject[i]->iSize    = bufMgr->dwMaxBsSize;
579         bufMgr->pBitStreamBuffObject[i]->uiType   = VASliceDataBufferType;
580         bufMgr->pBitStreamBuffObject[i]->format   = Media_Format_Buffer;
581         bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
582         bufMgr->pBitStreamBuffObject[i]->bo       = nullptr;
583         bufMgr->pBitStreamBase[i]                 = nullptr;
584     }
585 
586     // The pSliceData can be allocated on demand. So the default size is wPicHeightInLCU.
587     // Currently the LCU32 is used.
588     bufMgr->m_maxNumSliceData = MOS_ALIGN_CEIL(m_height, 32) / 32;
589     bufMgr->pSliceData        = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) *
590                                                                                    bufMgr->m_maxNumSliceData);
591 
592     if (bufMgr->pSliceData == nullptr)
593     {
594         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
595         goto finish;
596     }
597 
598     bufMgr->dwNumSliceData    = 0;
599     bufMgr->dwNumSliceControl = 0;
600 
601     /* as it can be increased on demand, the initial number will be based on LCU32 */
602     m_sliceCtrlBufNum = MOS_ALIGN_CEIL(m_height, 32) / 32;
603 
604     if (m_ddiDecodeCtx->bShortFormatInUse)
605     {
606         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC = (VASliceParameterBufferBase *)
607             MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferBase) * m_sliceCtrlBufNum);
608         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC == nullptr)
609         {
610             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
611             goto finish;
612         }
613     }
614     else if(!IsRextProfile())
615     {
616         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC = (VASliceParameterBufferHEVC *)
617             MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferHEVC) * m_sliceCtrlBufNum);
618         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC == nullptr)
619         {
620             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
621             goto finish;
622         }
623     }
624     else
625     {
626         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext= (VASliceParameterBufferHEVCExtension*)
627             MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferHEVCExtension) * m_sliceCtrlBufNum);
628         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext== nullptr)
629         {
630             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
631             goto finish;
632         }
633     }
634 
635     return VA_STATUS_SUCCESS;
636 
637 finish:
638     FreeResourceBuffer();
639     return vaStatus;
640 }
641 
FreeResourceBuffer()642 void DdiDecodeHEVCG11::FreeResourceBuffer()
643 {
644     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
645 
646     int32_t i;
647     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
648     {
649         if (bufMgr->pBitStreamBase[i])
650         {
651             DdiMediaUtil_UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
652             bufMgr->pBitStreamBase[i] = nullptr;
653         }
654         if (bufMgr->pBitStreamBuffObject[i])
655         {
656             DdiMediaUtil_FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
657             MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
658             bufMgr->pBitStreamBuffObject[i] = nullptr;
659         }
660     }
661 
662     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC)
663     {
664         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC);
665         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC = nullptr;
666     }
667     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC)
668     {
669         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC);
670         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC = nullptr;
671     }
672     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext)
673     {
674         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext);
675         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext = nullptr;
676     }
677 
678     // free decode bitstream buffer object
679     MOS_FreeMemory(bufMgr->pSliceData);
680     bufMgr->pSliceData = nullptr;
681 
682     return;
683 }
684 
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)685 uint8_t* DdiDecodeHEVCG11::GetPicParamBuf(
686     DDI_CODEC_COM_BUFFER_MGR    *bufMgr)
687 {
688     if(!IsRextProfile())
689     {
690         return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_HEVC.PicParamHEVC));
691     }
692     else
693     {
694         return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_HEVC.PicParamHEVCRext));
695     }
696 }
697 
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)698 VAStatus DdiDecodeHEVCG11::AllocSliceControlBuffer(
699     DDI_MEDIA_BUFFER       *buf)
700 {
701     DDI_CODEC_COM_BUFFER_MGR   *bufMgr;
702     uint32_t                    availSize;
703     uint32_t                    newSize;
704 
705     bufMgr     = &(m_ddiDecodeCtx->BufMgr);
706     availSize = m_sliceCtrlBufNum - bufMgr->dwNumSliceControl;
707 
708     if(buf->uiNumElements < 1 || buf->iSize < 1)
709         return VA_STATUS_ERROR_ALLOCATION_FAILED;
710 
711     if(m_ddiDecodeCtx->bShortFormatInUse)
712     {
713         if(availSize < buf->uiNumElements)
714         {
715             if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferBase))
716                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
717 
718             newSize   = sizeof(VASliceParameterBufferBase) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
719             bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC = (VASliceParameterBufferBase *)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC, newSize);
720             if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC == nullptr)
721             {
722                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
723             }
724             MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferBase) * (buf->uiNumElements - availSize));
725             m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
726         }
727         buf->pData      = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC;
728         buf->uiOffset   = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferBase);
729     }
730     else
731     {
732         if(!IsRextProfile())
733         {
734             if(availSize < buf->uiNumElements)
735             {
736                 if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferHEVC))
737                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
738 
739                 newSize   = sizeof(VASliceParameterBufferHEVC) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
740                 bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC = (VASliceParameterBufferHEVC *)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC, newSize);
741                 if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC == nullptr)
742                 {
743                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
744                 }
745                 MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferHEVC) * (buf->uiNumElements - availSize));
746                 m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
747             }
748             buf->pData      = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC;
749             buf->uiOffset   = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferHEVC);
750         }
751         else
752         {
753             if(availSize < buf->uiNumElements)
754             {
755                 if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferHEVCExtension))
756                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
757 
758                 newSize   = sizeof(VASliceParameterBufferHEVCExtension) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
759                 bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext= (VASliceParameterBufferHEVCExtension*)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext, newSize);
760                 if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext== nullptr)
761                 {
762                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
763                 }
764                 MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext+ m_sliceCtrlBufNum, sizeof(VASliceParameterBufferHEVCExtension) * (buf->uiNumElements - availSize));
765                 m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
766             }
767             buf->pData      = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext;
768             buf->uiOffset   = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferHEVCExtension);
769         }
770     }
771 
772     bufMgr->dwNumSliceControl += buf->uiNumElements;
773 
774     return VA_STATUS_SUCCESS;
775 }
776 
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)777 VAStatus DdiDecodeHEVCG11::CodecHalInit(
778     DDI_MEDIA_CONTEXT *mediaCtx,
779     void              *ptr)
780 {
781     VAStatus     vaStatus = VA_STATUS_SUCCESS;
782     MOS_CONTEXT *mosCtx   = (MOS_CONTEXT *)ptr;
783 
784     CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
785     m_ddiDecodeCtx->pCpDdiInterface->SetCpParams(m_ddiDecodeAttr->uiEncryptionType, m_codechalSettings);
786 
787     CODECHAL_STANDARD_INFO standardInfo;
788     memset(&standardInfo, 0, sizeof(standardInfo));
789 
790     standardInfo.CodecFunction = codecFunction;
791     standardInfo.Mode          = (CODECHAL_MODE)m_ddiDecodeCtx->wMode;
792 
793     m_codechalSettings->codecFunction = codecFunction;
794     m_codechalSettings->width       = m_width;
795     m_codechalSettings->height      = m_height;
796     m_codechalSettings->intelEntrypointInUse = false;
797 
798     m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
799     if (m_ddiDecodeAttr->profile == VAProfileHEVCMain10 ||
800         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 ||
801         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10)
802     {
803         m_codechalSettings->lumaChromaDepth |= CODECHAL_LUMA_CHROMA_DEPTH_10_BITS;
804     }
805 
806     m_codechalSettings->shortFormatInUse = m_ddiDecodeCtx->bShortFormatInUse;
807 
808     m_codechalSettings->mode           = CODECHAL_DECODE_MODE_HEVCVLD;
809     m_codechalSettings->standard       = CODECHAL_HEVC;
810     m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV420;
811 
812     if(m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 ||
813        m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12)
814     {
815         m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV422;
816     }
817 
818     if(m_ddiDecodeAttr->profile == VAProfileHEVCMain444 ||
819        m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10 ||
820        m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12)
821     {
822         m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV444;
823     }
824 
825     m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer = MOS_AllocAndZeroMemory(sizeof(CODECHAL_HEVC_IQ_MATRIX_PARAMS));
826     if (m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer == nullptr)
827     {
828         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
829         goto CleanUpandReturn;
830     }
831     m_ddiDecodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_PIC_PARAMS));
832     if (m_ddiDecodeCtx->DecodeParams.m_picParams == nullptr)
833     {
834         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
835         goto CleanUpandReturn;
836     }
837     if(IsRextProfile())
838     {
839         m_ddiDecodeCtx->DecodeParams.m_extPicParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_EXT_PIC_PARAMS));
840         if (m_ddiDecodeCtx->DecodeParams.m_extPicParams == nullptr)
841         {
842             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
843             goto CleanUpandReturn;
844         }
845     }
846 
847     m_sliceParamBufNum         = m_picHeightInMB;
848     m_ddiDecodeCtx->DecodeParams.m_sliceParams = MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_HEVC_SLICE_PARAMS));
849     if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
850     {
851         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
852         goto CleanUpandReturn;
853     }
854 
855     if(IsRextProfile())
856     {
857         m_ddiDecodeCtx->DecodeParams.m_extSliceParams = MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_HEVC_EXT_SLICE_PARAMS));
858         if (m_ddiDecodeCtx->DecodeParams.m_extSliceParams == nullptr)
859         {
860             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
861             goto CleanUpandReturn;
862         }
863     }
864 #ifdef _DECODE_PROCESSING_SUPPORTED
865     if (m_decProcessingType == VA_DEC_PROCESSING)
866     {
867         DecodeProcessingParams *procParams = nullptr;
868 
869         m_codechalSettings->downsamplingHinted = true;
870 
871         procParams = (DecodeProcessingParams *)MOS_AllocAndZeroMemory(sizeof(DecodeProcessingParams));
872         if (procParams == nullptr)
873         {
874             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
875             goto CleanUpandReturn;
876         }
877 
878         m_ddiDecodeCtx->DecodeParams.m_procParams = procParams;
879         procParams->m_outputSurface = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
880         if (procParams->m_outputSurface == nullptr)
881         {
882             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
883             goto CleanUpandReturn;
884         }
885     }
886 #endif
887 
888     vaStatus = CreateCodecHal(mediaCtx,
889         ptr,
890         &standardInfo);
891 
892     if (vaStatus != VA_STATUS_SUCCESS)
893     {
894         goto CleanUpandReturn;
895     }
896 
897     if (InitResourceBuffer() != VA_STATUS_SUCCESS)
898     {
899         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
900         goto CleanUpandReturn;
901     }
902 
903     return vaStatus;
904 
905 CleanUpandReturn:
906     FreeResourceBuffer();
907 
908     if (m_ddiDecodeCtx->pCodecHal)
909     {
910         m_ddiDecodeCtx->pCodecHal->Destroy();
911         MOS_Delete(m_ddiDecodeCtx->pCodecHal);
912         m_ddiDecodeCtx->pCodecHal = nullptr;
913     }
914 
915     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer);
916     m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer = nullptr;
917     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_picParams);
918     m_ddiDecodeCtx->DecodeParams.m_picParams = nullptr;
919     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_huffmanTable);
920     m_ddiDecodeCtx->DecodeParams.m_huffmanTable = nullptr;
921     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
922     m_ddiDecodeCtx->DecodeParams.m_sliceParams = nullptr;
923 
924 #ifdef _DECODE_PROCESSING_SUPPORTED
925     if (m_ddiDecodeCtx->DecodeParams.m_procParams)
926     {
927         auto procParams =
928             (DecodeProcessingParams *)m_ddiDecodeCtx->DecodeParams.m_procParams;
929         MOS_FreeMemory(procParams->m_outputSurface);
930 
931         MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_procParams);
932         m_ddiDecodeCtx->DecodeParams.m_procParams = nullptr;
933     }
934 #endif
935     return vaStatus;
936 }
937 
IsRextProfile()938 bool DdiDecodeHEVCG11::IsRextProfile()
939 {
940     return (                                                   \
941         m_ddiDecodeAttr->profile == VAProfileHEVCMain12     || \
942         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 || \
943         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12 || \
944         m_ddiDecodeAttr->profile == VAProfileHEVCMain444    || \
945         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10 || \
946         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12    \
947         );
948 }
949 
950 
951 extern template class MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>;
952 
953 static bool hevcRegistered =
954     MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>::RegisterCodec<DdiDecodeHEVCG11>(DECODE_ID_HEVC_G11);
955