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