1 /*
2 * Copyright (c) 2021-2024, 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     decode_avc_slice_packet.cpp
24 //! \brief    Defines the interface for avc decode slice packet
25 //!
26 #include "decode_avc_slice_packet.h"
27 #include "codec_def_common.h"
28 
29 namespace decode
30 {
Init()31 MOS_STATUS AvcDecodeSlcPkt::Init()
32 {
33     DECODE_FUNC_CALL();
34 
35     DECODE_CHK_NULL(m_featureManager);
36     DECODE_CHK_NULL(m_hwInterface);
37     DECODE_CHK_NULL(m_osInterface);
38     DECODE_CHK_NULL(m_miItf);
39     DECODE_CHK_NULL(m_avcPipeline);
40     DECODE_CHK_NULL(m_mfxItf);
41 
42     m_avcBasicFeature = dynamic_cast<AvcBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
43     DECODE_CHK_NULL(m_avcBasicFeature);
44 
45     m_allocator = m_pipeline->GetDecodeAllocator();
46     DECODE_CHK_NULL(m_allocator);
47 
48     DECODE_CHK_STATUS(CalculateSliceStateCommandSize());
49 
50     return MOS_STATUS_SUCCESS;
51 }
52 
Prepare()53 MOS_STATUS AvcDecodeSlcPkt::Prepare()
54 {
55     DECODE_FUNC_CALL();
56 
57     DECODE_CHK_NULL(m_avcBasicFeature->m_avcPicParams);
58     DECODE_CHK_NULL(m_avcBasicFeature->m_avcSliceParams);
59 
60     m_avcPicParams    = m_avcBasicFeature->m_avcPicParams;
61     m_avcSliceParams  = m_avcBasicFeature->m_avcSliceParams;
62     m_firstValidSlice = true;
63 
64     return MOS_STATUS_SUCCESS;
65 }
66 
AddCmd_AVC_SLICE_STATE(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)67 MOS_STATUS AvcDecodeSlcPkt::AddCmd_AVC_SLICE_STATE(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx)
68 {
69     SET_AVC_SLICE_STATE(cmdBuffer, slcIdx);
70     SetAndAddAvcSliceState(cmdBuffer, slcIdx);
71     return MOS_STATUS_SUCCESS;
72 }
73 
SET_AVC_SLICE_STATE(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)74 MOS_STATUS AvcDecodeSlcPkt::SET_AVC_SLICE_STATE(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx)
75 {
76     DECODE_FUNC_CALL();
77     auto                   &par        = m_mfxItf->MHW_GETPAR_F(MFX_AVC_SLICE_STATE)();
78     par                                = {};
79     PCODEC_AVC_SLICE_PARAMS slc        = m_avcSliceParams + slcIdx;
80     uint32_t                nextLength = 0;
81     uint32_t                nextOffset = 0;
82 
83     if (slcIdx < m_avcBasicFeature->m_lastValidSlice)
84     {
85         nextLength = (slc + 1)->slice_data_size;
86         nextOffset = (slc + 1)->slice_data_offset;
87     }
88     par.decodeInUse                      = true;
89     par.intelEntrypointInUse             = m_avcPipeline->m_intelEntrypointInUse;
90     par.picIdRemappingInUse              = m_avcBasicFeature->m_picIdRemappingInUse;
91     par.shortFormatInUse                 = m_avcPipeline->IsShortFormat();
92     par.presDataBuffer                   = &m_avcBasicFeature->m_resDataBuffer.OsResource;
93     par.avcPicParams                     = m_avcPicParams;
94     par.mvcExtPicParams                  = m_avcBasicFeature->m_mvcExtPicParams;
95     par.avcPicIdx                        = &m_avcBasicFeature->m_refFrames.m_avcPicIdx[0];
96     par.disableDeblockingFilterIndicator = slc->disable_deblocking_filter_idc;
97     par.sliceBetaOffsetDiv2              = slc->slice_beta_offset_div2;
98     par.sliceAlphaC0OffsetDiv2           = slc->slice_alpha_c0_offset_div2;
99     par.avcSliceParams                   = slc;
100     par.Offset                           = m_avcBasicFeature->m_sliceRecord[slcIdx].offset;
101     par.Length                           = m_avcBasicFeature->m_sliceRecord[slcIdx].length;
102     par.nextOffset                       = nextOffset;
103     par.nextLength                       = nextLength;
104     par.sliceIndex                       = slcIdx;
105     par.isLastSlice                      = (slcIdx == m_avcBasicFeature->m_lastValidSlice);
106     par.fullFrameData                    = m_avcBasicFeature->m_fullFrameData;
107     par.sliceType                        = m_avcBasicFeature->AvcBsdSliceType[slc->slice_type];
108     par.log2WeightDenomChroma            = slc->chroma_log2_weight_denom;
109     par.log2WeightDenomLuma              = slc->luma_log2_weight_denom;
110     par.cabacInitIdc10                   = slc->cabac_init_idc;
111     par.sliceQuantizationParameter       = 26 + m_avcPicParams->pic_init_qp_minus26 + slc->slice_qp_delta;
112 
113     if (slcIdx > 0)
114     {
115         par.totalBytesConsumed = m_avcBasicFeature->m_sliceRecord[slcIdx - 1].totalBytesConsumed;
116     }
117     else
118     {
119         par.totalBytesConsumed = 0;
120     }
121 
122     return MOS_STATUS_SUCCESS;
123 }
124 
MHW_SETPAR_DECL_SRC(MFD_AVC_BSD_OBJECT,AvcDecodeSlcPkt)125 MHW_SETPAR_DECL_SRC(MFD_AVC_BSD_OBJECT, AvcDecodeSlcPkt)
126 {
127     params.IndirectBsdDataLength                     = m_IndirectBsdDataLength;
128     params.IndirectBsdDataStartAddress               = m_IndirectBsdDataStartAddress;
129     params.LastsliceFlag                             = m_LastsliceFlag;
130     params.FirstMacroblockMbBitOffset                = m_FirstMacroblockMbBitOffset;
131     params.FirstMbByteOffsetOfSliceDataOrSliceHeader = m_FirstMbByteOffsetOfSliceDataOrSliceHeader;
132     params.decodeInUse                               = m_decodeInUse;
133     params.pAvcSliceParams                           = m_pAvcSliceParams;
134     return MOS_STATUS_SUCCESS;
135 }
136 
SetAndAddAvcSliceState(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)137 MOS_STATUS AvcDecodeSlcPkt::SetAndAddAvcSliceState(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx)
138 {
139     DECODE_FUNC_CALL();
140     auto     &par            = m_mfxItf->MHW_GETPAR_F(MFX_AVC_SLICE_STATE)();
141     //No need to clear par here due to par set in AddCmd_AVC_PHANTOM_SLICE and SET_AVC_SLICE_STATE and continue set and add to cmdbuffer here.
142     //par has already cleared in AddCmd_AVC_PHANTOM_SLICE and SET_AVC_SLICE_STATE.
143     auto     picParams       = m_avcPicParams;
144     uint32_t mbaffMultiplier = 1;
145     if (picParams->seq_fields.mb_adaptive_frame_field_flag &&
146         !picParams->pic_fields.field_pic_flag)
147     {
148         mbaffMultiplier++;
149     }
150     uint32_t frameFieldHeightInMb = 0;
151     CodecHal_GetFrameFieldHeightInMb(
152         picParams->CurrPic,
153         picParams->pic_height_in_mbs_minus1 + 1,
154         frameFieldHeightInMb);
155     auto sliceParams = m_avcSliceParams + slcIdx;
156     par.sliceType     = m_avcBasicFeature->AvcBsdSliceType[sliceParams->slice_type];
157     par.sliceQuantizationParameter = 26 + picParams->pic_init_qp_minus26 + sliceParams->slice_qp_delta;
158     par.disableDeblockingFilterIndicator = sliceParams->disable_deblocking_filter_idc;
159     par.roundintra = 5;
160     par.roundinter = 2;
161 
162     uint32_t widthInMb = picParams->pic_width_in_mbs_minus1 + 1;
163     par.sliceStartMbNum         = sliceParams->first_mb_in_slice * mbaffMultiplier;
164     par.sliceVerticalPosition   = (sliceParams->first_mb_in_slice / widthInMb) * mbaffMultiplier;
165     par.sliceHorizontalPosition = sliceParams->first_mb_in_slice % widthInMb;
166 
167     if (par.isLastSlice)
168     {
169         par.nextSliceVerticalPosition   = frameFieldHeightInMb;
170         par.nextSliceHorizontalPosition = 0;
171     }
172     else
173     {
174         par.nextSliceVerticalPosition   = (sliceParams->first_mb_in_next_slice / widthInMb) * mbaffMultiplier;
175         par.nextSliceHorizontalPosition = sliceParams->first_mb_in_next_slice % widthInMb;
176     }
177     if (m_avcBasicFeature->IsAvcPSlice(sliceParams->slice_type))
178     {
179         par.numberOfReferencePicturesInInterPredictionList0 = sliceParams->num_ref_idx_l0_active_minus1 + 1;
180         par.weightedPredictionIndicator                     = picParams->pic_fields.weighted_pred_flag;
181     }
182     else if (m_avcBasicFeature->IsAvcBSlice(sliceParams->slice_type))
183     {
184         par.numberOfReferencePicturesInInterPredictionList1 = sliceParams->num_ref_idx_l1_active_minus1 + 1;
185         par.numberOfReferencePicturesInInterPredictionList0 = sliceParams->num_ref_idx_l0_active_minus1 + 1;
186         par.weightedPredictionIndicator                     = picParams->pic_fields.weighted_bipred_idc;
187         par.directPredictionType                            = sliceParams->direct_spatial_mv_pred_flag;
188 
189         // Set MFX_AVC_WEIGHTOFFSET_STATE_CMD_G6
190         if (picParams->pic_fields.weighted_bipred_idc != 1)
191         {
192             // luma/chroma_log2_weight_denoms need to be set to default value in the case of implicit mode
193             par.log2WeightDenomChroma = 5;
194             par.log2WeightDenomLuma   = 5;
195         }
196     }
197 
198     DECODE_CHK_STATUS(m_mfxItf->MHW_ADDCMD_F(MFX_AVC_SLICE_STATE)(&cmdBuffer));
199 
200     return MOS_STATUS_SUCCESS;
201 }
202 
AddCmd_AVC_BSD_OBJECT(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)203 MOS_STATUS AvcDecodeSlcPkt::AddCmd_AVC_BSD_OBJECT(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx)
204 {
205     DECODE_FUNC_CALL();
206     auto &parSlice    = m_mfxItf->MHW_GETPAR_F(MFX_AVC_SLICE_STATE)();
207     auto sliceParams  = m_avcSliceParams + slcIdx;
208     m_LastsliceFlag   = parSlice.isLastSlice;
209     if (parSlice.shortFormatInUse)
210     {
211         if (parSlice.fullFrameData)
212         {
213             m_IndirectBsdDataLength       = parSlice.Length;
214             m_IndirectBsdDataStartAddress = sliceParams->slice_data_offset;
215         }
216         else
217         {
218             m_IndirectBsdDataLength       = parSlice.Length + 1 - m_osInterface->dwNumNalUnitBytesIncluded;
219             m_IndirectBsdDataStartAddress = sliceParams->slice_data_offset - 1 + m_osInterface->dwNumNalUnitBytesIncluded;
220         }
221     }
222     else
223     {
224         m_IndirectBsdDataLength       = parSlice.Length;
225         m_IndirectBsdDataStartAddress = sliceParams->slice_data_offset + parSlice.Offset;
226         m_FirstMacroblockMbBitOffset  = sliceParams->slice_data_bit_offset;
227         if (!parSlice.intelEntrypointInUse)
228         {
229             parSlice.Offset -= (m_osInterface->dwNumNalUnitBytesIncluded - 1);
230             m_IndirectBsdDataLength += parSlice.Offset;
231             m_IndirectBsdDataStartAddress -= parSlice.Offset;
232             m_FirstMbByteOffsetOfSliceDataOrSliceHeader = parSlice.Offset;
233         }
234     }
235     m_decodeInUse     = true;
236     m_pAvcSliceParams = sliceParams;
237     SETPAR_AND_ADDCMD(MFD_AVC_BSD_OBJECT, m_mfxItf, &cmdBuffer);
238     return MOS_STATUS_SUCCESS;
239 }
AddCmd_AVC_PHANTOM_SLICE(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)240 MOS_STATUS AvcDecodeSlcPkt::AddCmd_AVC_PHANTOM_SLICE(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx)
241 {
242     DECODE_FUNC_CALL();
243     PCODEC_AVC_SLICE_PARAMS slc = m_avcSliceParams + slcIdx;
244     if (!m_avcBasicFeature->IsAvcISlice(slc->slice_type))
245     {
246         DECODE_CHK_STATUS(AddCmd_AVC_SLICE_REF_IDX(cmdBuffer, slcIdx));
247         DECODE_CHK_STATUS(AddCmd_AVC_SLICE_WEIGHT_OFFSET(cmdBuffer, slcIdx));
248     }
249     auto &par                            = m_mfxItf->MHW_GETPAR_F(MFX_AVC_SLICE_STATE)();
250     par                                  = {};
251     par.disableDeblockingFilterIndicator = slc->disable_deblocking_filter_idc;
252     par.sliceBetaOffsetDiv2              = slc->slice_beta_offset_div2;
253     par.sliceAlphaC0OffsetDiv2           = slc->slice_alpha_c0_offset_div2;
254     par.intelEntrypointInUse             = m_avcPipeline->m_intelEntrypointInUse;
255     par.picIdRemappingInUse              = m_avcBasicFeature->m_picIdRemappingInUse;
256     par.shortFormatInUse                 = false;
257     par.presDataBuffer                   = &m_avcBasicFeature->m_resDataBuffer.OsResource;
258     par.avcPicParams                     = m_avcPicParams;
259     par.mvcExtPicParams                  = m_avcBasicFeature->m_mvcExtPicParams;
260     par.avcPicIdx                        = &m_avcBasicFeature->m_refFrames.m_avcPicIdx[0];
261     par.phantomSlice                     = true;
262     par.totalBytesConsumed               = 0;
263     par.avcSliceParams                   = slc;
264 
265     par.Offset     = 0;
266     par.Length     = slc->slice_data_offset;
267     par.nextOffset = slc->slice_data_offset;
268     par.nextLength = slc->slice_data_size;
269 
270     SetAndAddAvcSliceState(cmdBuffer, slcIdx);
271     return MOS_STATUS_SUCCESS;
272 }
273 
MHW_SETPAR_DECL_SRC(MFX_AVC_WEIGHTOFFSET_STATE,AvcDecodeSlcPkt)274 MHW_SETPAR_DECL_SRC(MFX_AVC_WEIGHTOFFSET_STATE, AvcDecodeSlcPkt)
275 {
276     params.decodeInUse = true;
277     params.uiList      = m_listID;
278     auto slc = m_avcSliceParams + m_curSliceNum;
279     MOS_SecureMemcpy(
280         &params.Weights,
281         sizeof(params.Weights),
282         &slc->Weights,
283         sizeof(slc->Weights));
284     //The correct explicit calculation (like in Cantiga)
285     for (auto i = 0; i < CODEC_MAX_NUM_REF_FIELD; i++)
286     {
287         params.weightoffset[3 * i] = params.Weights[params.uiList][i][0][0] & 0xFFFF;               // Y Weight
288         params.weightoffset[3 * i] |= (params.Weights[params.uiList][i][0][1] & 0xFFFF) << 16;      //Y Offset
289         params.weightoffset[3 * i + 1] = params.Weights[params.uiList][i][1][0] & 0xFFFF;           // Cb weight
290         params.weightoffset[3 * i + 1] |= (params.Weights[params.uiList][i][1][1] & 0xFFFF) << 16;  // Cb offset
291         params.weightoffset[3 * i + 2] = params.Weights[params.uiList][i][2][0] & 0xFFFF;           // Cr weight
292         params.weightoffset[3 * i + 2] |= (params.Weights[params.uiList][i][2][1] & 0xFFFF) << 16;  // Cr offset
293     }
294 
295     return MOS_STATUS_SUCCESS;
296 }
297 
AddCmd_AVC_SLICE_WEIGHT_OFFSET(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)298 MOS_STATUS AvcDecodeSlcPkt::AddCmd_AVC_SLICE_WEIGHT_OFFSET(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx)
299 {
300     DECODE_FUNC_CALL();
301     PCODEC_AVC_SLICE_PARAMS slc = m_avcSliceParams + slcIdx;
302     if (m_avcBasicFeature->IsAvcPSlice(slc->slice_type) &&
303         m_avcPicParams->pic_fields.weighted_pred_flag == 1)
304     {
305         m_listID = 0;
306         SETPAR_AND_ADDCMD(MFX_AVC_WEIGHTOFFSET_STATE, m_mfxItf, &cmdBuffer);
307     }
308     if (m_avcBasicFeature->IsAvcBSlice(slc->slice_type) &&
309         m_avcPicParams->pic_fields.weighted_bipred_idc == 1)
310     {
311         m_listID = 0;
312         SETPAR_AND_ADDCMD(MFX_AVC_WEIGHTOFFSET_STATE, m_mfxItf, &cmdBuffer);
313         m_listID = 1;
314         SETPAR_AND_ADDCMD(MFX_AVC_WEIGHTOFFSET_STATE, m_mfxItf, &cmdBuffer);
315     }
316     return MOS_STATUS_SUCCESS;
317 }
318 
MHW_SETPAR_DECL_SRC(MFX_AVC_REF_IDX_STATE,AvcDecodeSlcPkt)319 MHW_SETPAR_DECL_SRC(MFX_AVC_REF_IDX_STATE, AvcDecodeSlcPkt)
320 {
321     auto slc = m_avcSliceParams + m_curSliceNum;
322     params.CurrPic                 = m_avcPicParams->CurrPic;
323     params.uiList                  = m_listID;
324     if (params.uiList == 0)
325     {
326         params.numRefForList[params.uiList] = slc->num_ref_idx_l0_active_minus1 + 1;
327     }
328     if (params.uiList == 1)
329     {
330         params.numRefForList[params.uiList] = slc->num_ref_idx_l1_active_minus1 + 1;
331     }
332     MOS_SecureMemcpy(
333         &params.refPicList,
334         sizeof(params.refPicList),
335         &slc->RefPicList,
336         sizeof(slc->RefPicList));
337     params.pAvcPicIdx            = &m_avcBasicFeature->m_refFrames.m_avcPicIdx[0];
338     params.avcRefList            = (void **)m_avcBasicFeature->m_refFrames.m_refList;
339     params.intelEntrypointInUse = m_avcPipeline->m_intelEntrypointInUse;
340     params.picIdRemappingInUse  = m_avcBasicFeature->m_picIdRemappingInUse;
341      // Need to add an empty MFX_AVC_REF_IDX_STATE_CMD for dummy reference on I-Frame
342     if (!params.dummyReference)
343     {
344 
345         CODEC_REF_LIST **avcRefList         = (CODEC_REF_LIST **)params.avcRefList;
346         AvcRefListWrite *cmdAvcRefListWrite = (AvcRefListWrite *)&(params.referenceListEntry);
347 
348         uint8_t picIDOneOnOneMapping = 0;
349 
350         for (uint32_t i = 0; i < params.numRefForList[params.uiList]; i++)
351         {
352             uint8_t idx = params.refPicList[params.uiList][i].FrameIdx;
353 
354             if (!params.intelEntrypointInUse)
355             {
356                 if (idx >= CODEC_MAX_NUM_REF_FRAME)
357                 {
358                     DECODE_ASSERT(false);  // Idx must be within 0 to 15
359                     DECODE_ASSERTMESSAGE("Idx must be within 0 to 15!");
360                     idx = 0;
361                 }
362 
363                 idx = params.pAvcPicIdx[idx].ucPicIdx;
364             }
365 
366             uint8_t picID = params.picIdRemappingInUse ? params.refPicList[params.uiList][i].FrameIdx : avcRefList[idx]->ucFrameId;
367 
368             // When one on one ref idx mapping is enabled, program picID count from 0, 2 ...
369             if (params.oneOnOneMapping)
370             {
371                 picID = picIDOneOnOneMapping;
372                 picIDOneOnOneMapping += 2;
373             }
374             cmdAvcRefListWrite->Ref[i].frameStoreID = picID;
375             cmdAvcRefListWrite->Ref[i].bottomField =
376                 CodecHal_PictureIsBottomField(params.refPicList[params.uiList][i]);
377             cmdAvcRefListWrite->Ref[i].fieldPicFlag =
378                 CodecHal_PictureIsField(params.refPicList[params.uiList][i]);
379             cmdAvcRefListWrite->Ref[i].longTermFlag =
380                 CodecHal_PictureIsLongTermRef(avcRefList[idx]->RefPic);
381             cmdAvcRefListWrite->Ref[i].nonExisting = 0;
382         }
383 
384         for (auto i = params.numRefForList[params.uiList]; i < 32; i++)
385         {
386             cmdAvcRefListWrite->Ref[i].value = 0x80;
387         }
388     }
389     return MOS_STATUS_SUCCESS;
390 }
391 
AddCmd_AVC_SLICE_REF_IDX(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)392 MOS_STATUS AvcDecodeSlcPkt::AddCmd_AVC_SLICE_REF_IDX(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx)
393 {
394     DECODE_FUNC_CALL();
395     PCODEC_AVC_SLICE_PARAMS slc = m_avcSliceParams + slcIdx;
396     m_listID = 0;
397     SETPAR_AND_ADDCMD(MFX_AVC_REF_IDX_STATE, m_mfxItf, &cmdBuffer);
398     if (m_avcBasicFeature->IsAvcBSlice(slc->slice_type))
399     {
400         m_listID = 1;
401         SETPAR_AND_ADDCMD(MFX_AVC_REF_IDX_STATE, m_mfxItf, &cmdBuffer);
402     }
403     return MOS_STATUS_SUCCESS;
404 }
405 
AddCmd_AVC_SLICE_Addr(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)406 MOS_STATUS AvcDecodeSlcPkt::AddCmd_AVC_SLICE_Addr(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx)
407 {
408     DECODE_FUNC_CALL();
409     SET_AVC_SLICE_STATE(cmdBuffer, slcIdx);
410     auto &parSlice           = m_mfxItf->MHW_GETPAR_F(MFX_AVC_SLICE_STATE)();
411     auto &parSliceAddr       = m_mfxItf->MHW_GETPAR_F(MFD_AVC_SLICEADDR)();
412     parSliceAddr.decodeInUse = true;
413     if (parSlice.fullFrameData)
414     {
415         parSliceAddr.IndirectBsdDataLength       = parSlice.nextLength;
416         parSliceAddr.IndirectBsdDataStartAddress = parSlice.nextOffset;
417     }
418     else
419     {
420         parSliceAddr.IndirectBsdDataLength       = parSlice.nextLength + 1 - m_osInterface->dwNumNalUnitBytesIncluded;
421         parSliceAddr.IndirectBsdDataStartAddress = parSlice.nextOffset - 1 + m_osInterface->dwNumNalUnitBytesIncluded;
422     }
423     parSliceAddr.presDataBuffer       = parSlice.presDataBuffer;
424     parSliceAddr.dwSliceIndex         = parSlice.sliceIndex;
425     parSliceAddr.dwTotalBytesConsumed = parSlice.totalBytesConsumed;
426     parSliceAddr.avcSliceParams       = parSlice.avcSliceParams;
427     if (!parSlice.isLastSlice)
428     {
429         DECODE_CHK_STATUS(m_mfxItf->MHW_ADDCMD_F(MFD_AVC_SLICEADDR)(&cmdBuffer));
430     }
431     return MOS_STATUS_SUCCESS;
432 }
433 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)434 MOS_STATUS AvcDecodeSlcPkt::CalculateCommandSize(uint32_t &commandBufferSize,
435     uint32_t &                                             requestedPatchListSize)
436 {
437     DECODE_FUNC_CALL();
438 
439     commandBufferSize      = m_sliceStatesSize;
440     requestedPatchListSize = m_slicePatchListSize;
441 
442     return MOS_STATUS_SUCCESS;
443 }
444 
CalculateSliceStateCommandSize()445 MOS_STATUS AvcDecodeSlcPkt::CalculateSliceStateCommandSize()
446 {
447     DECODE_FUNC_CALL();
448 
449     // Slice Level Commands
450     DECODE_CHK_STATUS(m_hwInterface->GetMfxPrimitiveCommandsDataSize(CODECHAL_DECODE_MODE_AVCVLD, &m_sliceStatesSize, &m_slicePatchListSize, m_avcBasicFeature->m_shortFormatInUse));
451 
452     return MOS_STATUS_SUCCESS;
453 }
454 
455 }  // namespace decode
456