1 /*
2 * Copyright (c) 2019-2021, 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_hevc_slice_packet_xe_m_base.cpp
24 //! \brief    Defines the interface for hevc decode slice packet
25 //!
26 #include "codechal_utilities.h"
27 #include "decode_hevc_slice_packet_xe_m_base.h"
28 
29 namespace decode
30 {
31 
~HevcDecodeSlcPktXe_M_Base()32 HevcDecodeSlcPktXe_M_Base::~HevcDecodeSlcPktXe_M_Base()
33 {
34 }
35 
Init()36 MOS_STATUS HevcDecodeSlcPktXe_M_Base::Init()
37 {
38     DECODE_FUNC_CALL();
39     DECODE_CHK_NULL(m_featureManager);
40     DECODE_CHK_NULL(m_hwInterface);
41     DECODE_CHK_NULL(m_osInterface);
42     DECODE_CHK_NULL(m_miInterface);
43     DECODE_CHK_NULL(m_hevcPipeline);
44     DECODE_CHK_NULL(m_hcpInterface);
45 
46     m_hevcBasicFeature = dynamic_cast<HevcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
47     DECODE_CHK_NULL(m_hevcBasicFeature);
48 
49     m_allocator = m_pipeline ->GetDecodeAllocator();
50     DECODE_CHK_NULL(m_allocator);
51 
52     m_decodecp = m_pipeline->GetDecodeCp();
53 
54     DECODE_CHK_STATUS(CalculateSliceStateCommandSize());
55 
56     return MOS_STATUS_SUCCESS;
57 }
58 
Prepare()59 MOS_STATUS HevcDecodeSlcPktXe_M_Base::Prepare()
60 {
61     DECODE_FUNC_CALL();
62 
63     DECODE_CHK_NULL(m_hevcBasicFeature->m_hevcPicParams);
64     DECODE_CHK_NULL(m_hevcBasicFeature->m_hevcSliceParams);
65 
66     m_hevcPicParams       = m_hevcBasicFeature->m_hevcPicParams;
67     m_hevcSliceParams     = m_hevcBasicFeature->m_hevcSliceParams;
68     m_hevcRextPicParams   = m_hevcBasicFeature->m_hevcRextPicParams;
69     m_hevcRextSliceParams = m_hevcBasicFeature->m_hevcRextSliceParams;
70     m_hevcSccPicParams    = m_hevcBasicFeature->m_hevcSccPicParams;
71 
72     return MOS_STATUS_SUCCESS;
73 }
74 
ValidateSubTileIdx(const HevcTileCoding::SliceTileInfo & sliceTileInfo,uint32_t subTileIdx)75 MOS_STATUS HevcDecodeSlcPktXe_M_Base::ValidateSubTileIdx(
76     const HevcTileCoding::SliceTileInfo &sliceTileInfo,
77     uint32_t                             subTileIdx)
78 {
79     if (sliceTileInfo.numTiles > 0)
80     {
81         DECODE_CHK_COND(subTileIdx >= sliceTileInfo.numTiles, "sub tile index exceeds number of tiles!");
82     }
83     else
84     {
85         DECODE_CHK_COND(subTileIdx > 0, "sub tile index exceeds number of tiles!");
86     }
87 
88     return MOS_STATUS_SUCCESS;
89 }
90 
SetHcpSliceStateParams(MHW_VDBOX_HEVC_SLICE_STATE & sliceStateParams,uint32_t sliceIdx,uint32_t subTileIdx)91 MOS_STATUS HevcDecodeSlcPktXe_M_Base::SetHcpSliceStateParams(
92     MHW_VDBOX_HEVC_SLICE_STATE &sliceStateParams,
93     uint32_t                    sliceIdx,
94     uint32_t                    subTileIdx)
95 {
96     DECODE_FUNC_CALL();
97 
98     const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
99     DECODE_CHK_NULL(sliceTileInfo);
100 
101     CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
102 
103     sliceStateParams.presDataBuffer = &(m_hevcBasicFeature->m_resDataBuffer.OsResource);
104     sliceStateParams.pRefIdxMapping = m_hevcBasicFeature->m_refFrames.m_refIdxMapping;
105     sliceStateParams.pHevcPicParams = m_hevcPicParams;
106     sliceStateParams.pHevcSliceParams = sliceParams;
107 
108     sliceStateParams.bLastSliceInTile = sliceTileInfo->lastSliceOfTile;
109     sliceStateParams.bLastSliceInTileColumn = sliceTileInfo->lastSliceOfTile &&
110                                               (sliceTileInfo->sliceTileY == m_hevcPicParams->num_tile_rows_minus1);
111 
112     sliceStateParams.dwLength = sliceParams->slice_data_size;
113     sliceStateParams.dwSliceIndex = sliceIdx;
114     sliceStateParams.bLastSlice = m_hevcBasicFeature->IsLastSlice(sliceIdx);
115 
116     return MOS_STATUS_SUCCESS;
117 }
118 
SetRefIdxParams(MHW_VDBOX_HEVC_REF_IDX_PARAMS & refIdxParams,uint32_t sliceIdx)119 MOS_STATUS HevcDecodeSlcPktXe_M_Base::SetRefIdxParams(
120     MHW_VDBOX_HEVC_REF_IDX_PARAMS &refIdxParams,
121     uint32_t                       sliceIdx)
122 {
123     CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
124 
125     if (!m_hcpInterface->IsHevcISlice(sliceParams->LongSliceFlags.fields.slice_type))
126     {
127         HevcReferenceFrames &refFrames = m_hevcBasicFeature->m_refFrames;
128         DECODE_CHK_STATUS(refFrames.FixSliceRefList(*m_hevcPicParams, *sliceParams));
129 
130         refIdxParams.CurrPic         = m_hevcPicParams->CurrPic;
131         refIdxParams.ucNumRefForList = sliceParams->num_ref_idx_l0_active_minus1 + 1;
132 
133         DECODE_CHK_STATUS(MOS_SecureMemcpy(&refIdxParams.RefPicList, sizeof(refIdxParams.RefPicList),
134                                            &sliceParams->RefPicList, sizeof(sliceParams->RefPicList)));
135 
136         refIdxParams.hevcRefList  = (void **)refFrames.m_refList;
137         refIdxParams.poc_curr_pic = m_hevcPicParams->CurrPicOrderCntVal;
138         for (uint8_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
139         {
140             refIdxParams.poc_list[i] = m_hevcPicParams->PicOrderCntValList[i];
141         }
142 
143         refIdxParams.pRefIdxMapping     = refFrames.m_refIdxMapping;
144         refIdxParams.RefFieldPicFlag    = m_hevcPicParams->RefFieldPicFlag;
145         refIdxParams.RefBottomFieldFlag = m_hevcPicParams->RefBottomFieldFlag;
146     }
147     else if (m_hevcBasicFeature->m_useDummyReference && !m_osInterface->bSimIsActive)
148     {
149         refIdxParams.bDummyReference = true;
150     }
151 
152     return MOS_STATUS_SUCCESS;
153 }
154 
SetWeightOffsetParams(MHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS & weightOffsetParams,uint32_t sliceIdx)155 MOS_STATUS HevcDecodeSlcPktXe_M_Base::SetWeightOffsetParams(
156     MHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS &weightOffsetParams,
157     uint32_t                            sliceIdx)
158 {
159     CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
160 
161     bool weightedPred   = m_hevcPicParams->weighted_pred_flag &&
162                           m_hcpInterface->IsHevcPSlice(sliceParams->LongSliceFlags.fields.slice_type);
163     bool weightedBiPred = m_hevcPicParams->weighted_bipred_flag &&
164                           m_hcpInterface->IsHevcBSlice(sliceParams->LongSliceFlags.fields.slice_type);
165     if (weightedPred || weightedBiPred)
166     {
167         weightOffsetParams.ucList = 0;
168 
169         DECODE_CHK_STATUS(MOS_SecureMemcpy(
170             &weightOffsetParams.LumaWeights[0], sizeof(weightOffsetParams.LumaWeights[0]),
171             &sliceParams->delta_luma_weight_l0, sizeof(sliceParams->delta_luma_weight_l0)));
172 
173         DECODE_CHK_STATUS(MOS_SecureMemcpy(
174             &weightOffsetParams.LumaWeights[1], sizeof(weightOffsetParams.LumaWeights[1]),
175             &sliceParams->delta_luma_weight_l1, sizeof(sliceParams->delta_luma_weight_l1)));
176 
177         PCODEC_HEVC_EXT_SLICE_PARAMS slcRextParams = (m_hevcRextSliceParams == nullptr) ?
178                                                      nullptr : (m_hevcRextSliceParams + sliceIdx);
179         if (slcRextParams != nullptr)
180         {
181             DECODE_CHK_STATUS(MOS_SecureMemcpy(
182                 &weightOffsetParams.LumaOffsets[0], sizeof(weightOffsetParams.LumaOffsets[0]),
183                 &slcRextParams->luma_offset_l0, sizeof(slcRextParams->luma_offset_l0)));
184 
185             DECODE_CHK_STATUS(MOS_SecureMemcpy(
186                 &weightOffsetParams.LumaOffsets[1], sizeof(weightOffsetParams.LumaOffsets[1]),
187                 &slcRextParams->luma_offset_l1, sizeof(slcRextParams->luma_offset_l1)));
188 
189             DECODE_CHK_STATUS(MOS_SecureMemcpy(
190                 &weightOffsetParams.ChromaOffsets[0], sizeof(weightOffsetParams.ChromaOffsets[0]),
191                 &slcRextParams->ChromaOffsetL0, sizeof(slcRextParams->ChromaOffsetL0)));
192 
193             DECODE_CHK_STATUS(MOS_SecureMemcpy(
194                 &weightOffsetParams.ChromaOffsets[1], sizeof(weightOffsetParams.ChromaOffsets[1]),
195                 &slcRextParams->ChromaOffsetL1, sizeof(slcRextParams->ChromaOffsetL1)));
196         }
197         else
198         {
199             for (uint32_t i = 0; i < 15; i++)
200             {
201                 weightOffsetParams.LumaOffsets[0][i] = (int16_t)sliceParams->luma_offset_l0[i];
202                 weightOffsetParams.LumaOffsets[1][i] = (int16_t)sliceParams->luma_offset_l1[i];
203 
204                 for (uint32_t j = 0; j < 2; j++)
205                 {
206                     weightOffsetParams.ChromaOffsets[0][i][j] = (int16_t)sliceParams->ChromaOffsetL0[i][j];
207                     weightOffsetParams.ChromaOffsets[1][i][j] = (int16_t)sliceParams->ChromaOffsetL1[i][j];
208                 }
209             }
210         }
211 
212         DECODE_CHK_STATUS(MOS_SecureMemcpy(
213             &weightOffsetParams.ChromaWeights[0], sizeof(weightOffsetParams.ChromaWeights[0]),
214             &sliceParams->delta_chroma_weight_l0, sizeof(sliceParams->delta_chroma_weight_l0)));
215 
216         DECODE_CHK_STATUS(MOS_SecureMemcpy(
217             &weightOffsetParams.ChromaWeights[1], sizeof(weightOffsetParams.ChromaWeights[1]),
218             &sliceParams->delta_chroma_weight_l1, sizeof(sliceParams->delta_chroma_weight_l1)));
219     }
220 
221     return MOS_STATUS_SUCCESS;
222 }
223 
AddWeightOffset(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx)224 MOS_STATUS HevcDecodeSlcPktXe_M_Base::AddWeightOffset(
225     MOS_COMMAND_BUFFER &cmdBuffer,
226     uint32_t            sliceIdx)
227 {
228     CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
229     bool weightedPred   = m_hevcPicParams->weighted_pred_flag &&
230                           m_hcpInterface->IsHevcPSlice(sliceParams->LongSliceFlags.fields.slice_type);
231     bool weightedBiPred = m_hevcPicParams->weighted_bipred_flag &&
232                           m_hcpInterface->IsHevcBSlice(sliceParams->LongSliceFlags.fields.slice_type);
233 
234     if (weightedPred || weightedBiPred)
235     {
236         MHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS weightOffsetParams;
237         MOS_ZeroMemory(&weightOffsetParams, sizeof(weightOffsetParams));
238 
239         DECODE_CHK_STATUS(SetWeightOffsetParams(weightOffsetParams, sliceIdx));
240         DECODE_CHK_STATUS(m_hcpInterface->AddHcpWeightOffsetStateCmd(&cmdBuffer, nullptr, &weightOffsetParams));
241 
242         if (weightedBiPred)
243         {
244             weightOffsetParams.ucList = 1;
245             DECODE_CHK_STATUS(m_hcpInterface->AddHcpWeightOffsetStateCmd(&cmdBuffer, nullptr, &weightOffsetParams));
246         }
247     }
248 
249     return MOS_STATUS_SUCCESS;
250 }
251 
SetBsdObjParams(MHW_VDBOX_HCP_BSD_PARAMS & bsdObjParams,uint32_t sliceIdx,uint32_t subTileIdx)252 MOS_STATUS HevcDecodeSlcPktXe_M_Base::SetBsdObjParams(
253     MHW_VDBOX_HCP_BSD_PARAMS &bsdObjParams,
254     uint32_t                  sliceIdx,
255     uint32_t                  subTileIdx)
256 {
257     const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
258     DECODE_CHK_NULL(sliceTileInfo);
259     DECODE_CHK_STATUS(ValidateSubTileIdx(*sliceTileInfo, subTileIdx));
260 
261     CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
262 
263     if (sliceTileInfo->numTiles > 1)
264     {
265         bsdObjParams.dwBsdDataLength = sliceTileInfo->tileArrayBuf[subTileIdx].bsdLength;
266         bsdObjParams.dwBsdDataStartOffset = sliceParams->slice_data_offset +
267                                             sliceTileInfo->tileArrayBuf[subTileIdx].bsdOffset;
268     }
269     else
270     {
271         bsdObjParams.dwBsdDataLength = sliceParams->slice_data_size;
272         bsdObjParams.dwBsdDataStartOffset = sliceParams->slice_data_offset;
273     }
274 
275     return MOS_STATUS_SUCCESS;
276 }
277 
AddBsdObj(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx,uint32_t subTileIdx)278 MOS_STATUS HevcDecodeSlcPktXe_M_Base::AddBsdObj(
279     MOS_COMMAND_BUFFER &cmdBuffer,
280     uint32_t            sliceIdx,
281     uint32_t            subTileIdx)
282 {
283     MHW_VDBOX_HCP_BSD_PARAMS bsdObjParams;
284     MOS_ZeroMemory(&bsdObjParams, sizeof(MHW_VDBOX_HCP_BSD_PARAMS));
285 
286     DECODE_CHK_STATUS(SetBsdObjParams(bsdObjParams, sliceIdx, subTileIdx));
287     DECODE_CHK_STATUS(m_hcpInterface->AddHcpBsdObjectCmd(&cmdBuffer, &bsdObjParams));
288 
289     return MOS_STATUS_SUCCESS;
290 }
291 
AddHcpCpState(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx,uint32_t subTileIdx)292 MOS_STATUS HevcDecodeSlcPktXe_M_Base::AddHcpCpState(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t sliceIdx, uint32_t subTileIdx)
293 {
294     PMOS_RESOURCE buffer = &(m_hevcBasicFeature->m_resDataBuffer.OsResource);
295     uint32_t startoffset  = m_hevcSliceParams->slice_data_offset;
296 
297     const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
298     DECODE_CHK_NULL(sliceTileInfo);
299     DECODE_CHK_STATUS(ValidateSubTileIdx(*sliceTileInfo, subTileIdx));
300 
301     CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
302 
303     if (sliceTileInfo->numTiles > 1)
304     {
305         startoffset = sliceParams->slice_data_offset +
306         sliceTileInfo->tileArrayBuf[subTileIdx].bsdOffset;
307     }
308     else
309     {
310         startoffset = sliceParams->slice_data_offset;
311     }
312     if(m_decodecp)
313     {
314         DECODE_CHK_STATUS(m_decodecp->AddHcpState(&cmdBuffer, buffer, m_hevcSliceParams->slice_data_size, startoffset, sliceIdx));
315     }
316     return MOS_STATUS_SUCCESS;
317 }
318 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)319 MOS_STATUS HevcDecodeSlcPktXe_M_Base::CalculateCommandSize(uint32_t &commandBufferSize,
320                                                   uint32_t &requestedPatchListSize)
321 {
322     commandBufferSize      = m_sliceStatesSize;
323     requestedPatchListSize = m_slicePatchListSize;
324     return MOS_STATUS_SUCCESS;
325 }
326 
CalculateSliceStateCommandSize()327 MOS_STATUS HevcDecodeSlcPktXe_M_Base::CalculateSliceStateCommandSize()
328 {
329     DECODE_FUNC_CALL();
330 
331     // Slice Level Commands
332     DECODE_CHK_STATUS(m_hwInterface->GetHcpPrimitiveCommandSize(m_hevcBasicFeature->m_mode,
333                                                                  &m_sliceStatesSize,
334                                                                  &m_slicePatchListSize,
335                                                                  false));
336 
337     return MOS_STATUS_SUCCESS;
338 }
339 
340 }
341