1 /*
2 * Copyright (c) 2022-2023, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     ddi_decode_hevc_specific.cpp
24 //! \brief    HEVC class definition for DDI media decoder
25 //!
26 
27 #include "ddi_decode_functions.h"
28 #include "media_libva_util_next.h"
29 #include "ddi_decode_hevc_specific.h"
30 #include "media_ddi_factory.h"
31 #include "media_libva_common_next.h"
32 #include "codec_def_decode_hevc.h"
33 #include "media_libva_interface_next.h"
34 #include "ddi_libva_decoder_specific.h"
35 #include "ddi_decode_trace_specific.h"
36 
37 namespace decode
38 {
39 
ParseSliceParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferHEVC * slcParam,uint32_t numSlices)40 VAStatus DdiDecodeHevc::ParseSliceParams(
41     DDI_MEDIA_CONTEXT          *mediaCtx,
42     VASliceParameterBufferHEVC *slcParam,
43     uint32_t                   numSlices)
44 {
45     DDI_CODEC_FUNC_ENTER;
46 
47     VASliceParameterBufferHEVC *slc     = slcParam;
48     VASliceParameterBufferBase *slcBase = (VASliceParameterBufferBase *)slcParam;
49     bool isHevcRext = IsRextProfile();
50     bool isHevcScc  = IsSccProfile();
51 
52     PCODEC_HEVC_SLICE_PARAMS codecSlcParams = (PCODEC_HEVC_SLICE_PARAMS)(m_decodeCtx->DecodeParams.m_sliceParams);
53     codecSlcParams += m_decodeCtx->DecodeParams.m_numSlices;
54     PCODEC_HEVC_EXT_SLICE_PARAMS codecSclParamsRext = nullptr;
55     VASliceParameterBufferHEVCExtension *slcExtension = nullptr;
56     VASliceParameterBufferHEVCRext *slcRext = nullptr;
57 
58     if (isHevcRext)
59     {
60         codecSclParamsRext = (PCODEC_HEVC_EXT_SLICE_PARAMS)(m_decodeCtx->DecodeParams.m_extSliceParams);
61         codecSclParamsRext += m_decodeCtx->DecodeParams.m_numSlices;
62         slcExtension = (VASliceParameterBufferHEVCExtension *)slcParam;
63         slc     = &slcExtension->base;
64         slcRext = &slcExtension->rext;
65     }
66 
67     if ((slcParam == nullptr) || (codecSlcParams == nullptr) || (isHevcRext && (codecSclParamsRext == nullptr || slcRext == nullptr)))
68     {
69         DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing HEVC Slice parameter\n");
70         return VA_STATUS_ERROR_INVALID_PARAMETER;
71     }
72 
73     memset(codecSlcParams, 0, numSlices * sizeof(CODEC_HEVC_SLICE_PARAMS));
74     if (isHevcRext)
75     {
76         memset(codecSclParamsRext, 0, numSlices * sizeof(CODEC_HEVC_EXT_SLICE_PARAMS));
77     }
78 
79     uint32_t sliceBaseOffset = GetBsBufOffset(m_groupIndex);
80     uint32_t i, j, slcCount;
81     for (slcCount = 0; slcCount < numSlices; slcCount++)
82     {
83         if (m_decodeCtx->bShortFormatInUse)
84         {
85             codecSlcParams->slice_data_size   = slcBase->slice_data_size;
86             codecSlcParams->slice_data_offset = sliceBaseOffset + slcBase->slice_data_offset;
87             if (slcBase->slice_data_flag)
88             {
89                 DDI_CODEC_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
90             }
91             slcBase++;
92         }
93         else
94         {
95             codecSlcParams->slice_data_size   = slc->slice_data_size;
96             codecSlcParams->slice_data_offset = sliceBaseOffset + slc->slice_data_offset;
97             if (slcBase->slice_data_flag)
98             {
99                 DDI_CODEC_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
100             }
101 
102             codecSlcParams->ByteOffsetToSliceData = slc->slice_data_byte_offset;
103             codecSlcParams->NumEmuPrevnBytesInSliceHdr = slc->slice_data_num_emu_prevn_bytes;
104             codecSlcParams->slice_segment_address = slc->slice_segment_address;
105 
106             for (i = 0; i < 2; i++)
107             {
108                 for (j = 0; j < CODEC_MAX_NUM_REF_FRAME_HEVC; j++)
109                 {
110                     codecSlcParams->RefPicList[i][j].FrameIdx = (slc->RefPicList[i][j] == 0xff) ? 0x7f : slc->RefPicList[i][j];
111                 }
112             }
113 
114             codecSlcParams->LongSliceFlags.value           = slc->LongSliceFlags.value;
115             codecSlcParams->collocated_ref_idx             = slc->collocated_ref_idx;
116             codecSlcParams->num_ref_idx_l0_active_minus1   = slc->num_ref_idx_l0_active_minus1;
117             codecSlcParams->num_ref_idx_l1_active_minus1   = slc->num_ref_idx_l1_active_minus1;
118             codecSlcParams->slice_qp_delta                 = slc->slice_qp_delta;
119             codecSlcParams->slice_cb_qp_offset             = slc->slice_cb_qp_offset;
120             codecSlcParams->slice_cr_qp_offset             = slc->slice_cr_qp_offset;
121             codecSlcParams->slice_beta_offset_div2         = slc->slice_beta_offset_div2;
122             codecSlcParams->slice_tc_offset_div2           = slc->slice_tc_offset_div2;
123             codecSlcParams->luma_log2_weight_denom         = slc->luma_log2_weight_denom;
124             codecSlcParams->delta_chroma_log2_weight_denom = slc->delta_chroma_log2_weight_denom;
125 
126             MOS_SecureMemcpy(codecSlcParams->delta_luma_weight_l0,
127                 15,
128                 slc->delta_luma_weight_l0,
129                 15);
130             MOS_SecureMemcpy(codecSlcParams->delta_luma_weight_l1,
131                 15,
132                 slc->delta_luma_weight_l1,
133                 15);
134 
135             MOS_SecureMemcpy(codecSlcParams->delta_chroma_weight_l0,
136                 15 * 2,
137                 slc->delta_chroma_weight_l0,
138                 15 * 2);
139             MOS_SecureMemcpy(codecSlcParams->delta_chroma_weight_l1,
140                 15 * 2,
141                 slc->delta_chroma_weight_l1,
142                 15 * 2);
143             codecSlcParams->five_minus_max_num_merge_cand = slc->five_minus_max_num_merge_cand;
144             codecSlcParams->num_entry_point_offsets       = slc->num_entry_point_offsets;
145             codecSlcParams->EntryOffsetToSubsetArray      = slc->entry_offset_to_subset_array;
146 
147             if (!isHevcRext)
148             {
149                 MOS_SecureMemcpy(codecSlcParams->luma_offset_l0,
150                     15,
151                     slc->luma_offset_l0,
152                     15);
153                 MOS_SecureMemcpy(codecSlcParams->luma_offset_l1,
154                     15,
155                     slc->luma_offset_l1,
156                     15);
157                 MOS_SecureMemcpy(codecSlcParams->ChromaOffsetL0,
158                     15 * 2,
159                     slc->ChromaOffsetL0,
160                     15 * 2);
161                 MOS_SecureMemcpy(codecSlcParams->ChromaOffsetL1,
162                     15 * 2,
163                     slc->ChromaOffsetL1,
164                     15 * 2);
165 
166                 slc++;
167             }
168             else
169             {
170                 MOS_SecureMemcpy(codecSclParamsRext->luma_offset_l0,
171                     15 * sizeof(int16_t),
172                     slcRext->luma_offset_l0,
173                     15 * sizeof(int16_t));
174                 MOS_SecureMemcpy(codecSclParamsRext->luma_offset_l1,
175                     15 * sizeof(int16_t),
176                     slcRext->luma_offset_l1,
177                     15 * sizeof(int16_t));
178                 MOS_SecureMemcpy(codecSclParamsRext->ChromaOffsetL0,
179                     15 * 2 * sizeof(int16_t),
180                     slcRext->ChromaOffsetL0,
181                     15 * 2 * sizeof(int16_t));
182                 MOS_SecureMemcpy(codecSclParamsRext->ChromaOffsetL1,
183                     15 * 2 * sizeof(int16_t),
184                     slcRext->ChromaOffsetL1,
185                     15 * 2 * sizeof(int16_t));
186 
187                 codecSclParamsRext->cu_chroma_qp_offset_enabled_flag = slcRext->slice_ext_flags.bits.cu_chroma_qp_offset_enabled_flag;
188 
189                 if (isHevcScc)
190                 {
191                     codecSclParamsRext->use_integer_mv_flag    = slcRext->slice_ext_flags.bits.use_integer_mv_flag;
192                     codecSclParamsRext->slice_act_y_qp_offset  = slcRext->slice_act_y_qp_offset;
193                     codecSclParamsRext->slice_act_cb_qp_offset = slcRext->slice_act_cb_qp_offset;
194                     codecSclParamsRext->slice_act_cr_qp_offset = slcRext->slice_act_cr_qp_offset;
195                 }
196 
197                 codecSclParamsRext++;
198                 slcExtension++;
199                 slc     = &slcExtension->base;
200                 slcRext = &slcExtension->rext;
201             }
202         }
203         codecSlcParams++;
204     }
205 
206     return VA_STATUS_SUCCESS;
207 }
208 
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VAPictureParameterBufferHEVC * picParam)209 VAStatus DdiDecodeHevc::ParsePicParams(
210     DDI_MEDIA_CONTEXT            *mediaCtx,
211     VAPictureParameterBufferHEVC *picParam)
212 {
213     DDI_CODEC_FUNC_ENTER;
214 
215     PCODEC_HEVC_PIC_PARAMS     codecPicParams    = (PCODEC_HEVC_PIC_PARAMS)(m_decodeCtx->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_decodeCtx->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_decodeCtx->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_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing HEVC Picture parameter\n");
247         return VA_STATUS_ERROR_INVALID_PARAMETER;
248     }
249 
250     SetupCodecPicture(
251         mediaCtx,
252         &m_decodeCtx->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_decodeCtx->RTtbl),
269                 MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, picParamBase->ReferenceFrames[i].picture_id));
270         }
271         SetupCodecPicture(
272             mediaCtx,
273             &m_decodeCtx->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     for (i = 0; i < HEVC_NUM_MAX_TILE_COLUMN - 1; i++)
359     {
360         codecPicParams->column_width_minus1[i] = picParamBase->column_width_minus1[i];
361     }
362     for (i = 0; i < HEVC_NUM_MAX_TILE_ROW - 1; i++)
363     {
364         codecPicParams->row_height_minus1[i] = picParamBase->row_height_minus1[i];
365     }
366 
367     codecPicParams->diff_cu_qp_delta_depth           = picParamBase->diff_cu_qp_delta_depth;
368     codecPicParams->pps_beta_offset_div2             = picParamBase->pps_beta_offset_div2;
369     codecPicParams->pps_tc_offset_div2               = picParamBase->pps_tc_offset_div2;
370     codecPicParams->log2_parallel_merge_level_minus2 = picParamBase->log2_parallel_merge_level_minus2;
371     codecPicParams->CurrPicOrderCntVal               = picParamBase->CurrPic.pic_order_cnt;
372 
373     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
374     {
375         codecPicParams->PicOrderCntValList[i] = picParamBase->ReferenceFrames[i].pic_order_cnt;
376     }
377 
378     for (i = 0; i < 8; i++)
379     {
380         codecPicParams->RefPicSetStCurrBefore[i] = 0xff;
381         codecPicParams->RefPicSetStCurrAfter[i]  = 0xff;
382         codecPicParams->RefPicSetLtCurr[i]       = 0xff;
383     }
384 
385     j = k = l = 0;
386 
387     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
388     {
389         if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE)
390         {
391             DDI_CODEC_CHK_LESS(j, 8, "RefPicSetStCurrBefore[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
392             codecPicParams->RefPicSetStCurrBefore[j++] = i;
393         }
394         else if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_AFTER)
395         {
396             DDI_CODEC_CHK_LESS(k, 8, "RefPicSetStCurrAfter[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
397             codecPicParams->RefPicSetStCurrAfter[k++] = i;
398         }
399         else if (picParamBase->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_LT_CURR)
400         {
401             DDI_CODEC_CHK_LESS(l, 8, "RefPicSetLtCurr[] index out of bounds.", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
402             codecPicParams->RefPicSetLtCurr[l++] = i;
403         }
404     }
405 
406     codecPicParams->RefFieldPicFlag            = 0;
407     codecPicParams->RefBottomFieldFlag         = 0;
408     codecPicParams->StatusReportFeedbackNumber = 0;
409 
410     if (bIsHevcRext)
411     {
412         codecPicParamsExt->PicRangeExtensionFlags.dwRangeExtensionPropertyFlags    = picParamRext->range_extension_pic_fields.value;
413         codecPicParamsExt->diff_cu_chroma_qp_offset_depth                          = picParamRext->diff_cu_chroma_qp_offset_depth;
414         codecPicParamsExt->chroma_qp_offset_list_len_minus1                        = picParamRext->chroma_qp_offset_list_len_minus1;
415         codecPicParamsExt->log2_sao_offset_scale_luma                              = picParamRext->log2_sao_offset_scale_luma;
416         codecPicParamsExt->log2_sao_offset_scale_chroma                            = picParamRext->log2_sao_offset_scale_chroma;
417         codecPicParamsExt->log2_max_transform_skip_block_size_minus2               = picParamRext->log2_max_transform_skip_block_size_minus2;
418 
419         for (i = 0; i < 6; i++)
420         {
421             codecPicParamsExt->cb_qp_offset_list[i] = picParamRext->cb_qp_offset_list[i];
422             codecPicParamsExt->cr_qp_offset_list[i] = picParamRext->cr_qp_offset_list[i];
423         }
424     }
425 
426     if (bIsHevcScc)
427     {
428         codecPicParamsScc->PicSCCExtensionFlags.dwScreenContentCodingPropertyFlags = picParamScc->screen_content_pic_fields.value;
429         codecPicParamsScc->palette_max_size                                        = picParamScc->palette_max_size;
430         codecPicParamsScc->delta_palette_max_predictor_size                        = picParamScc->delta_palette_max_predictor_size;
431         codecPicParamsScc->PredictorPaletteSize                                    = picParamScc->predictor_palette_size;
432         codecPicParamsScc->pps_act_y_qp_offset_plus5                               = picParamScc->pps_act_y_qp_offset_plus5;
433         codecPicParamsScc->pps_act_cb_qp_offset_plus5                              = picParamScc->pps_act_cb_qp_offset_plus5;
434         codecPicParamsScc->pps_act_cr_qp_offset_plus3                              = picParamScc->pps_act_cr_qp_offset_plus3;
435         uint32_t uiCopySize = sizeof(codecPicParamsScc->PredictorPaletteEntries);
436         MOS_SecureMemcpy(&codecPicParamsScc->PredictorPaletteEntries, uiCopySize, &picParamScc->predictor_palette_entries, uiCopySize);
437     }
438 
439     return VA_STATUS_SUCCESS;
440 }
441 
ParseIQMatrix(DDI_MEDIA_CONTEXT * mediaCtx,VAIQMatrixBufferHEVC * matrix)442 VAStatus DdiDecodeHevc::ParseIQMatrix(
443     DDI_MEDIA_CONTEXT    *mediaCtx,
444     VAIQMatrixBufferHEVC *matrix)
445 {
446     DDI_CODEC_FUNC_ENTER;
447 
448     PCODECHAL_HEVC_IQ_MATRIX_PARAMS iqMatrix =
449         (PCODECHAL_HEVC_IQ_MATRIX_PARAMS)(m_decodeCtx->DecodeParams.m_iqMatrixBuffer);
450 
451     if ((matrix == nullptr) || (iqMatrix == nullptr))
452     {
453         DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing HEVC IQMatrix parameter\n");
454         return VA_STATUS_ERROR_INVALID_PARAMETER;
455     }
456 
457     MOS_SecureMemcpy((void *)iqMatrix->ucScalingLists0,
458         6 * 16 * sizeof(uint8_t),
459         (void *)matrix->ScalingList4x4,
460         6 * 16 * sizeof(uint8_t));
461     MOS_SecureMemcpy((void *)iqMatrix->ucScalingLists1,
462         6 * 64 * sizeof(uint8_t),
463         (void *)matrix->ScalingList8x8,
464         6 * 64 * sizeof(uint8_t));
465     MOS_SecureMemcpy((void *)iqMatrix->ucScalingLists2,
466         6 * 64 * sizeof(uint8_t),
467         (void *)matrix->ScalingList16x16,
468         6 * 64 * sizeof(uint8_t));
469     MOS_SecureMemcpy((void *)iqMatrix->ucScalingLists3,
470         2 * 64 * sizeof(uint8_t),
471         (void *)matrix->ScalingList32x32,
472         2 * 64 * sizeof(uint8_t));
473     MOS_SecureMemcpy((void *)iqMatrix->ucScalingListDCCoefSizeID2,
474         6 * sizeof(uint8_t),
475         (void *)matrix->ScalingListDC16x16,
476         6 * sizeof(uint8_t));
477     MOS_SecureMemcpy((void *)iqMatrix->ucScalingListDCCoefSizeID3,
478         2 * sizeof(uint8_t),
479         (void *)matrix->ScalingListDC32x32,
480         2 * sizeof(uint8_t));
481 
482     return VA_STATUS_SUCCESS;
483 }
484 
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)485 VAStatus DdiDecodeHevc::RenderPicture(
486     VADriverContextP ctx,
487     VAContextID      context,
488     VABufferID       *buffers,
489     int32_t          numBuffers)
490 {
491     DDI_CODEC_FUNC_ENTER;
492 
493     VAStatus va = VA_STATUS_SUCCESS;
494     PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
495 
496     void *data = nullptr;
497     for (int i = 0; i < numBuffers; i++)
498     {
499         if (!buffers || (buffers[i] == VA_INVALID_ID))
500         {
501             return VA_STATUS_ERROR_INVALID_BUFFER;
502         }
503 
504         DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, buffers[i]);
505         if (nullptr == buf)
506         {
507             return VA_STATUS_ERROR_INVALID_BUFFER;
508         }
509 
510         uint32_t dataSize = buf->iSize;
511         MediaLibvaInterfaceNext::MapBuffer(ctx, buffers[i], &data);
512 
513         if (data == nullptr)
514         {
515             return VA_STATUS_ERROR_INVALID_BUFFER;
516         }
517 
518         switch ((int32_t)buf->uiType)
519         {
520         case VASliceDataBufferType:
521         {
522             int32_t index = GetBitstreamBufIndexFromBuffer(&m_decodeCtx->BufMgr, buf);
523             if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
524             {
525                 return VA_STATUS_ERROR_INVALID_BUFFER;
526             }
527 
528             MediaLibvaCommonNext::MediaBufferToMosResource(m_decodeCtx->BufMgr.pBitStreamBuffObject[index], &m_decodeCtx->BufMgr.resBitstreamBuffer);
529             m_decodeCtx->DecodeParams.m_dataSize += dataSize;
530 
531             break;
532         }
533         case VASliceParameterBufferType:
534         {
535             if (buf->uiNumElements == 0)
536             {
537                 return VA_STATUS_ERROR_INVALID_BUFFER;
538             }
539 
540             VASliceParameterBufferHEVC *slcInfoHEVC = (VASliceParameterBufferHEVC *)data;
541             uint32_t numSlices = buf->uiNumElements;
542             DDI_CODEC_CHK_RET(AllocSliceParamContext(numSlices),"AllocSliceParamContext failed!");
543             DDI_CODEC_CHK_RET(ParseSliceParams(mediaCtx, slcInfoHEVC, numSlices),"ParseSliceParams failed!");
544             m_decodeCtx->DecodeParams.m_numSlices += numSlices;
545             m_groupIndex++;
546             break;
547         }
548         case VAIQMatrixBufferType:
549         {
550             VAIQMatrixBufferHEVC *imxBuf = (VAIQMatrixBufferHEVC *)data;
551             DDI_CODEC_CHK_RET(ParseIQMatrix(mediaCtx, imxBuf),"ParseIQMatrix failed!");
552 
553             break;
554         }
555         case VAPictureParameterBufferType:
556         {
557             VAPictureParameterBufferHEVC *picParam = (VAPictureParameterBufferHEVC *)data;
558             DDI_CODEC_CHK_RET(ParsePicParams(mediaCtx, picParam),"ParsePicParams failed!");
559             break;
560         }
561         case VASubsetsParameterBufferType:
562         {
563 
564             if (m_decodeCtx->DecodeParams.m_subsetParams == nullptr) {
565                 m_decodeCtx->DecodeParams.m_subsetParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_SUBSET_PARAMS));
566 
567                 if (m_decodeCtx->DecodeParams.m_subsetParams == nullptr)
568                     break;
569             }
570 
571             MOS_SecureMemcpy(m_decodeCtx->DecodeParams.m_subsetParams, dataSize, data, dataSize);
572 
573             break;
574         }
575         case VAProcPipelineParameterBufferType:
576         {
577             DDI_CODEC_CHK_RET(ParseProcessingBuffer(mediaCtx, data),"ParseProcessingBuffer failed!");
578             break;
579         }
580         case VADecodeStreamoutBufferType:
581         {
582             MediaLibvaCommonNext::MediaBufferToMosResource(buf, &m_decodeCtx->BufMgr.resExternalStreamOutBuffer);
583             m_streamOutEnabled = true;
584             break;
585         }
586         default:
587             va = m_decodeCtx->pCpDdiInterfaceNext->RenderCencPicture(ctx, context, buf, data);
588             break;
589         }
590         MediaLibvaInterfaceNext::UnmapBuffer(ctx, buffers[i]);
591     }
592 
593     return va;
594 }
595 
GetFormat()596 MOS_FORMAT DdiDecodeHevc::GetFormat()
597 {
598     DDI_CODEC_FUNC_ENTER;
599 
600     MOS_FORMAT Format = Format_NV12;
601     DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_decodeCtx->RTtbl);
602     CodechalDecodeParams  *decodeParams  = &m_decodeCtx->DecodeParams;
603     CODEC_HEVC_PIC_PARAMS *picParams     = (CODEC_HEVC_PIC_PARAMS *)decodeParams->m_picParams;
604     if ((m_ddiDecodeAttr->profile == VAProfileHEVCMain10) &&
605         ((picParams->bit_depth_luma_minus8 ||
606         picParams->bit_depth_chroma_minus8)))
607     {
608         Format = Format_P010;
609         if (picParams->chroma_format_idc == 2)
610         {
611             Format = Format_Y210;
612         }
613         else if (picParams->chroma_format_idc == 3)
614         {
615             Format = Format_Y410;
616         }
617     }
618     else if (m_ddiDecodeAttr->profile == VAProfileHEVCMain10
619             && picParams->bit_depth_luma_minus8 == 0
620             && picParams->bit_depth_chroma_minus8 == 0
621             && rtTbl->pCurrentRT->format == Media_Format_P010)
622     {
623         // for hevc deocde 8bit in 10bit, the app will pass the render
624         // target surface with the P010.
625         Format = Format_P010;
626     }
627     else if (m_ddiDecodeAttr->profile == VAProfileHEVCMain12)
628     {
629         Format = Format_P016;
630     }
631     else if (m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10
632             || m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12
633             || m_ddiDecodeAttr->profile == VAProfileHEVCMain444
634             || m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10
635             || m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12)
636     {
637         Format = Format_NV12;
638         if (picParams->bit_depth_luma_minus8 == 0
639             && picParams->bit_depth_chroma_minus8 == 0) // 8bit
640         {
641             if (picParams->chroma_format_idc == 1) // 420
642             {
643                 Format = Format_NV12;
644                 if (rtTbl->pCurrentRT->format == Media_Format_P010)
645                 {
646                     Format = Format_P010;
647                 }
648                 else if (rtTbl->pCurrentRT->format == Media_Format_P016 || rtTbl->pCurrentRT->format == Media_Format_P012)
649                 {
650                     Format = Format_P016;
651                 }
652             }
653             else if (picParams->chroma_format_idc == 2) // 422
654             {
655                 Format = Format_YUY2;
656                 if (rtTbl->pCurrentRT->format == Media_Format_Y210)
657                 {
658                     Format = Format_Y210;
659                 }
660 #if VA_CHECK_VERSION(1, 9, 0)
661                 else if (rtTbl->pCurrentRT->format == Media_Format_Y216 || rtTbl->pCurrentRT->format == Media_Format_Y212)
662 #else
663                 else if (rtTbl->pCurrentRT->format == Media_Format_Y216)
664 #endif
665                 {
666                     Format = Format_Y216;
667                 }
668             }
669             else // 444
670             {
671                 Format = Format_AYUV;
672                 if (rtTbl->pCurrentRT->format == Media_Format_Y410)
673                 {
674                     Format = Format_Y410;
675                 }
676 #if VA_CHECK_VERSION(1, 9, 0)
677                 else if (rtTbl->pCurrentRT->format == Media_Format_Y416 || rtTbl->pCurrentRT->format == Media_Format_Y412)
678 #else
679                 else if (rtTbl->pCurrentRT->format == Media_Format_Y416)
680 #endif
681                 {
682                     Format = Format_Y416;
683                 }
684             }
685         }
686         else if (picParams->bit_depth_luma_minus8 == 1
687                 || picParams->bit_depth_chroma_minus8 == 1
688                 || picParams->bit_depth_luma_minus8 == 2
689                 || picParams->bit_depth_chroma_minus8 == 2) // 10bit
690         {
691             if (picParams->chroma_format_idc == 1) // 420
692             {
693                 Format = Format_P010;
694                 if (rtTbl->pCurrentRT->format == Media_Format_P016 || rtTbl->pCurrentRT->format == Media_Format_P012)
695                 {
696                     Format = Format_P016;
697                 }
698             }
699             else if (picParams->chroma_format_idc == 2) // 422
700             {
701                 Format = Format_Y210;
702 #if VA_CHECK_VERSION(1, 9, 0)
703                 if (rtTbl->pCurrentRT->format == Media_Format_Y216 || rtTbl->pCurrentRT->format == Media_Format_Y212)
704 #else
705                 if (rtTbl->pCurrentRT->format == Media_Format_Y216)
706 #endif
707                 {
708                     Format = Format_Y216;
709                 }
710             }
711             else // 444
712             {
713                 Format = Format_Y410;
714 #if VA_CHECK_VERSION(1, 9, 0)
715                 if (rtTbl->pCurrentRT->format == Media_Format_Y416 || rtTbl->pCurrentRT->format == Media_Format_Y412)
716 #else
717                 if (rtTbl->pCurrentRT->format == Media_Format_Y416)
718 #endif
719                 {
720                     Format = Format_Y416;
721                 }
722             }
723         }
724         else if (picParams->bit_depth_luma_minus8 >= 3
725                 || picParams->bit_depth_chroma_minus8 >= 3) // 12bit
726         {
727             if (picParams->chroma_format_idc == 1) // 420
728             {
729                 Format = Format_P016;
730             }
731             else if (picParams->chroma_format_idc == 2) // 422
732             {
733                 Format = Format_Y216;
734             }
735             else // 444
736             {
737                 Format = Format_Y416;
738             }
739         }
740     }
741     else if (m_ddiDecodeAttr->profile == VAProfileHEVCSccMain10)
742     {
743         // 420 10bit
744         Format = Format_P010;
745     }
746     else if (m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444 ||
747              m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444_10)
748     {
749         // 420/422/444 8bit
750         if ((picParams->bit_depth_luma_minus8 == 0) &&
751             (picParams->bit_depth_chroma_minus8 == 0))
752         {
753             if (picParams->chroma_format_idc == 2)
754             {
755                 Format = Format_YUY2;
756             }
757             else if (picParams->chroma_format_idc == 3)
758             {
759                 Format = Format_AYUV;
760             }
761             else
762             {
763                 Format = Format_NV12;
764             }
765         }
766         else
767         {
768             // 10bit
769             if (picParams->chroma_format_idc == 2)
770             {
771                 Format = Format_Y210;
772             }
773             else if (picParams->chroma_format_idc == 3)
774             {
775                 Format = Format_Y410;
776             }
777             else
778             {
779                 Format = Format_P010;
780             }
781         }
782     }
783 
784     return Format;
785 }
786 
SetDecodeParams()787 VAStatus DdiDecodeHevc::SetDecodeParams()
788 {
789     DDI_CODEC_FUNC_ENTER;
790 
791      DDI_CODEC_CHK_RET(DdiDecodeBase::SetDecodeParams(), "SetDecodeParams failed!");
792      CODEC_HEVC_PIC_PARAMS *picParams = (CODEC_HEVC_PIC_PARAMS *)(&m_decodeCtx->DecodeParams)->m_picParams;
793      // "flat" scaling lists
794      if (picParams->scaling_list_enabled_flag == 0)
795      {
796         PCODECHAL_HEVC_IQ_MATRIX_PARAMS matrixParams = (PCODECHAL_HEVC_IQ_MATRIX_PARAMS)(&m_decodeCtx->DecodeParams)->m_iqMatrixBuffer;
797 
798         memset(matrixParams->ucScalingLists0,
799             0x10,
800             6 * 16 * sizeof(uint8_t));
801 
802         memset(matrixParams->ucScalingLists1,
803             0x10,
804             6 * 64 * sizeof(uint8_t));
805 
806         memset(matrixParams->ucScalingLists2,
807             0x10,
808             6 * 64 * sizeof(uint8_t));
809 
810         memset(matrixParams->ucScalingLists3,
811             0x10,
812             2 * 64 * sizeof(uint8_t));
813 
814         memset(matrixParams->ucScalingListDCCoefSizeID2,
815             0x10,
816             6 * sizeof(uint8_t));
817 
818         memset(matrixParams->ucScalingListDCCoefSizeID3,
819             0x10,
820             2 * sizeof(uint8_t));
821      }
822 #ifdef _DECODE_PROCESSING_SUPPORTED
823         // Bridge the SFC input with vdbox output
824     if (m_decProcessingType == VA_DEC_PROCESSING)
825     {
826         auto procParams = (DecodeProcessingParams *)m_decodeCtx->DecodeParams.m_procParams;
827         procParams->m_inputSurface = (&m_decodeCtx->DecodeParams)->m_destSurface;
828         // codechal_decode_sfc.c expects Input Width/Height information.
829         procParams->m_inputSurface->dwWidth  = procParams->m_inputSurface->OsResource.iWidth;
830         procParams->m_inputSurface->dwHeight = procParams->m_inputSurface->OsResource.iHeight;
831         procParams->m_inputSurface->dwPitch  = procParams->m_inputSurface->OsResource.iPitch;
832         procParams->m_inputSurface->Format   = procParams->m_inputSurface->OsResource.Format;
833 
834         if (m_requireInputRegion)
835         {
836             procParams->m_inputSurfaceRegion.m_x = 0;
837             procParams->m_inputSurfaceRegion.m_y = 0;
838             procParams->m_inputSurfaceRegion.m_width  = procParams->m_inputSurface->dwWidth;
839             procParams->m_inputSurfaceRegion.m_height = procParams->m_inputSurface->dwHeight;
840         }
841     }
842 #endif
843      return VA_STATUS_SUCCESS;
844 }
845 
AllocSliceParamContext(uint32_t numSlices)846 VAStatus DdiDecodeHevc::AllocSliceParamContext(uint32_t numSlices)
847 {
848     DDI_CODEC_FUNC_ENTER;
849 
850     uint32_t baseSize = sizeof(CODEC_HEVC_SLICE_PARAMS);
851 
852     if (m_sliceParamBufNum < (m_decodeCtx->DecodeParams.m_numSlices + numSlices))
853     {
854         // in order to avoid that the buffer is reallocated multi-times,
855         // extra 10 slices are added.
856         uint32_t extraSlices = numSlices + 10;
857 
858         m_decodeCtx->DecodeParams.m_sliceParams = realloc(m_decodeCtx->DecodeParams.m_sliceParams,
859             baseSize * (m_sliceParamBufNum + extraSlices));
860 
861         if (m_decodeCtx->DecodeParams.m_sliceParams == nullptr)
862         {
863             return VA_STATUS_ERROR_ALLOCATION_FAILED;
864         }
865 
866         memset((void *)((uint8_t *)m_decodeCtx->DecodeParams.m_sliceParams + baseSize * m_sliceParamBufNum), 0, baseSize * extraSlices);
867 
868         if (IsRextProfile())
869         {
870             uint32_t rextSize = sizeof(CODEC_HEVC_EXT_SLICE_PARAMS);
871             m_decodeCtx->DecodeParams.m_extSliceParams = realloc(m_decodeCtx->DecodeParams.m_extSliceParams,
872             rextSize * (m_sliceParamBufNum + extraSlices));
873 
874             if (m_decodeCtx->DecodeParams.m_extSliceParams == nullptr)
875             {
876                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
877             }
878 
879             memset((void *)((uint8_t *)m_decodeCtx->DecodeParams.m_extSliceParams + rextSize * m_sliceParamBufNum), 0, rextSize * extraSlices);
880         }
881 
882         m_sliceParamBufNum += extraSlices;
883     }
884 
885     return VA_STATUS_SUCCESS;
886 }
887 
DestroyContext(VADriverContextP ctx)888 void DdiDecodeHevc::DestroyContext(VADriverContextP ctx)
889 {
890     DDI_CODEC_FUNC_ENTER;
891 
892     FreeResourceBuffer();
893     // explicitly call the base function to do the further clean-up
894     DdiDecodeBase::DestroyContext(ctx);
895 
896     return;
897 }
898 
ContextInit(int32_t picWidth,int32_t picHeight)899 void DdiDecodeHevc::ContextInit(
900     int32_t picWidth,
901     int32_t picHeight)
902 {
903     DDI_CODEC_FUNC_ENTER;
904 
905     // call the function in base class to initialize it.
906     DdiDecodeBase::ContextInit(picWidth, picHeight);
907 
908     if (m_ddiDecodeAttr->componentData.data.sliceMode == VA_DEC_SLICE_MODE_BASE)
909     {
910         m_decodeCtx->bShortFormatInUse = true;
911     }
912     m_decodeCtx->wMode = CODECHAL_DECODE_MODE_HEVCVLD;
913 
914     return;
915 }
916 
InitResourceBuffer()917 VAStatus DdiDecodeHevc::InitResourceBuffer()
918 {
919     DDI_CODEC_FUNC_ENTER;
920 
921     VAStatus vaStatus = VA_STATUS_SUCCESS;
922 
923     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_decodeCtx->BufMgr);
924     bufMgr->pSliceData = nullptr;
925 
926     bufMgr->ui64BitstreamOrder = 0;
927 
928     if (m_width * m_height < CODEC_720P_MAX_PIC_WIDTH * CODEC_720P_MAX_PIC_HEIGHT)
929     {
930         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 2;
931     }
932     else if (m_width * m_height < CODEC_4K_MAX_PIC_WIDTH * CODEC_4K_MAX_PIC_HEIGHT)
933     {
934         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 8;
935     }
936     else
937     {
938         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 16;
939     }
940 
941     // minimal 10k bytes for some special case. Will refractor this later
942     if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
943     {
944         bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
945     }
946 
947     int32_t i;
948     // init decode bitstream buffer object
949     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
950     {
951         bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
952         if (bufMgr->pBitStreamBuffObject[i] == nullptr)
953         {
954             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
955             FreeResourceBuffer();
956             return vaStatus;
957         }
958         bufMgr->pBitStreamBuffObject[i]->iSize    = bufMgr->dwMaxBsSize;
959         bufMgr->pBitStreamBuffObject[i]->uiType   = VASliceDataBufferType;
960         bufMgr->pBitStreamBuffObject[i]->format   = Media_Format_Buffer;
961         bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
962         bufMgr->pBitStreamBuffObject[i]->bo       = nullptr;
963         bufMgr->pBitStreamBase[i]                 = nullptr;
964     }
965 
966     // The pSliceData can be allocated on demand. So the default size is wPicHeightInLCU.
967     // Currently the LCU32 is used.
968     bufMgr->m_maxNumSliceData = MOS_ALIGN_CEIL(m_height, 32) / 32;
969     bufMgr->pSliceData        = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) *
970                                  bufMgr->m_maxNumSliceData);
971 
972     if (bufMgr->pSliceData == nullptr)
973     {
974         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
975         FreeResourceBuffer();
976         return vaStatus;
977     }
978 
979     bufMgr->dwNumSliceData    = 0;
980     bufMgr->dwNumSliceControl = 0;
981 
982     /* as it can be increased on demand, the initial number will be based on LCU32 */
983     m_sliceCtrlBufNum = MOS_ALIGN_CEIL(m_height, 32) / 32;
984 
985     if (m_decodeCtx->bShortFormatInUse)
986     {
987         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC =
988             (VASliceParameterBufferBase *)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferBase) * m_sliceCtrlBufNum);
989         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC == nullptr)
990         {
991             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
992             FreeResourceBuffer();
993             return vaStatus;
994         }
995     }
996     else if (!IsRextProfile())
997     {
998         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC =
999             (VASliceParameterBufferHEVC *)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferHEVC) * m_sliceCtrlBufNum);
1000         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC == nullptr)
1001         {
1002             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1003             FreeResourceBuffer();
1004             return vaStatus;
1005         }
1006     }
1007     else
1008     {
1009         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext =
1010             (VASliceParameterBufferHEVCExtension*)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferHEVCExtension) * m_sliceCtrlBufNum);
1011         if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext == nullptr)
1012         {
1013             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1014             FreeResourceBuffer();
1015             return vaStatus;
1016         }
1017     }
1018 
1019     return VA_STATUS_SUCCESS;
1020 }
1021 
FreeResourceBuffer()1022 void DdiDecodeHevc::FreeResourceBuffer()
1023 {
1024     DDI_CODEC_FUNC_ENTER;
1025 
1026     DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_decodeCtx->BufMgr);
1027 
1028     int32_t i = 0;
1029     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
1030     {
1031         if (bufMgr->pBitStreamBase[i])
1032         {
1033             MediaLibvaUtilNext::UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
1034             bufMgr->pBitStreamBase[i] = nullptr;
1035         }
1036         if (bufMgr->pBitStreamBuffObject[i])
1037         {
1038             MediaLibvaUtilNext::FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
1039             MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
1040             bufMgr->pBitStreamBuffObject[i] = nullptr;
1041         }
1042     }
1043 
1044     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC)
1045     {
1046         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC);
1047         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC = nullptr;
1048     }
1049     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC)
1050     {
1051         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC);
1052         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC = nullptr;
1053     }
1054     if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext)
1055     {
1056         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext);
1057         bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext = nullptr;
1058     }
1059 
1060     // free decode bitstream buffer object
1061     MOS_FreeMemory(bufMgr->pSliceData);
1062     bufMgr->pSliceData = nullptr;
1063 
1064     return;
1065 }
1066 
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)1067 uint8_t* DdiDecodeHevc::GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR *bufMgr)
1068 {
1069     DDI_CODEC_FUNC_ENTER;
1070 
1071     if (!IsRextProfile())
1072     {
1073         return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_HEVC.PicParamHEVC));
1074     }
1075     else
1076     {
1077         return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_HEVC.PicParamHEVCRext));
1078     }
1079 }
1080 
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)1081 VAStatus DdiDecodeHevc::AllocSliceControlBuffer(DDI_MEDIA_BUFFER *buf)
1082 {
1083     DDI_CODEC_FUNC_ENTER;
1084 
1085     DDI_CODEC_COM_BUFFER_MGR *bufMgr   = nullptr;
1086     uint32_t                 availSize = 0;
1087     uint32_t                 newSize   = 0;
1088 
1089     bufMgr    = &(m_decodeCtx->BufMgr);
1090     availSize = m_sliceCtrlBufNum - bufMgr->dwNumSliceControl;
1091 
1092     if (buf->uiNumElements < 1 || buf->iSize < 1)
1093         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1094 
1095     if (m_decodeCtx->bShortFormatInUse)
1096     {
1097         if (availSize < buf->uiNumElements)
1098         {
1099             if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferBase))
1100                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1101 
1102             newSize = sizeof(VASliceParameterBufferBase) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
1103             bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC = (VASliceParameterBufferBase *)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC, newSize);
1104             if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC == nullptr)
1105             {
1106                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1107             }
1108             MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferBase) * (buf->uiNumElements - availSize));
1109             m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
1110         }
1111         buf->pData    = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC;
1112         buf->uiOffset = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferBase);
1113     }
1114     else
1115     {
1116         if (!IsRextProfile())
1117         {
1118             if (availSize < buf->uiNumElements)
1119             {
1120                 if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferHEVC))
1121                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
1122 
1123                 newSize = sizeof(VASliceParameterBufferHEVC) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
1124                 bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC = (VASliceParameterBufferHEVC *)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC, newSize);
1125                 if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC == nullptr)
1126                 {
1127                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
1128                 }
1129                 MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferHEVC) * (buf->uiNumElements - availSize));
1130                 m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
1131             }
1132             buf->pData    = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC;
1133             buf->uiOffset = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferHEVC);
1134         }
1135         else
1136         {
1137             if (availSize < buf->uiNumElements)
1138             {
1139                 if (buf->iSize / buf->uiNumElements != sizeof(VASliceParameterBufferHEVCExtension))
1140                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
1141 
1142                 newSize = sizeof(VASliceParameterBufferHEVCExtension) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
1143                 bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext= (VASliceParameterBufferHEVCExtension*)realloc(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext, newSize);
1144                 if (bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext == nullptr)
1145                 {
1146                     return VA_STATUS_ERROR_ALLOCATION_FAILED;
1147                 }
1148                 MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext+ m_sliceCtrlBufNum, sizeof(VASliceParameterBufferHEVCExtension) * (buf->uiNumElements - availSize));
1149                 m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
1150             }
1151             buf->pData    = (uint8_t*)bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext;
1152             buf->uiOffset = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferHEVCExtension);
1153         }
1154     }
1155 
1156     bufMgr->dwNumSliceControl += buf->uiNumElements;
1157 
1158     return VA_STATUS_SUCCESS;
1159 }
1160 
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)1161 VAStatus DdiDecodeHevc::CodecHalInit(
1162     DDI_MEDIA_CONTEXT *mediaCtx,
1163     void              *ptr)
1164 {
1165     DDI_CODEC_FUNC_ENTER;
1166 
1167     VAStatus    vaStatus = VA_STATUS_SUCCESS;
1168     MOS_CONTEXT *mosCtx  = (MOS_CONTEXT *)ptr;
1169 
1170     CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
1171     m_decodeCtx->pCpDdiInterfaceNext->SetCpParams(m_ddiDecodeAttr->componentData.data.encryptType, m_codechalSettings);
1172 
1173     CODECHAL_STANDARD_INFO standardInfo;
1174     memset(&standardInfo, 0, sizeof(standardInfo));
1175 
1176     standardInfo.CodecFunction = codecFunction;
1177     standardInfo.Mode          = (CODECHAL_MODE)m_decodeCtx->wMode;
1178 
1179     m_codechalSettings->codecFunction = codecFunction;
1180     m_codechalSettings->width         = m_width;
1181     m_codechalSettings->height        = m_height;
1182     m_codechalSettings->intelEntrypointInUse = false;
1183 
1184     m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
1185     if (m_ddiDecodeAttr->profile == VAProfileHEVCMain10     ||
1186         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 ||
1187         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10 ||
1188         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain10  ||
1189         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10)
1190     {
1191         m_codechalSettings->lumaChromaDepth |= CODECHAL_LUMA_CHROMA_DEPTH_10_BITS;
1192     }
1193 
1194     m_codechalSettings->shortFormatInUse = m_decodeCtx->bShortFormatInUse;
1195 
1196     m_codechalSettings->mode         = CODECHAL_DECODE_MODE_HEVCVLD;
1197     m_codechalSettings->standard     = CODECHAL_HEVC;
1198     m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV420;
1199 
1200     if (m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 ||
1201        m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12)
1202     {
1203         m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV422;
1204     }
1205 
1206     if (m_ddiDecodeAttr->profile == VAProfileHEVCMain444    ||
1207         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10 ||
1208         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12 ||
1209         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444 ||
1210         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444_10)
1211     {
1212         m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV444;
1213     }
1214 
1215     m_decodeCtx->DecodeParams.m_iqMatrixBuffer = MOS_AllocAndZeroMemory(sizeof(CODECHAL_HEVC_IQ_MATRIX_PARAMS));
1216     if (m_decodeCtx->DecodeParams.m_iqMatrixBuffer == nullptr)
1217     {
1218         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1219         goto CleanUpandReturn;
1220     }
1221     m_decodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_PIC_PARAMS));
1222     if (m_decodeCtx->DecodeParams.m_picParams == nullptr)
1223     {
1224         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1225         goto CleanUpandReturn;
1226     }
1227     if (IsRextProfile())
1228     {
1229         m_decodeCtx->DecodeParams.m_extPicParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_EXT_PIC_PARAMS));
1230         if (m_decodeCtx->DecodeParams.m_extPicParams == nullptr)
1231         {
1232             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1233             goto CleanUpandReturn;
1234         }
1235 
1236         if (IsSccProfile())
1237         {
1238             m_decodeCtx->DecodeParams.m_advPicParams = MOS_AllocAndZeroMemory(sizeof(CODEC_HEVC_SCC_PIC_PARAMS));
1239             if (m_decodeCtx->DecodeParams.m_advPicParams == nullptr)
1240             {
1241                 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1242                 goto CleanUpandReturn;
1243             }
1244         }
1245     }
1246 
1247     m_sliceParamBufNum = m_picHeightInMB;
1248     m_decodeCtx->DecodeParams.m_sliceParams = MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_HEVC_SLICE_PARAMS));
1249     if (m_decodeCtx->DecodeParams.m_sliceParams == nullptr)
1250     {
1251         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1252         goto CleanUpandReturn;
1253     }
1254 
1255     if (IsRextProfile())
1256     {
1257         m_decodeCtx->DecodeParams.m_extSliceParams = MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_HEVC_EXT_SLICE_PARAMS));
1258         if (m_decodeCtx->DecodeParams.m_extSliceParams == nullptr)
1259         {
1260             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1261             goto CleanUpandReturn;
1262         }
1263     }
1264 
1265 #ifdef _DECODE_PROCESSING_SUPPORTED
1266     if (m_decProcessingType == VA_DEC_PROCESSING)
1267     {
1268         DecodeProcessingParams *procParams = nullptr;
1269 
1270         m_codechalSettings->downsamplingHinted = true;
1271 
1272         procParams = (DecodeProcessingParams *)MOS_AllocAndZeroMemory(sizeof(DecodeProcessingParams));
1273         if (procParams == nullptr)
1274         {
1275             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1276             goto CleanUpandReturn;
1277         }
1278 
1279         m_decodeCtx->DecodeParams.m_procParams = procParams;
1280         procParams->m_outputSurface = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
1281         if (procParams->m_outputSurface == nullptr)
1282         {
1283             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1284             goto CleanUpandReturn;
1285         }
1286     }
1287 #endif
1288 
1289     vaStatus = CreateCodecHal(mediaCtx,
1290         ptr,
1291         &standardInfo);
1292 
1293     if (vaStatus != VA_STATUS_SUCCESS)
1294     {
1295         goto CleanUpandReturn;
1296     }
1297 
1298     if (InitResourceBuffer() != VA_STATUS_SUCCESS)
1299     {
1300         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1301         goto CleanUpandReturn;
1302     }
1303 
1304     return vaStatus;
1305 
1306 CleanUpandReturn:
1307     FreeResourceBuffer();
1308 
1309     if (m_decodeCtx->pCodecHal)
1310     {
1311         m_decodeCtx->pCodecHal->Destroy();
1312         MOS_Delete(m_decodeCtx->pCodecHal);
1313         m_decodeCtx->pCodecHal = nullptr;
1314     }
1315 
1316     MOS_FreeMemory(m_decodeCtx->DecodeParams.m_iqMatrixBuffer);
1317     m_decodeCtx->DecodeParams.m_iqMatrixBuffer = nullptr;
1318     MOS_FreeMemory(m_decodeCtx->DecodeParams.m_picParams);
1319     m_decodeCtx->DecodeParams.m_picParams = nullptr;
1320     MOS_FreeMemory(m_decodeCtx->DecodeParams.m_huffmanTable);
1321     m_decodeCtx->DecodeParams.m_huffmanTable = nullptr;
1322     MOS_FreeMemory(m_decodeCtx->DecodeParams.m_sliceParams);
1323     m_decodeCtx->DecodeParams.m_sliceParams = nullptr;
1324 
1325 #ifdef _DECODE_PROCESSING_SUPPORTED
1326     if (m_decodeCtx->DecodeParams.m_procParams)
1327     {
1328         auto procParams =
1329             (DecodeProcessingParams *)m_decodeCtx->DecodeParams.m_procParams;
1330         MOS_FreeMemory(procParams->m_outputSurface);
1331 
1332         MOS_FreeMemory(m_decodeCtx->DecodeParams.m_procParams);
1333         m_decodeCtx->DecodeParams.m_procParams = nullptr;
1334     }
1335 #endif
1336     return vaStatus;
1337 }
1338 
IsRextProfile()1339 bool DdiDecodeHevc::IsRextProfile()
1340 {
1341     DDI_CODEC_FUNC_ENTER;
1342 
1343     return (                                                   \
1344         m_ddiDecodeAttr->profile == VAProfileHEVCMain12     || \
1345         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_10 || \
1346         m_ddiDecodeAttr->profile == VAProfileHEVCMain422_12 || \
1347         m_ddiDecodeAttr->profile == VAProfileHEVCMain444    || \
1348         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_10 || \
1349         m_ddiDecodeAttr->profile == VAProfileHEVCMain444_12 || \
1350         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain    || \
1351         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain10  || \
1352         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444 || \
1353         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444_10 \
1354     );
1355 }
1356 
IsSccProfile()1357 bool DdiDecodeHevc::IsSccProfile()
1358 {
1359     DDI_CODEC_FUNC_ENTER;
1360 
1361     return (                                                   \
1362         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain    || \
1363         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain10  || \
1364         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444 || \
1365         m_ddiDecodeAttr->profile == VAProfileHEVCSccMain444_10 \
1366     );
1367 }
1368 
SetupCodecPicture(DDI_MEDIA_CONTEXT * mediaCtx,DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,CODEC_PICTURE * codecHalPic,VAPictureHEVC vaPic,bool fieldPicFlag,bool bottomFieldFlag,bool picReference)1369 void DdiDecodeHevc::SetupCodecPicture(
1370     DDI_MEDIA_CONTEXT              *mediaCtx,
1371     DDI_CODEC_RENDER_TARGET_TABLE  *rtTbl,
1372     CODEC_PICTURE                  *codecHalPic,
1373     VAPictureHEVC                  vaPic,
1374     bool                           fieldPicFlag,
1375     bool                           bottomFieldFlag,
1376     bool                           picReference)
1377 {
1378     DDI_CODEC_FUNC_ENTER;
1379 
1380     if (vaPic.picture_id != VA_INVALID_SURFACE)
1381     {
1382         DDI_MEDIA_SURFACE *surface = MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, vaPic.picture_id);
1383         codecHalPic->FrameIdx = GetRenderTargetID(rtTbl, surface);
1384     }
1385     else
1386     {
1387         codecHalPic->FrameIdx = (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX;
1388     }
1389 
1390     if (picReference)
1391     {
1392         if (codecHalPic->FrameIdx == (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX)
1393         {
1394             codecHalPic->PicFlags = PICTURE_INVALID;
1395         }
1396         else if (vaPic.flags & VA_PICTURE_HEVC_LONG_TERM_REFERENCE)
1397         {
1398             codecHalPic->PicFlags = PICTURE_LONG_TERM_REFERENCE;
1399         }
1400         else
1401         {
1402             codecHalPic->PicFlags = PICTURE_SHORT_TERM_REFERENCE;
1403         }
1404     }
1405     else
1406     {
1407         if (fieldPicFlag)
1408         {
1409             if (bottomFieldFlag)
1410             {
1411                 codecHalPic->PicFlags = PICTURE_BOTTOM_FIELD;
1412             }
1413             else
1414             {
1415                 codecHalPic->PicFlags = PICTURE_TOP_FIELD;
1416             }
1417         }
1418         else
1419         {
1420             codecHalPic->PicFlags = PICTURE_FRAME;
1421         }
1422     }
1423 
1424     return;
1425 }
1426 
1427 } // namespace decode
1428