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