xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/codec/ddi/media_ddi_decode_avc.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2017-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_avc.cpp
24 //! \brief    The class implementation of DdiDecodeAVC  for Avc decode
25 //!
26 
27 #include "media_libva_decoder.h"
28 #include "media_libva_util.h"
29 #include "media_ddi_decode_avc.h"
30 #include "mos_solo_generic.h"
31 #include "codechal_memdecomp.h"
32 #include "media_ddi_decode_const.h"
33 #include "media_ddi_factory.h"
34 #include "media_factory.h"
35 
ParseSliceParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferH264 * slcParam,uint32_t numSlices)36 VAStatus DdiDecodeAVC::ParseSliceParams(
37     DDI_MEDIA_CONTEXT           *mediaCtx,
38     VASliceParameterBufferH264  *slcParam,
39     uint32_t                     numSlices)
40 {
41     PCODEC_AVC_SLICE_PARAMS avcSliceParams;
42     avcSliceParams = (PCODEC_AVC_SLICE_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
43     avcSliceParams += m_ddiDecodeCtx->DecodeParams.m_numSlices;
44 
45     if ((slcParam == nullptr) || (avcSliceParams == nullptr))
46     {
47         DDI_ASSERTMESSAGE("Invalid Parameter for Parsing AVC Slice parameter\n");
48         return VA_STATUS_ERROR_INVALID_PARAMETER;
49     }
50     VASliceParameterBufferH264 *slc;
51     slc = (VASliceParameterBufferH264 *)slcParam;
52 
53     VASliceParameterBufferBase *slcBase;
54     slcBase = (VASliceParameterBufferBase *)slcParam;
55 
56     PCODEC_AVC_PIC_PARAMS avcPicParams;
57     avcPicParams                          = (PCODEC_AVC_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_picParams);
58     avcPicParams->pic_fields.IntraPicFlag = (slc->slice_type == 2) ? 1 : 0;
59 
60     bool useCABAC = (bool)(avcPicParams->pic_fields.entropy_coding_mode_flag);
61 
62     uint32_t sliceBaseOffset;
63     sliceBaseOffset = GetBsBufOffset(m_groupIndex);
64 
65     uint32_t i, slcCount, refCount;
66     for (slcCount = 0; slcCount < numSlices; slcCount++)
67     {
68         if (m_ddiDecodeCtx->bShortFormatInUse)
69         {
70             avcSliceParams->slice_data_size   = slcBase->slice_data_size;
71             avcSliceParams->slice_data_offset = sliceBaseOffset +
72                                                 slcBase->slice_data_offset;
73             if (slcBase->slice_data_flag)
74             {
75                 DDI_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
76             }
77             slcBase++;
78         }
79         else
80         {
81             if (useCABAC)
82             {
83                 // add the alignment bit
84                 slc->slice_data_bit_offset = MOS_ALIGN_CEIL(slc->slice_data_bit_offset, 8);
85             }
86 
87             // remove 1 byte of NAL unit code
88             slc->slice_data_bit_offset = slc->slice_data_bit_offset - 8;
89 
90             avcSliceParams->slice_data_size   = slc->slice_data_size;
91             avcSliceParams->slice_data_offset = sliceBaseOffset +
92                                                 slc->slice_data_offset;
93             if (slc->slice_data_flag)
94             {
95                 DDI_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
96             }
97 
98             avcSliceParams->slice_data_bit_offset         = slc->slice_data_bit_offset;
99             avcSliceParams->first_mb_in_slice             = slc->first_mb_in_slice;
100             avcSliceParams->NumMbsForSlice                = 0;  // not in LibVA slc->NumMbsForSlice;
101             avcSliceParams->slice_type                    = slc->slice_type;
102             avcSliceParams->direct_spatial_mv_pred_flag   = slc->direct_spatial_mv_pred_flag;
103             avcSliceParams->num_ref_idx_l0_active_minus1  = slc->num_ref_idx_l0_active_minus1;
104             avcSliceParams->num_ref_idx_l1_active_minus1  = slc->num_ref_idx_l1_active_minus1;
105             if(slcCount == 0)
106             {
107                 avcPicParams->num_ref_idx_l0_active_minus1 = avcSliceParams->num_ref_idx_l0_active_minus1;
108                 avcPicParams->num_ref_idx_l1_active_minus1 = avcSliceParams->num_ref_idx_l1_active_minus1;
109             }
110             avcSliceParams->cabac_init_idc                = slc->cabac_init_idc;
111             avcSliceParams->slice_qp_delta                = slc->slice_qp_delta;
112             avcSliceParams->disable_deblocking_filter_idc = slc->disable_deblocking_filter_idc;
113             avcSliceParams->slice_alpha_c0_offset_div2    = slc->slice_alpha_c0_offset_div2;
114             avcSliceParams->slice_beta_offset_div2        = slc->slice_beta_offset_div2;
115             // reference list 0
116             refCount = std::min(avcSliceParams->num_ref_idx_l0_active_minus1 + 1, CODEC_MAX_NUM_REF_FIELD);
117             for (i = 0; i < refCount; i++)
118             {
119                 SetupCodecPicture(
120                     mediaCtx,
121                     &(m_ddiDecodeCtx->RTtbl),
122                     &(avcSliceParams->RefPicList[0][i]),
123                     slc->RefPicList0[i],
124                     avcPicParams->pic_fields.field_pic_flag,
125                     false,
126                     true);
127 
128                 GetSlcRefIdx(&(avcPicParams->RefFrameList[0]), &(avcSliceParams->RefPicList[0][i]));
129             }
130             // reference list 1
131             refCount = std::min(avcSliceParams->num_ref_idx_l1_active_minus1 + 1, CODEC_MAX_NUM_REF_FIELD);
132             for (i = 0; i < refCount; i++)
133             {
134                 SetupCodecPicture(
135                     mediaCtx,
136                     &(m_ddiDecodeCtx->RTtbl),
137                     &(avcSliceParams->RefPicList[1][i]),
138                     slc->RefPicList1[i],
139                     avcPicParams->pic_fields.field_pic_flag,
140                     false,
141                     true);
142 
143                 GetSlcRefIdx(&(avcPicParams->RefFrameList[0]), &(avcSliceParams->RefPicList[1][i]));
144             }
145 
146             avcSliceParams->luma_log2_weight_denom   = slc->luma_log2_weight_denom;
147             avcSliceParams->chroma_log2_weight_denom = slc->chroma_log2_weight_denom;
148             for (i = 0; i < 32; i++)
149             {
150                 // list 0
151                 avcSliceParams->Weights[0][i][0][0] = slc->luma_weight_l0[i];  // Y weight
152                 avcSliceParams->Weights[0][i][0][1] = slc->luma_offset_l0[i];  // Y offset
153 
154                 avcSliceParams->Weights[0][i][1][0] = slc->chroma_weight_l0[i][0];  // Cb weight
155                 avcSliceParams->Weights[0][i][1][1] = slc->chroma_offset_l0[i][0];  // Cb offset
156 
157                 avcSliceParams->Weights[0][i][2][0] = slc->chroma_weight_l0[i][1];  // Cr weight
158                 avcSliceParams->Weights[0][i][2][1] = slc->chroma_offset_l0[i][1];  // Cr offset
159 
160                 // list 1
161                 avcSliceParams->Weights[1][i][0][0] = slc->luma_weight_l1[i];  // Y weight
162                 avcSliceParams->Weights[1][i][0][1] = slc->luma_offset_l1[i];  // Y offset
163 
164                 avcSliceParams->Weights[1][i][1][0] = slc->chroma_weight_l1[i][0];  // Cb weight
165                 avcSliceParams->Weights[1][i][1][1] = slc->chroma_offset_l1[i][0];  // Cb offset
166 
167                 avcSliceParams->Weights[1][i][2][0] = slc->chroma_weight_l1[i][1];  // Cr weight
168                 avcSliceParams->Weights[1][i][2][1] = slc->chroma_offset_l1[i][1];  // Cr offset
169             }
170             slc++;
171         }
172         avcSliceParams->slice_id = 0;
173         avcSliceParams++;
174     }
175 
176     return VA_STATUS_SUCCESS;
177 }
178 
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VAPictureParameterBufferH264 * picParam)179 VAStatus DdiDecodeAVC::ParsePicParams(
180     DDI_MEDIA_CONTEXT *           mediaCtx,
181     VAPictureParameterBufferH264 *picParam)
182 {
183     PCODEC_AVC_PIC_PARAMS avcPicParams;
184     avcPicParams = (PCODEC_AVC_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_picParams);
185 
186     if ((picParam == nullptr) ||
187         (avcPicParams == nullptr))
188         return VA_STATUS_ERROR_INVALID_PARAMETER;
189 
190     SetupCodecPicture(mediaCtx,
191         &(m_ddiDecodeCtx->RTtbl),
192         &avcPicParams->CurrPic,
193         picParam->CurrPic,
194         picParam->pic_fields.bits.field_pic_flag,
195         false,
196         false);
197 
198     //Check the current frame index
199     //Add the invalid surface id to RecList
200     if (avcPicParams->CurrPic.FrameIdx < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE)
201     {
202         m_ddiDecodeCtx->RecListSurfaceID[avcPicParams->CurrPic.FrameIdx] =
203             picParam->CurrPic.picture_id;
204     }
205 
206     uint32_t i;
207     uint32_t j;
208     avcPicParams->UsedForReferenceFlags = 0x0;
209     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME; i++)
210     {
211         if (picParam->ReferenceFrames[i].picture_id != VA_INVALID_SURFACE)
212         {
213             UpdateRegisteredRTSurfaceFlag(&(m_ddiDecodeCtx->RTtbl),
214                 DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx,
215                     picParam->ReferenceFrames[i].picture_id));
216         }
217 
218         SetupCodecPicture(
219             mediaCtx,
220             &(m_ddiDecodeCtx->RTtbl),
221             &(avcPicParams->RefFrameList[i]),
222             picParam->ReferenceFrames[i],
223             picParam->pic_fields.bits.field_pic_flag,
224             true,
225             false);
226 
227         if ((picParam->ReferenceFrames[i].flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
228             (picParam->ReferenceFrames[i].flags & VA_PICTURE_H264_LONG_TERM_REFERENCE))
229         {
230             if (!m_ddiDecodeCtx->bShortFormatInUse)
231             {
232                 avcPicParams->UsedForReferenceFlags = avcPicParams->UsedForReferenceFlags | (3 << (i * 2));
233             }
234             else if ((picParam->ReferenceFrames[i].flags & VA_PICTURE_H264_BOTTOM_FIELD) ||
235                      (picParam->ReferenceFrames[i].flags & VA_PICTURE_H264_TOP_FIELD))
236             {
237                 if (picParam->ReferenceFrames[i].flags & VA_PICTURE_H264_BOTTOM_FIELD)
238                     avcPicParams->UsedForReferenceFlags = avcPicParams->UsedForReferenceFlags | (2 << (i * 2));
239 
240                 if (picParam->ReferenceFrames[i].flags & VA_PICTURE_H264_TOP_FIELD)
241                     avcPicParams->UsedForReferenceFlags = avcPicParams->UsedForReferenceFlags | (1 << (i * 2));
242             }
243             else
244             {
245                 avcPicParams->UsedForReferenceFlags = avcPicParams->UsedForReferenceFlags | (3 << (i * 2));
246             }
247         }
248     }
249 
250     //Accoding to RecList, if the surface id is invalid, set PicFlags equal to PICTURE_INVALID
251     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME; i++)
252     {
253         //Check the surface id of reference list
254         if (avcPicParams->RefFrameList[i].FrameIdx < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE
255             && VA_INVALID_ID == m_ddiDecodeCtx->RecListSurfaceID[avcPicParams->RefFrameList[i].FrameIdx])
256         {
257             //Set invalid flag
258             avcPicParams->RefFrameList[i].PicFlags = PICTURE_INVALID;
259         }
260     }
261 
262     avcPicParams->pic_width_in_mbs_minus1      = picParam->picture_width_in_mbs_minus1;
263     avcPicParams->pic_height_in_mbs_minus1     = picParam->picture_height_in_mbs_minus1;
264     avcPicParams->bit_depth_luma_minus8        = picParam->bit_depth_luma_minus8;
265     avcPicParams->bit_depth_chroma_minus8      = picParam->bit_depth_chroma_minus8;
266     avcPicParams->num_ref_frames               = picParam->num_ref_frames;
267     avcPicParams->CurrFieldOrderCnt[0]         = picParam->CurrPic.TopFieldOrderCnt;
268     avcPicParams->CurrFieldOrderCnt[1]         = picParam->CurrPic.BottomFieldOrderCnt;
269     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME; i++)
270     {
271         avcPicParams->FieldOrderCntList[i][0] = picParam->ReferenceFrames[i].TopFieldOrderCnt;
272         avcPicParams->FieldOrderCntList[i][1] = picParam->ReferenceFrames[i].BottomFieldOrderCnt;
273     }
274 
275     avcPicParams->seq_fields.chroma_format_idc                 = picParam->seq_fields.bits.chroma_format_idc;
276     avcPicParams->seq_fields.residual_colour_transform_flag    = picParam->seq_fields.bits.residual_colour_transform_flag;
277     avcPicParams->seq_fields.frame_mbs_only_flag               = picParam->seq_fields.bits.frame_mbs_only_flag;
278     avcPicParams->seq_fields.mb_adaptive_frame_field_flag      = picParam->seq_fields.bits.mb_adaptive_frame_field_flag;
279     avcPicParams->seq_fields.direct_8x8_inference_flag         = picParam->seq_fields.bits.direct_8x8_inference_flag;
280     avcPicParams->seq_fields.log2_max_frame_num_minus4         = picParam->seq_fields.bits.log2_max_frame_num_minus4;
281     avcPicParams->seq_fields.pic_order_cnt_type                = picParam->seq_fields.bits.pic_order_cnt_type;
282     avcPicParams->seq_fields.log2_max_pic_order_cnt_lsb_minus4 = picParam->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4;
283     avcPicParams->seq_fields.delta_pic_order_always_zero_flag  = picParam->seq_fields.bits.delta_pic_order_always_zero_flag;
284 
285     avcPicParams->num_slice_groups_minus1        = 0;
286     avcPicParams->slice_group_map_type           = 0;
287     avcPicParams->slice_group_change_rate_minus1 = 0;
288     avcPicParams->pic_init_qp_minus26            = picParam->pic_init_qp_minus26;
289     avcPicParams->chroma_qp_index_offset         = picParam->chroma_qp_index_offset;
290     avcPicParams->second_chroma_qp_index_offset  = picParam->second_chroma_qp_index_offset;
291 
292     avcPicParams->pic_fields.entropy_coding_mode_flag               = picParam->pic_fields.bits.entropy_coding_mode_flag;
293     avcPicParams->pic_fields.weighted_pred_flag                     = picParam->pic_fields.bits.weighted_pred_flag;
294     avcPicParams->pic_fields.weighted_bipred_idc                    = picParam->pic_fields.bits.weighted_bipred_idc;
295     avcPicParams->pic_fields.transform_8x8_mode_flag                = picParam->pic_fields.bits.transform_8x8_mode_flag;
296     avcPicParams->pic_fields.field_pic_flag                         = picParam->pic_fields.bits.field_pic_flag;
297     avcPicParams->pic_fields.constrained_intra_pred_flag            = picParam->pic_fields.bits.constrained_intra_pred_flag;
298     avcPicParams->pic_fields.pic_order_present_flag                 = picParam->pic_fields.bits.pic_order_present_flag;
299     avcPicParams->pic_fields.deblocking_filter_control_present_flag = picParam->pic_fields.bits.deblocking_filter_control_present_flag;
300     avcPicParams->pic_fields.redundant_pic_cnt_present_flag         = picParam->pic_fields.bits.redundant_pic_cnt_present_flag;
301     avcPicParams->pic_fields.reference_pic_flag                     = picParam->pic_fields.bits.reference_pic_flag;
302 
303     for (i = 0; i < CODEC_MAX_NUM_REF_FRAME; i++)
304     {
305         avcPicParams->FrameNumList[i] = picParam->ReferenceFrames[i].frame_idx;
306     }
307 
308     avcPicParams->frame_num = picParam->frame_num;
309 
310 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
311     // Picture Info
312     DECODE_EVENTDATA_INFO_PICTUREVA eventData = {0};
313     eventData.CodecFormat                   = m_ddiDecodeCtx->wMode;
314     eventData.FrameType                     = avcPicParams->pic_fields.IntraPicFlag == 1 ? I_TYPE : MIXED_TYPE;
315     eventData.PicStruct                     = avcPicParams->CurrPic.PicFlags;  // 1-Top; 2-Bottom; 3-Frame
316     eventData.Width                         = (avcPicParams->pic_width_in_mbs_minus1 + 1) * MACROBLOCK_WIDTH;
317     eventData.Height                        = (avcPicParams->pic_height_in_mbs_minus1 + 1) * MACROBLOCK_HEIGHT;
318     eventData.Bitdepth                      = avcPicParams->bit_depth_luma_minus8 + 8;
319     eventData.ChromaFormat                  = avcPicParams->seq_fields.chroma_format_idc;  // 0-4:0:0; 1-4:2:0; 2-4:2:2; 3-4:4:4
320     MOS_TraceEvent(EVENT_DECODE_INFO_PICTUREVA, EVENT_TYPE_INFO, &eventData, sizeof(eventData), NULL, 0);
321 #endif
322 
323     return VA_STATUS_SUCCESS;
324 }
325 
ParseIQMatrix(DDI_MEDIA_CONTEXT * mediaCtx,VAIQMatrixBufferH264 * matrix)326 VAStatus DdiDecodeAVC::ParseIQMatrix(
327     DDI_MEDIA_CONTEXT *   mediaCtx,
328     VAIQMatrixBufferH264 *matrix)
329 {
330     PCODEC_AVC_IQ_MATRIX_PARAMS avcIqMatrix;
331 
332     avcIqMatrix = (PCODEC_AVC_IQ_MATRIX_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer);
333 
334     if ((matrix == nullptr) || (avcIqMatrix == nullptr))
335     {
336         DDI_ASSERTMESSAGE("Invalid Parameter for Parsing AVC IQMatrix parameter\n");
337         return VA_STATUS_ERROR_INVALID_PARAMETER;
338     }
339     // 4x4 block
340     int32_t i;
341     for (i = 0; i < 6; i++)
342     {
343         MOS_SecureMemcpy(avcIqMatrix->ScalingList4x4[i],
344             16,
345             matrix->ScalingList4x4[i],
346             16);
347     }
348     // 8x8 block
349     for (i = 0; i < 2; i++)
350     {
351         MOS_SecureMemcpy(avcIqMatrix->ScalingList8x8[i],
352             64,
353             matrix->ScalingList8x8[i],
354             64);
355     }
356     return VA_STATUS_SUCCESS;
357 }
358 
AllocSliceParamContext(uint32_t numSlices)359 VAStatus DdiDecodeAVC::AllocSliceParamContext(
360     uint32_t numSlices)
361 {
362     uint32_t baseSize = sizeof(CODEC_AVC_SLICE_PARAMS);
363 
364     if (m_sliceParamBufNum < (m_ddiDecodeCtx->DecodeParams.m_numSlices + numSlices))
365     {
366         // in order to avoid that the buffer is reallocated multi-times,
367         // extra 10 slices are added.
368         uint32_t extraSlices                           = numSlices + 10;
369         m_ddiDecodeCtx->DecodeParams.m_sliceParams = realloc(m_ddiDecodeCtx->DecodeParams.m_sliceParams,
370             baseSize * (m_sliceParamBufNum + extraSlices));
371 
372         if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
373         {
374             return VA_STATUS_ERROR_ALLOCATION_FAILED;
375         }
376 
377         memset((void *)((uint8_t *)m_ddiDecodeCtx->DecodeParams.m_sliceParams + baseSize * m_sliceParamBufNum),
378             0,
379             baseSize * extraSlices);
380 
381         m_sliceParamBufNum += extraSlices;
382     }
383 
384     return VA_STATUS_SUCCESS;
385 }
386 
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)387 VAStatus DdiDecodeAVC::RenderPicture(
388     VADriverContextP ctx,
389     VAContextID      context,
390     VABufferID *     buffers,
391     int32_t          numBuffers)
392 {
393     VAStatus va = VA_STATUS_SUCCESS;
394 
395     DDI_FUNCTION_ENTER();
396 
397     PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
398     void *            data;
399     for (int32_t i = 0; i < numBuffers; i++)
400     {
401         DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffers[i]);
402         if (nullptr == buf)
403         {
404             return VA_STATUS_ERROR_INVALID_BUFFER;
405         }
406         uint32_t dataSize = buf->iSize;
407 
408         DdiMedia_MapBuffer(ctx, buffers[i], &data);
409 
410         if (data == nullptr)
411         {
412             return VA_STATUS_ERROR_INVALID_BUFFER;
413         }
414 
415         switch ((int32_t)buf->uiType)
416         {
417         case VASliceDataBufferType:
418         {
419             int32_t index = GetBitstreamBufIndexFromBuffer(&m_ddiDecodeCtx->BufMgr, buf);
420             if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
421             {
422                 return VA_STATUS_ERROR_INVALID_BUFFER;
423             }
424 
425             DdiMedia_MediaBufferToMosResource(m_ddiDecodeCtx->BufMgr.pBitStreamBuffObject[index], &m_ddiDecodeCtx->BufMgr.resBitstreamBuffer);
426             m_ddiDecodeCtx->DecodeParams.m_dataSize += dataSize;
427 
428             break;
429         }
430         case VASliceParameterBufferType:
431         {
432             VASliceParameterBufferH264 *slcInfoH264;
433             if (buf->uiNumElements == 0)
434             {
435                 return VA_STATUS_ERROR_INVALID_BUFFER;
436             }
437 
438             slcInfoH264        = (VASliceParameterBufferH264 *)data;
439             uint32_t numSlices = buf->uiNumElements;
440             DDI_CHK_RET(AllocSliceParamContext(numSlices),"AllocSliceParamContext failed!");
441             DDI_CHK_RET(ParseSliceParams(mediaCtx, slcInfoH264, numSlices),"ParseSliceParams failed!");
442             m_ddiDecodeCtx->DecodeParams.m_numSlices += numSlices;
443             m_groupIndex++;
444             break;
445         }
446         case VAIQMatrixBufferType:
447         {
448             VAIQMatrixBufferH264 *imxBuf = (VAIQMatrixBufferH264 *)data;
449             DDI_CHK_RET(ParseIQMatrix(mediaCtx, imxBuf),"ParseIQMatrix failed!");
450             break;
451         }
452         case VAPictureParameterBufferType:
453         {
454             VAPictureParameterBufferH264 *picParam;
455             picParam = (VAPictureParameterBufferH264 *)data;
456             DDI_CHK_RET(ParsePicParams(mediaCtx, picParam),"ParsePicParams failed!");
457             break;
458         }
459         case VAProcPipelineParameterBufferType:
460         {
461             DDI_CHK_RET(ParseProcessingBuffer(mediaCtx, data),"ParseProcessingBuffer failed!");
462             break;
463         }
464         case VADecodeStreamoutBufferType:
465         {
466             DdiMedia_MediaBufferToMosResource(buf, &m_ddiDecodeCtx->BufMgr.resExternalStreamOutBuffer);
467             m_streamOutEnabled = true;
468             break;
469         }
470 
471         default:
472             va = m_ddiDecodeCtx->pCpDdiInterface->RenderCencPicture(ctx, context, buf, data);
473             break;
474         }
475         DdiMedia_UnmapBuffer(ctx, buffers[i]);
476     }
477 
478     DDI_FUNCTION_EXIT(va);
479     return va;
480 }
481 
SetDecodeParams()482 VAStatus DdiDecodeAVC::SetDecodeParams()
483 {
484     DDI_CHK_RET(DdiMediaDecode::SetDecodeParams(),"SetDecodeParams failed!");
485 #ifdef _DECODE_PROCESSING_SUPPORTED
486         // Bridge the SFC input with VDBOX output
487     if (m_decProcessingType == VA_DEC_PROCESSING)
488     {
489         auto procParams =
490             (DecodeProcessingParams *)m_ddiDecodeCtx->DecodeParams.m_procParams;
491         procParams->m_inputSurface = (&m_ddiDecodeCtx->DecodeParams)->m_destSurface;
492         // codechal_decode_sfc.c expects Input Width/Height information.
493         procParams->m_inputSurface->dwWidth  = procParams->m_inputSurface->OsResource.iWidth;
494         procParams->m_inputSurface->dwHeight = procParams->m_inputSurface->OsResource.iHeight;
495         procParams->m_inputSurface->dwPitch  = procParams->m_inputSurface->OsResource.iPitch;
496         procParams->m_inputSurface->Format   = procParams->m_inputSurface->OsResource.Format;
497 
498         if(m_requireInputRegion)
499         {
500             procParams->m_inputSurfaceRegion.m_x = 0;
501             procParams->m_inputSurfaceRegion.m_y = 0;
502             procParams->m_inputSurfaceRegion.m_width = procParams->m_inputSurface->dwWidth;
503             procParams->m_inputSurfaceRegion.m_height = procParams->m_inputSurface->dwHeight;
504         }
505     }
506 #endif
507 
508     return  VA_STATUS_SUCCESS;
509 }
510 
DestroyContext(VADriverContextP ctx)511 void DdiDecodeAVC::DestroyContext(
512     VADriverContextP ctx)
513 {
514     FreeResourceBuffer();
515     // explicitly call the base function to do the further clean-up
516     DdiMediaDecode::DestroyContext(ctx);
517     return;
518 }
519 
ContextInit(int32_t picWidth,int32_t picHeight)520 void DdiDecodeAVC::ContextInit(int32_t picWidth, int32_t picHeight)
521 {
522     // call the function in base class to initialize it.
523     DdiMediaDecode::ContextInit(picWidth, picHeight);
524 
525     if (m_ddiDecodeAttr->uiDecSliceMode == VA_DEC_SLICE_MODE_BASE)
526     {
527         m_ddiDecodeCtx->bShortFormatInUse = true;
528     }
529     m_ddiDecodeCtx->wMode    = CODECHAL_DECODE_MODE_AVCVLD;
530     return;
531 }
532 
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)533 uint8_t* DdiDecodeAVC::GetPicParamBuf(
534     DDI_CODEC_COM_BUFFER_MGR    *bufMgr)
535     {
536          return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_H264.PicParam264));
537     }
538 
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)539 VAStatus DdiDecodeAVC::AllocSliceControlBuffer(
540     DDI_MEDIA_BUFFER       *buf)
541 {
542     DDI_CODEC_COM_BUFFER_MGR   *bufMgr;
543     uint32_t                    availSize;
544     uint32_t                    newSize;
545 
546     bufMgr     = &(m_ddiDecodeCtx->BufMgr);
547     availSize = m_sliceCtrlBufNum - bufMgr->dwNumSliceControl;
548 
549     if(m_ddiDecodeCtx->bShortFormatInUse)
550     {
551         if(availSize < buf->uiNumElements)
552                 {
553             newSize   = sizeof(VASliceParameterBufferBase) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
554             bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base = (VASliceParameterBufferBase *)realloc(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base, newSize);
555             if(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base == nullptr)
556             {
557                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
558             }
559             MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferBase) * (buf->uiNumElements - availSize));
560             m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
561         }
562         buf->pData      = (uint8_t*)bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base;
563         buf->uiOffset   = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferBase);
564     }
565     else
566     {
567         if(availSize < buf->uiNumElements)
568         {
569             newSize   = sizeof(VASliceParameterBufferH264) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
570             bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264 = (VASliceParameterBufferH264 *)realloc(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264, newSize);
571             if(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264 == nullptr)
572             {
573                 return VA_STATUS_ERROR_ALLOCATION_FAILED;
574             }
575             MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264 + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferH264) * (buf->uiNumElements - availSize));
576             m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
577          }
578          buf->pData      = (uint8_t*)bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264;
579          buf->uiOffset   = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferH264);
580       }
581 
582     bufMgr->dwNumSliceControl += buf->uiNumElements;
583 
584     return VA_STATUS_SUCCESS;
585 }
586 
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)587 VAStatus DdiDecodeAVC::CodecHalInit(
588     DDI_MEDIA_CONTEXT  *mediaCtx,
589     void               *ptr)
590 {
591     VAStatus     vaStatus = VA_STATUS_SUCCESS;
592     MOS_CONTEXT *mosCtx = (MOS_CONTEXT *)ptr;
593 
594     m_codechalSettings->shortFormatInUse = m_ddiDecodeCtx->bShortFormatInUse;
595 
596     CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
597 
598     CODECHAL_STANDARD_INFO standardInfo;
599     memset(&standardInfo, 0, sizeof(standardInfo));
600 
601     standardInfo.CodecFunction = codecFunction;
602     standardInfo.Mode          = (CODECHAL_MODE)m_ddiDecodeCtx->wMode;
603 
604     m_codechalSettings->codecFunction = codecFunction;
605     m_codechalSettings->width       = m_width;
606     m_codechalSettings->height      = m_height;
607     //For Avc Decoding:
608     // if the slice header contains the emulation_prevention_three_byte, we need to set bIntelEntrypointInUse to false.
609     // Because in this case, driver can not get the correct BsdStartAddress by itself. We need to turn to GEN to calculate the correct address.
610     m_codechalSettings->intelEntrypointInUse = false;
611 
612     m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
613 
614     m_codechalSettings->mode     = CODECHAL_DECODE_MODE_AVCVLD;
615     m_codechalSettings->standard = CODECHAL_AVC;
616 
617     m_ddiDecodeCtx->pCpDdiInterface->SetCpParams(m_ddiDecodeAttr->uiEncryptionType, m_codechalSettings);
618 
619     m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer = (void*)MOS_AllocAndZeroMemory(sizeof(CODEC_AVC_IQ_MATRIX_PARAMS));
620     if (m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer == nullptr)
621     {
622         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
623         goto CleanUpandReturn;
624     }
625     m_ddiDecodeCtx->DecodeParams.m_picParams = (void*)MOS_AllocAndZeroMemory(sizeof(CODEC_AVC_PIC_PARAMS));
626     if (m_ddiDecodeCtx->DecodeParams.m_picParams == nullptr)
627     {
628         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
629         goto CleanUpandReturn;
630     }
631 
632     m_sliceParamBufNum        = m_picHeightInMB;
633     m_ddiDecodeCtx->DecodeParams.m_sliceParams = (void*)MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_AVC_SLICE_PARAMS));
634     if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
635     {
636         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
637         goto CleanUpandReturn;
638     }
639 
640 #ifdef _DECODE_PROCESSING_SUPPORTED
641     if (m_decProcessingType == VA_DEC_PROCESSING)
642     {
643         DecodeProcessingParams *procParams = nullptr;
644 
645         m_codechalSettings->downsamplingHinted = true;
646 
647         procParams = (DecodeProcessingParams *)MOS_AllocAndZeroMemory(sizeof(DecodeProcessingParams));
648         if (procParams == nullptr)
649         {
650             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
651             goto CleanUpandReturn;
652         }
653 
654         m_ddiDecodeCtx->DecodeParams.m_procParams = procParams;
655         procParams->m_outputSurface               = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
656         if (procParams->m_outputSurface == nullptr)
657         {
658             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
659             goto CleanUpandReturn;
660         }
661     }
662 #endif
663     vaStatus = CreateCodecHal(mediaCtx,
664                                  ptr,
665                                  &standardInfo);
666 
667     if (vaStatus != VA_STATUS_SUCCESS)
668     {
669         goto CleanUpandReturn;
670     }
671 
672     if (InitResourceBuffer() != VA_STATUS_SUCCESS)
673     {
674         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
675         goto CleanUpandReturn;
676     }
677 
678     return vaStatus;
679 
680 CleanUpandReturn:
681     FreeResourceBuffer();
682 
683     if (m_ddiDecodeCtx->pCodecHal)
684     {
685         m_ddiDecodeCtx->pCodecHal->Destroy();
686         MOS_Delete(m_ddiDecodeCtx->pCodecHal);
687         m_ddiDecodeCtx->pCodecHal = nullptr;
688     }
689     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer);
690     m_ddiDecodeCtx->DecodeParams.m_iqMatrixBuffer = nullptr;
691     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_picParams);
692     m_ddiDecodeCtx->DecodeParams.m_picParams = nullptr;
693     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_huffmanTable);
694     m_ddiDecodeCtx->DecodeParams.m_huffmanTable = nullptr;
695     MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
696     m_ddiDecodeCtx->DecodeParams.m_sliceParams = nullptr;
697 
698 #ifdef _DECODE_PROCESSING_SUPPORTED
699     if (m_ddiDecodeCtx->DecodeParams.m_procParams)
700     {
701         auto procParams =
702             (DecodeProcessingParams *)m_ddiDecodeCtx->DecodeParams.m_procParams;
703         MOS_FreeMemory(procParams->m_outputSurface);
704 
705         MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_procParams);
706         m_ddiDecodeCtx->DecodeParams.m_procParams = nullptr;
707     }
708 #endif
709     return vaStatus;
710 }
711 
InitResourceBuffer()712 VAStatus DdiDecodeAVC::InitResourceBuffer()
713 {
714     VAStatus                  vaStatus;
715     DDI_CODEC_COM_BUFFER_MGR *bufMgr;
716 
717     vaStatus           = VA_STATUS_SUCCESS;
718     bufMgr             = &(m_ddiDecodeCtx->BufMgr);
719     bufMgr->pSliceData = nullptr;
720 
721     bufMgr->ui64BitstreamOrder = 0;
722 
723     if(m_width * m_height < CODEC_720P_MAX_PIC_WIDTH * CODEC_720P_MAX_PIC_HEIGHT)
724     {
725         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 2;
726     }
727     else if(m_width * m_height < CODEC_4K_MAX_PIC_WIDTH * CODEC_4K_MAX_PIC_HEIGHT)
728     {
729         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 8;
730     }
731     else
732     {
733         bufMgr->dwMaxBsSize = m_width * m_height * 3 / 16;
734     }
735 
736     // minimal 10k bytes for some special case. Will refractor this later
737     if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
738     {
739         bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
740     }
741 
742     int32_t                   i, count;
743     // init decode bitstream buffer object
744     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
745     {
746         bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
747         if (bufMgr->pBitStreamBuffObject[i] == nullptr)
748         {
749             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
750             goto finish;
751         }
752         bufMgr->pBitStreamBuffObject[i]->iSize    = bufMgr->dwMaxBsSize;
753         bufMgr->pBitStreamBuffObject[i]->uiType   = VASliceDataBufferType;
754         bufMgr->pBitStreamBuffObject[i]->format   = Media_Format_Buffer;
755         bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
756         bufMgr->pBitStreamBuffObject[i]->bo       = nullptr;
757         bufMgr->pBitStreamBase[i]                 = nullptr;
758     }
759 
760     // The pSliceData can be allocated on demand. So the default size is wPicHeightInMB.
761     bufMgr->m_maxNumSliceData                = m_picHeightInMB;
762     bufMgr->pSliceData                       = (DDI_CODEC_BITSTREAM_BUFFER_INFO*)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) *
763             bufMgr->m_maxNumSliceData);
764 
765     if (bufMgr->pSliceData == nullptr)
766     {
767         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
768         goto finish;
769     }
770 
771     bufMgr->dwNumSliceData    = 0;
772     bufMgr->dwNumSliceControl = 0;
773 
774     m_sliceCtrlBufNum = m_picHeightInMB;
775     if (m_ddiDecodeCtx->bShortFormatInUse)
776     {
777         bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base = (VASliceParameterBufferBase *)
778             MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferBase) * m_sliceCtrlBufNum);
779         if (bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base == nullptr)
780         {
781             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
782             goto finish;
783         }
784     }
785     else
786     {
787         bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264 = (VASliceParameterBufferH264 *)
788             MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferH264) * m_sliceCtrlBufNum);
789         if (bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264 == nullptr)
790         {
791             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
792             goto finish;
793         }
794     }
795 
796     return VA_STATUS_SUCCESS;
797 
798 finish:
799     FreeResourceBuffer();
800     return vaStatus;
801 }
802 
FreeResourceBuffer()803 void DdiDecodeAVC::FreeResourceBuffer()
804 {
805     DDI_CODEC_COM_BUFFER_MGR *bufMgr;
806     int32_t                   i;
807 
808     bufMgr = &(m_ddiDecodeCtx->BufMgr);
809 
810     for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
811     {
812         if (bufMgr->pBitStreamBase[i])
813         {
814             DdiMediaUtil_UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
815             bufMgr->pBitStreamBase[i] = nullptr;
816         }
817         if (bufMgr->pBitStreamBuffObject[i])
818         {
819             DdiMediaUtil_FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
820             MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
821             bufMgr->pBitStreamBuffObject[i] = nullptr;
822         }
823     }
824 
825     if (bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264)
826     {
827         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264);
828         bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264 = nullptr;
829     }
830     if (bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base)
831     {
832         MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base);
833         bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base = nullptr;
834     }
835 
836     // free decode bitstream buffer object
837     MOS_FreeMemory(bufMgr->pSliceData);
838     bufMgr->pSliceData = nullptr;
839 }
840 
GetSlcRefIdx(CODEC_PICTURE * picReference,CODEC_PICTURE * slcReference)841 void DdiDecodeAVC::GetSlcRefIdx(CODEC_PICTURE *picReference, CODEC_PICTURE *slcReference)
842 {
843     if (nullptr == picReference|| nullptr == slcReference)
844     {return;}
845 
846     int32_t i = 0;
847     if (slcReference->FrameIdx != CODEC_AVC_NUM_UNCOMPRESSED_SURFACE)
848     {
849         for (i = 0; i < CODEC_MAX_NUM_REF_FRAME; i++)
850         {
851             if (slcReference->FrameIdx == picReference[i].FrameIdx)
852             {
853                 slcReference->FrameIdx = i;
854                 break;
855             }
856         }
857         if (i == CODEC_MAX_NUM_REF_FRAME)
858         {
859             slcReference->FrameIdx = CODEC_AVC_NUM_UNCOMPRESSED_SURFACE;
860         }
861     }
862 }
863 
SetupCodecPicture(DDI_MEDIA_CONTEXT * mediaCtx,DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,CODEC_PICTURE * codecHalPic,VAPictureH264 vaPic,bool fieldPicFlag,bool picReference,bool sliceReference)864 void DdiDecodeAVC::SetupCodecPicture(
865     DDI_MEDIA_CONTEXT                   *mediaCtx,
866     DDI_CODEC_RENDER_TARGET_TABLE       *rtTbl,
867     CODEC_PICTURE                       *codecHalPic,
868     VAPictureH264                       vaPic,
869     bool                                fieldPicFlag,
870     bool                                picReference,
871     bool                                sliceReference)
872 {
873     if(vaPic.picture_id != DDI_CODEC_INVALID_FRAME_INDEX)
874     {
875         DDI_MEDIA_SURFACE *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, vaPic.picture_id);
876         vaPic.frame_idx    = GetRenderTargetID(rtTbl, surface);
877         if(vaPic.frame_idx == DDI_CODEC_INVALID_FRAME_INDEX)
878         {
879             codecHalPic->FrameIdx = CODEC_AVC_NUM_UNCOMPRESSED_SURFACE - 1;
880         }
881         else
882         {
883             codecHalPic->FrameIdx = (uint8_t)vaPic.frame_idx;
884         }
885     }
886     else
887     {
888         vaPic.frame_idx    = DDI_CODEC_INVALID_FRAME_INDEX;
889         codecHalPic->FrameIdx = CODEC_AVC_NUM_UNCOMPRESSED_SURFACE - 1;
890     }
891 
892     if (picReference)
893     {
894         if (vaPic.frame_idx == DDI_CODEC_INVALID_FRAME_INDEX)
895         {
896             codecHalPic->PicFlags = PICTURE_INVALID;
897         }
898         else if ((vaPic.flags&VA_PICTURE_H264_LONG_TERM_REFERENCE) == VA_PICTURE_H264_LONG_TERM_REFERENCE)
899         {
900             codecHalPic->PicFlags = PICTURE_LONG_TERM_REFERENCE;
901         }
902         else
903         {
904             codecHalPic->PicFlags = PICTURE_SHORT_TERM_REFERENCE;
905         }
906     }
907     else
908     {
909         if (fieldPicFlag)
910         {
911             if ((vaPic.flags&VA_PICTURE_H264_BOTTOM_FIELD) == VA_PICTURE_H264_BOTTOM_FIELD)
912             {
913                 codecHalPic->PicFlags = PICTURE_BOTTOM_FIELD;
914             }
915             else
916             {
917                 codecHalPic->PicFlags = PICTURE_TOP_FIELD;
918             }
919         }
920         else
921         {
922             codecHalPic->PicFlags = PICTURE_FRAME;
923         }
924     }
925 
926     if (sliceReference && (vaPic.picture_id == VA_INVALID_ID))//VA_INVALID_ID is used to indicate invalide picture in LIBVA.
927     {
928         codecHalPic->PicFlags = PICTURE_INVALID;
929     }
930 }
931 
932 extern template class MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>;
933 
934 static bool h264Registered =
935     MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>::
936     RegisterCodec<DdiDecodeAVC>(DECODE_ID_AVC);
937