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