1 /*
2 * Copyright (c) 2022-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_hevc_slice_packet.cpp
24 //! \brief    Defines the interface for hevc decode slice packet
25 //!
26 #include "decode_hevc_slice_packet.h"
27 
28 namespace decode
29 {
~HevcDecodeSlcPkt()30     HevcDecodeSlcPkt::~HevcDecodeSlcPkt()
31     {
32     }
33 
Init()34     MOS_STATUS HevcDecodeSlcPkt::Init()
35     {
36         DECODE_FUNC_CALL();
37 
38         DECODE_CHK_NULL(m_featureManager);
39         DECODE_CHK_NULL(m_hwInterface);
40         DECODE_CHK_NULL(m_osInterface);
41         DECODE_CHK_NULL(m_miItf);
42         DECODE_CHK_NULL(m_hevcPipeline);
43 
44         m_hevcBasicFeature = dynamic_cast<HevcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
45         DECODE_CHK_NULL(m_hevcBasicFeature);
46 
47         m_allocator = m_pipeline ->GetDecodeAllocator();
48         DECODE_CHK_NULL(m_allocator);
49 
50         m_decodecp = m_pipeline->GetDecodeCp();
51 
52         DECODE_CHK_STATUS(CalculateSliceStateCommandSize());
53 
54         return MOS_STATUS_SUCCESS;
55     }
56 
Prepare()57     MOS_STATUS HevcDecodeSlcPkt::Prepare()
58     {
59         DECODE_FUNC_CALL();
60 
61         DECODE_CHK_NULL(m_hevcBasicFeature->m_hevcPicParams);
62         DECODE_CHK_NULL(m_hevcBasicFeature->m_hevcSliceParams);
63 
64         m_hevcPicParams       = m_hevcBasicFeature->m_hevcPicParams;
65         m_hevcSliceParams     = m_hevcBasicFeature->m_hevcSliceParams;
66         m_hevcRextPicParams   = m_hevcBasicFeature->m_hevcRextPicParams;
67         m_hevcRextSliceParams = m_hevcBasicFeature->m_hevcRextSliceParams;
68         m_hevcSccPicParams    = m_hevcBasicFeature->m_hevcSccPicParams;
69 
70         return MOS_STATUS_SUCCESS;
71     }
72 
ValidateSubTileIdx(const HevcTileCoding::SliceTileInfo & sliceTileInfo,uint32_t subTileIdx)73     MOS_STATUS HevcDecodeSlcPkt::ValidateSubTileIdx(
74         const HevcTileCoding::SliceTileInfo &sliceTileInfo,
75         uint32_t                             subTileIdx)
76     {
77         DECODE_FUNC_CALL();
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 
AddCmd_HCP_PALETTE_INITIALIZER_STATE(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx)91     MOS_STATUS HevcDecodeSlcPkt::AddCmd_HCP_PALETTE_INITIALIZER_STATE(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t sliceIdx)
92     {
93         DECODE_FUNC_CALL();
94 
95         const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
96         DECODE_CHK_NULL(sliceTileInfo);
97 
98         bool sccPaletteMode   = m_hevcBasicFeature->m_isSCCPLTMode;
99         bool firstSliceOfTile = sliceTileInfo->firstSliceOfTile;
100         bool independentSlice = m_hevcBasicFeature->IsIndependentSlice(sliceIdx);
101 
102         if (sccPaletteMode && (firstSliceOfTile || independentSlice))
103         {
104             auto &params = m_hcpItf->MHW_GETPAR_F(HCP_PALETTE_INITIALIZER_STATE)();
105             params       = {};
106 
107             uint32_t yentryIdx = 0;
108             uint32_t yentry = 0, cbEntry = 0, crEntry = 0;
109 
110             params.predictorPaletteSize = m_hevcSccPicParams->PredictorPaletteSize;
111             params.hevcSccPaletteSize   = m_HevcSccPaletteSize;
112             for (uint32_t i = 0; i < m_HevcSccPaletteSize; i += 3)
113             {
114                 // First 64 color entries
115                 yentryIdx                                    = i * 2 / 3;
116                 params.predictorPaletteEntries[0][yentryIdx] = m_hevcSccPicParams->PredictorPaletteEntries[0][yentryIdx];  // Y
117                 params.predictorPaletteEntries[1][yentryIdx] = m_hevcSccPicParams->PredictorPaletteEntries[1][yentryIdx];
118 
119                 params.predictorPaletteEntries[2][yentryIdx]     = m_hevcSccPicParams->PredictorPaletteEntries[2][yentryIdx];  // Cr
120                 params.predictorPaletteEntries[0][yentryIdx + 1] = m_hevcSccPicParams->PredictorPaletteEntries[0][yentryIdx + 1];
121 
122                 params.predictorPaletteEntries[1][yentryIdx + 1] = m_hevcSccPicParams->PredictorPaletteEntries[1][yentryIdx + 1];  // Cb
123                 params.predictorPaletteEntries[2][yentryIdx + 1] = m_hevcSccPicParams->PredictorPaletteEntries[2][yentryIdx + 1];
124 
125                 // Second 64 color entries
126                 yentryIdx += 64;
127                 params.predictorPaletteEntries[0][yentryIdx] = m_hevcSccPicParams->PredictorPaletteEntries[0][yentryIdx];  // Y
128                 params.predictorPaletteEntries[1][yentryIdx] = m_hevcSccPicParams->PredictorPaletteEntries[1][yentryIdx];
129 
130                 params.predictorPaletteEntries[2][yentryIdx]     = m_hevcSccPicParams->PredictorPaletteEntries[2][yentryIdx];  // Cr
131                 params.predictorPaletteEntries[0][yentryIdx + 1] = m_hevcSccPicParams->PredictorPaletteEntries[0][yentryIdx + 1];
132 
133                 params.predictorPaletteEntries[1][yentryIdx + 1] = m_hevcSccPicParams->PredictorPaletteEntries[1][yentryIdx + 1];  // Cb
134                 params.predictorPaletteEntries[2][yentryIdx + 1] = m_hevcSccPicParams->PredictorPaletteEntries[2][yentryIdx + 1];
135             }
136 
137             DECODE_CHK_STATUS(m_hcpItf->MHW_ADDCMD_F(HCP_PALETTE_INITIALIZER_STATE)(&cmdBuffer));
138         }
139 
140         return MOS_STATUS_SUCCESS;
141     }
142 
SET_HCP_SLICE_STATE(uint32_t sliceIdx,uint32_t subTileIdx)143     MOS_STATUS HevcDecodeSlcPkt::SET_HCP_SLICE_STATE(uint32_t sliceIdx, uint32_t subTileIdx)
144     {
145         DECODE_FUNC_CALL();
146 
147         const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
148         DECODE_CHK_NULL(sliceTileInfo);
149 
150         CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
151         DECODE_CHK_NULL(sliceParams);
152 
153         DECODE_CHK_NULL(m_hevcPicParams);
154 
155         uint32_t dwSliceIndex   = sliceIdx;
156         bool     bLastSlice     = m_hevcBasicFeature->IsLastSlice(sliceIdx);
157         int8_t * pRefIdxMapping = m_hevcBasicFeature->m_refFrames.m_refIdxMapping;
158 
159         auto &params                 = m_hcpItf->MHW_GETPAR_F(HCP_SLICE_STATE)();
160         params.lastSliceInTile       = sliceTileInfo->lastSliceOfTile;
161         params.lastSliceInTileColumn = sliceTileInfo->lastSliceOfTile && (sliceTileInfo->sliceTileY == m_hevcPicParams->num_tile_rows_minus1);
162 
163         uint32_t ctbSize    = 1 << (m_hevcPicParams->log2_diff_max_min_luma_coding_block_size + m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
164         uint32_t widthInPix = (1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) * (m_hevcPicParams->PicWidthInMinCbsY);
165         uint32_t widthInCtb = MOS_ROUNDUP_DIVIDE(widthInPix, ctbSize);
166 
167         // It is a hardware requirement that the first HCP_SLICE_STATE of the workload starts at LCU X,Y = 0,0.
168         // If first slice doesn't starts from (0,0), that means this is error bitstream.
169         if (dwSliceIndex == 0)
170         {
171             params.slicestartctbxOrSliceStartLcuXEncoder = 0;
172             params.slicestartctbyOrSliceStartLcuYEncoder = 0;
173         }
174         else
175         {
176             params.slicestartctbxOrSliceStartLcuXEncoder = sliceParams->slice_segment_address % widthInCtb;
177             params.slicestartctbyOrSliceStartLcuYEncoder = sliceParams->slice_segment_address / widthInCtb;
178         }
179 
180         if (bLastSlice)
181         {
182             params.nextslicestartctbxOrNextSliceStartLcuXEncoder = 0;
183             params.nextslicestartctbyOrNextSliceStartLcuYEncoder = 0;
184         }
185         else
186         {
187             params.nextslicestartctbxOrNextSliceStartLcuXEncoder = (sliceParams + 1)->slice_segment_address % widthInCtb;
188             params.nextslicestartctbyOrNextSliceStartLcuYEncoder = (sliceParams + 1)->slice_segment_address / widthInCtb;
189         }
190 
191         params.sliceType                  = sliceParams->LongSliceFlags.fields.slice_type;
192         params.lastsliceofpic             = bLastSlice;
193         params.dependentSliceFlag         = sliceParams->LongSliceFlags.fields.dependent_slice_segment_flag;
194         params.sliceTemporalMvpEnableFlag = sliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag;
195         params.sliceCbQpOffset            = sliceParams->slice_cb_qp_offset;
196         params.sliceCrQpOffset            = sliceParams->slice_cr_qp_offset;
197 
198         params.deblockingFilterDisable       = sliceParams->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag;
199         params.tcOffsetDiv2                  = sliceParams->slice_tc_offset_div2;
200         params.betaOffsetDiv2                = sliceParams->slice_beta_offset_div2;
201         params.loopFilterAcrossSlicesEnabled = sliceParams->LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag;
202         params.saoChromaFlag                 = sliceParams->LongSliceFlags.fields.slice_sao_chroma_flag;
203         params.saoLumaFlag                   = sliceParams->LongSliceFlags.fields.slice_sao_luma_flag;
204         params.mvdL1ZeroFlag                 = sliceParams->LongSliceFlags.fields.mvd_l1_zero_flag;
205 
206         uint8_t isLowDelay = 1;
207 
208         if (sliceParams->LongSliceFlags.fields.slice_type == SLICE_TYPE_I_SLICE)
209         {
210             isLowDelay = 0;
211         }
212         else
213         {
214             for (uint8_t i = 0; i < sliceParams->num_ref_idx_l0_active_minus1 + 1; i++)
215             {
216                 uint8_t refFrameID = sliceParams->RefPicList[0][i].FrameIdx;
217                 if (m_hevcPicParams->PicOrderCntValList[refFrameID] > m_hevcPicParams->CurrPicOrderCntVal)
218                 {
219                     isLowDelay = 0;
220                     break;
221                 }
222             }
223 
224             if (sliceParams->LongSliceFlags.fields.slice_type == SLICE_TYPE_B_SLICE)
225             {
226                 for (uint8_t i = 0; i < sliceParams->num_ref_idx_l1_active_minus1 + 1; i++)
227                 {
228                     uint8_t refFrameID = sliceParams->RefPicList[1][i].FrameIdx;
229                     if (m_hevcPicParams->PicOrderCntValList[refFrameID] > m_hevcPicParams->CurrPicOrderCntVal)
230                     {
231                         isLowDelay = 0;
232                         break;
233                     }
234                 }
235             }
236         }
237 
238         params.isLowDelay            = isLowDelay & 0x1;
239         params.collocatedFromL0Flag  = sliceParams->LongSliceFlags.fields.collocated_from_l0_flag;
240         params.chromalog2Weightdenom = sliceParams->luma_log2_weight_denom + sliceParams->delta_chroma_log2_weight_denom;
241         params.lumaLog2WeightDenom   = sliceParams->luma_log2_weight_denom;
242         params.cabacInitFlag         = sliceParams->LongSliceFlags.fields.cabac_init_flag;
243         params.maxmergeidx           = 5 - sliceParams->five_minus_max_num_merge_cand - 1;
244 
245         uint8_t collocatedRefIndex = 0, collocatedFrameIdx = 0, collocatedFromL0Flag = 0;
246 
247         if (sliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1)
248         {
249             // Get Collocated Picture POC
250             collocatedRefIndex   = sliceParams->collocated_ref_idx;
251             collocatedFrameIdx   = 0;
252             collocatedFromL0Flag = sliceParams->LongSliceFlags.fields.collocated_from_l0_flag;
253             if (sliceParams->LongSliceFlags.fields.slice_type == SLICE_TYPE_P_SLICE)
254             {
255                 collocatedFrameIdx = sliceParams->RefPicList[0][collocatedRefIndex].FrameIdx;
256             }
257             else if (sliceParams->LongSliceFlags.fields.slice_type == SLICE_TYPE_B_SLICE)
258             {
259                 collocatedFrameIdx = sliceParams->RefPicList[!collocatedFromL0Flag][collocatedRefIndex].FrameIdx;
260             }
261 
262             if (sliceParams->LongSliceFlags.fields.slice_type == SLICE_TYPE_I_SLICE)
263             {
264                 params.collocatedrefidx = 0;
265             }
266             else
267             {
268                 MHW_CHK_COND(*(pRefIdxMapping + collocatedFrameIdx) < 0, "Invalid parameter");
269                 params.collocatedrefidx = *(pRefIdxMapping + collocatedFrameIdx);
270             }
271         }
272         else
273         {
274             params.collocatedrefidx = 0;
275         }
276 
277         static uint8_t ucFirstInterSliceCollocatedFrameIdx   = 0;
278         static uint8_t ucFirstInterSliceCollocatedFromL0Flag = 0;
279         static bool    bFinishFirstInterSlice                = false;
280 
281         // Need to save the first interSlice collocatedRefIdx value to use on subsequent intra slices
282         // this is a HW requrement as collcoated ref fetching from memory may not be complete yet
283         if (dwSliceIndex == 0)
284         {
285             ucFirstInterSliceCollocatedFrameIdx   = 0;
286             ucFirstInterSliceCollocatedFromL0Flag = 0;
287             bFinishFirstInterSlice                = false;
288         }
289 
290         if ((!bFinishFirstInterSlice) &&
291             (sliceParams->LongSliceFlags.fields.slice_type != SLICE_TYPE_I_SLICE) &&
292             (sliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1))
293         {
294             ucFirstInterSliceCollocatedFrameIdx   = params.collocatedrefidx;
295             ucFirstInterSliceCollocatedFromL0Flag = params.collocatedFromL0Flag;
296             bFinishFirstInterSlice                = true;
297         }
298 
299         if (bFinishFirstInterSlice &&
300             ((sliceParams->LongSliceFlags.fields.slice_type == SLICE_TYPE_I_SLICE) ||
301                 (sliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 0)))
302         {
303             params.collocatedrefidx     = ucFirstInterSliceCollocatedFrameIdx;
304             params.collocatedFromL0Flag = ucFirstInterSliceCollocatedFromL0Flag;
305         }
306 
307         params.sliceheaderlength = sliceParams->ByteOffsetToSliceData;
308 
309         int32_t sliceQP        = sliceParams->slice_qp_delta + m_hevcPicParams->init_qp_minus26 + 26;
310         params.sliceqpSignFlag = (sliceQP >= 0) ? 0 : 1;
311         params.sliceqp         = ABS(sliceQP);
312 
313         bool bTileInSlice = sliceTileInfo->numTiles > 1;
314         if (bTileInSlice)
315         {
316             if (bLastSlice)
317             {
318                 params.nextslicestartctbxOrNextSliceStartLcuXEncoder = 0;
319                 params.nextslicestartctbyOrNextSliceStartLcuYEncoder = 0;
320             }
321         }
322         else
323         {
324             params.slicestartctbxOrSliceStartLcuXEncoder = sliceParams->slice_segment_address % widthInCtb;
325             params.slicestartctbyOrSliceStartLcuYEncoder = sliceParams->slice_segment_address / widthInCtb;
326         }
327 
328         auto hevcExtSliceParams = m_hevcRextSliceParams + sliceIdx;
329         if (m_hevcRextPicParams && hevcExtSliceParams)
330         {
331             // DW3[23]
332             if (m_hevcRextPicParams->PicRangeExtensionFlags.fields.chroma_qp_offset_list_enabled_flag)
333             {
334                 params.cuChromaQpOffsetEnable = hevcExtSliceParams->cu_chroma_qp_offset_enabled_flag;
335             }
336         }
337 
338         if (!bTileInSlice)
339         {
340             params.sliceheaderlength = sliceParams->ByteOffsetToSliceData;
341         }
342 
343         if ((dwSliceIndex == 0) || !params.dependentSliceFlag)
344         {
345             params.originalSliceStartCtbX = sliceParams->slice_segment_address % widthInCtb;
346             params.originalSliceStartCtbY = sliceParams->slice_segment_address / widthInCtb;
347         }
348         else
349         {
350             params.originalSliceStartCtbX = sliceTileInfo->origCtbX;
351             params.originalSliceStartCtbY = sliceTileInfo->origCtbY;
352         }
353 
354         if (m_hevcSccPicParams && hevcExtSliceParams)
355         {
356             if (m_hevcSccPicParams->PicSCCExtensionFlags.fields.pps_slice_act_qp_offsets_present_flag)
357             {
358                 // DW12
359                 params.sliceActYQpOffset  = hevcExtSliceParams->slice_act_y_qp_offset;
360                 params.sliceActCbQpOffset = hevcExtSliceParams->slice_act_cb_qp_offset;
361                 params.sliceActCrQpOffset = hevcExtSliceParams->slice_act_cr_qp_offset;
362             }
363 
364             params.useIntegerMvFlag = hevcExtSliceParams->use_integer_mv_flag;
365         }
366 
367         return MOS_STATUS_SUCCESS;
368     }
369 
SET_HCP_REF_IDX_STATE(uint32_t sliceIdx)370     MOS_STATUS HevcDecodeSlcPkt::SET_HCP_REF_IDX_STATE(uint32_t sliceIdx)
371     {
372         DECODE_FUNC_CALL();
373 
374         auto &params        = m_hcpItf->MHW_GETPAR_F(HCP_REF_IDX_STATE)();
375         params.bDecodeInUse = true;
376 
377         CODEC_HEVC_SLICE_PARAMS *sliceParams                           = m_hevcSliceParams + sliceIdx;
378         int8_t                  *pRefIdxMapping                        = 0;
379         int                      pocCurrPic                            = 0;
380         int32_t                  pocList[CODEC_MAX_NUM_REF_FRAME_HEVC] = {};
381         uint16_t                 refFieldPicFlag                       = 0;
382         uint16_t                 refBottomFieldFlag                    = 0;
383         CODEC_PICTURE            refPicList[2][CODEC_MAX_NUM_REF_FRAME_HEVC] = {};
384 
385         if (!m_hcpItf->IsHevcISlice(sliceParams->LongSliceFlags.fields.slice_type))
386         {
387             HevcReferenceFrames &refFrames = m_hevcBasicFeature->m_refFrames;
388             DECODE_CHK_STATUS(refFrames.FixSliceRefList(*m_hevcPicParams, *sliceParams));
389 
390             CODEC_PICTURE currPic  = m_hevcPicParams->CurrPic;
391             if (params.ucList != 1)
392             {
393                 params.ucNumRefForList = sliceParams->num_ref_idx_l0_active_minus1 + 1;
394             }
395 
396             DECODE_CHK_STATUS(MOS_SecureMemcpy(&refPicList, sizeof(refPicList), &sliceParams->RefPicList, sizeof(sliceParams->RefPicList)));
397 
398             void **hevcRefList = (void **)refFrames.m_refList;
399             pocCurrPic         = m_hevcPicParams->CurrPicOrderCntVal;
400 
401             for (uint8_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
402             {
403                 pocList[i] = m_hevcPicParams->PicOrderCntValList[i];
404             }
405 
406             pRefIdxMapping     = refFrames.m_refIdxMapping;
407             refFieldPicFlag    = m_hevcPicParams->RefFieldPicFlag;
408             refBottomFieldFlag = m_hevcPicParams->RefBottomFieldFlag;
409 
410             // Need to add an empty HCP_REF_IDX_STATE_CMD for dummy reference on I-Frame
411             // ucNumRefForList could be 0 for encode
412             MHW_ASSERT(currPic.FrameIdx != 0x7F);
413 
414             params.numRefIdxLRefpiclistnumActiveMinus1 = params.ucNumRefForList - 1;
415 
416             for (uint8_t i = 0; i < params.ucNumRefForList; i++)
417             {
418                 uint8_t refFrameIDx = refPicList[params.ucList][i].FrameIdx;
419                 if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC)
420                 {
421                     MHW_ASSERT(*(pRefIdxMapping + refFrameIDx) >= 0);
422 
423                     params.listEntryLxReferencePictureFrameIdRefaddr07[i] = *(pRefIdxMapping + refFrameIDx);
424                     int32_t pocDiff                                       = pocCurrPic - pocList[refFrameIDx];
425                     params.referencePictureTbValue[i]                     = CodecHal_Clip3(-128, 127, pocDiff);
426                     CODEC_REF_LIST **refList                              = (CODEC_REF_LIST **)hevcRefList;
427                     params.longtermreference[i]                           = CodecHal_PictureIsLongTermRef(refList[currPic.FrameIdx]->RefList[refFrameIDx]);
428                     params.fieldPicFlag[i]                                = (refFieldPicFlag >> refFrameIDx) & 0x01;
429                     params.bottomFieldFlag[i]                             = ((refBottomFieldFlag >> refFrameIDx) & 0x01) ? 0 : 1;
430                 }
431                 else
432                 {
433                     params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0;
434                     params.referencePictureTbValue[i]                     = 0;
435                     params.longtermreference[i]                           = false;
436                     params.fieldPicFlag[i]                                = 0;
437                     params.bottomFieldFlag[i]                             = 0;
438                 }
439             }
440         }
441         else if (m_hevcBasicFeature->m_useDummyReference && !m_osInterface->bSimIsActive)
442         {
443             params.bDummyReference = true;
444         }
445 
446         return MOS_STATUS_SUCCESS;
447     }
448 
SET_HCP_WEIGHTOFFSET_STATE(uint32_t sliceIdx)449     MOS_STATUS HevcDecodeSlcPkt::SET_HCP_WEIGHTOFFSET_STATE(uint32_t sliceIdx)
450     {
451         DECODE_FUNC_CALL();
452 
453         auto &params = m_hcpItf->MHW_GETPAR_F(HCP_WEIGHTOFFSET_STATE)();
454 
455         CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
456 
457         bool weightedPred   = m_hevcPicParams->weighted_pred_flag   && m_hcpItf->IsHevcPSlice(sliceParams->LongSliceFlags.fields.slice_type);
458         bool weightedBiPred = m_hevcPicParams->weighted_bipred_flag && m_hcpItf->IsHevcBSlice(sliceParams->LongSliceFlags.fields.slice_type);
459 
460         if (weightedPred || weightedBiPred)
461         {
462             params.ucList = 0;
463 
464             DECODE_CHK_STATUS(MOS_SecureMemcpy(
465                 &params.LumaWeights[0], sizeof(params.LumaWeights[0]), &sliceParams->delta_luma_weight_l0, sizeof(sliceParams->delta_luma_weight_l0)));
466 
467             DECODE_CHK_STATUS(MOS_SecureMemcpy(
468                 &params.LumaWeights[1], sizeof(params.LumaWeights[1]), &sliceParams->delta_luma_weight_l1, sizeof(sliceParams->delta_luma_weight_l1)));
469 
470             PCODEC_HEVC_EXT_SLICE_PARAMS slcRextParams = (m_hevcRextSliceParams == nullptr) ? nullptr : (m_hevcRextSliceParams + sliceIdx);
471 
472             if (slcRextParams != nullptr)
473             {
474                 DECODE_CHK_STATUS(MOS_SecureMemcpy(
475                     &params.LumaOffsets[0], sizeof(params.LumaOffsets[0]), &slcRextParams->luma_offset_l0, sizeof(slcRextParams->luma_offset_l0)));
476 
477                 DECODE_CHK_STATUS(MOS_SecureMemcpy(
478                     &params.LumaOffsets[1], sizeof(params.LumaOffsets[1]), &slcRextParams->luma_offset_l1, sizeof(slcRextParams->luma_offset_l1)));
479 
480                 DECODE_CHK_STATUS(MOS_SecureMemcpy(
481                     &params.ChromaOffsets[0], sizeof(params.ChromaOffsets[0]), &slcRextParams->ChromaOffsetL0, sizeof(slcRextParams->ChromaOffsetL0)));
482 
483                 DECODE_CHK_STATUS(MOS_SecureMemcpy(
484                     &params.ChromaOffsets[1], sizeof(params.ChromaOffsets[1]), &slcRextParams->ChromaOffsetL1, sizeof(slcRextParams->ChromaOffsetL1)));
485             }
486             else
487             {
488                 for (uint32_t i = 0; i < 15; i++)
489                 {
490                     params.LumaOffsets[0][i] = (int16_t)sliceParams->luma_offset_l0[i];
491                     params.LumaOffsets[1][i] = (int16_t)sliceParams->luma_offset_l1[i];
492 
493                     for (uint32_t j = 0; j < 2; j++)
494                     {
495                         params.ChromaOffsets[0][i][j] = (int16_t)sliceParams->ChromaOffsetL0[i][j];
496                         params.ChromaOffsets[1][i][j] = (int16_t)sliceParams->ChromaOffsetL1[i][j];
497                     }
498                 }
499             }
500 
501             DECODE_CHK_STATUS(MOS_SecureMemcpy(
502                 &params.ChromaWeights[0], sizeof(params.ChromaWeights[0]), &sliceParams->delta_chroma_weight_l0, sizeof(sliceParams->delta_chroma_weight_l0)));
503 
504             DECODE_CHK_STATUS(MOS_SecureMemcpy(
505                 &params.ChromaWeights[1], sizeof(params.ChromaWeights[1]), &sliceParams->delta_chroma_weight_l1, sizeof(sliceParams->delta_chroma_weight_l1)));
506         }
507 
508         return MOS_STATUS_SUCCESS;
509     }
510 
AddCmd_HCP_WEIGHTOFFSET_STATE(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx)511     MOS_STATUS HevcDecodeSlcPkt::AddCmd_HCP_WEIGHTOFFSET_STATE(
512         MOS_COMMAND_BUFFER &cmdBuffer,
513         uint32_t            sliceIdx)
514     {
515         DECODE_FUNC_CALL();
516 
517         CODEC_HEVC_SLICE_PARAMS *sliceParams  = m_hevcSliceParams + sliceIdx;
518 
519         bool weightedPred   = m_hevcPicParams->weighted_pred_flag   && m_hcpItf->IsHevcPSlice(sliceParams->LongSliceFlags.fields.slice_type);
520         bool weightedBiPred = m_hevcPicParams->weighted_bipred_flag && m_hcpItf->IsHevcBSlice(sliceParams->LongSliceFlags.fields.slice_type);
521 
522         if (weightedPred || weightedBiPred)
523         {
524             auto &params = m_hcpItf->MHW_GETPAR_F(HCP_WEIGHTOFFSET_STATE)();
525             params       = {};
526 
527             DECODE_CHK_STATUS(SET_HCP_WEIGHTOFFSET_STATE(sliceIdx));
528             DECODE_CHK_STATUS(m_hcpItf->MHW_ADDCMD_F(HCP_WEIGHTOFFSET_STATE)(&cmdBuffer));
529 
530             if (weightedBiPred)
531             {
532                 params.ucList = 1;
533                 DECODE_CHK_STATUS(m_hcpItf->MHW_ADDCMD_F(HCP_WEIGHTOFFSET_STATE)(&cmdBuffer));
534             }
535         }
536 
537         return MOS_STATUS_SUCCESS;
538     }
539 
SET_HCP_BSD_OBJECT(uint32_t sliceIdx,uint32_t subTileIdx)540     MOS_STATUS HevcDecodeSlcPkt::SET_HCP_BSD_OBJECT(uint32_t sliceIdx, uint32_t subTileIdx)
541     {
542         DECODE_FUNC_CALL();
543 
544         auto &params = m_hcpItf->MHW_GETPAR_F(HCP_BSD_OBJECT)();
545 
546         const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
547         DECODE_CHK_NULL(sliceTileInfo);
548         DECODE_CHK_STATUS(ValidateSubTileIdx(*sliceTileInfo, subTileIdx));
549 
550         CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
551 
552         if (sliceTileInfo->numTiles > 1)
553         {
554             params.bsdDataLength      = sliceTileInfo->tileArrayBuf[subTileIdx].bsdLength;
555             params.bsdDataStartOffset = sliceParams->slice_data_offset + sliceTileInfo->tileArrayBuf[subTileIdx].bsdOffset;
556         }
557         else
558         {
559             params.bsdDataLength      = sliceParams->slice_data_size;
560             params.bsdDataStartOffset = sliceParams->slice_data_offset;
561         }
562 
563         return MOS_STATUS_SUCCESS;
564     }
565 
AddCmd_HCP_BSD_OBJECT(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx,uint32_t subTileIdx)566     MOS_STATUS HevcDecodeSlcPkt::AddCmd_HCP_BSD_OBJECT(
567         MOS_COMMAND_BUFFER &cmdBuffer,
568         uint32_t            sliceIdx,
569         uint32_t            subTileIdx)
570     {
571         DECODE_FUNC_CALL();
572 
573         auto &params = m_hcpItf->MHW_GETPAR_F(HCP_BSD_OBJECT)();
574         params       = {};
575 
576         DECODE_CHK_STATUS(SET_HCP_BSD_OBJECT(sliceIdx, subTileIdx));
577         DECODE_CHK_STATUS(m_hcpItf->MHW_ADDCMD_F(HCP_BSD_OBJECT)(&cmdBuffer));
578 
579         return MOS_STATUS_SUCCESS;
580     }
581 
AddHcpCpState(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx,uint32_t subTileIdx)582     MOS_STATUS HevcDecodeSlcPkt::AddHcpCpState(MOS_COMMAND_BUFFER &cmdBuffer, uint32_t sliceIdx, uint32_t subTileIdx)
583     {
584         DECODE_FUNC_CALL();
585 
586         PMOS_RESOURCE buffer      = &(m_hevcBasicFeature->m_resDataBuffer.OsResource);
587         uint32_t      startoffset = m_hevcSliceParams->slice_data_offset;
588 
589         const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
590         DECODE_CHK_NULL(sliceTileInfo);
591         DECODE_CHK_STATUS(ValidateSubTileIdx(*sliceTileInfo, subTileIdx));
592 
593         CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcSliceParams + sliceIdx;
594 
595         if (sliceTileInfo->numTiles > 1)
596         {
597             startoffset = sliceParams->slice_data_offset + sliceTileInfo->tileArrayBuf[subTileIdx].bsdOffset;
598         }
599         else
600         {
601             startoffset = sliceParams->slice_data_offset;
602         }
603         if(m_decodecp)
604         {
605             DECODE_CHK_STATUS(m_decodecp->AddHcpState(&cmdBuffer, buffer, m_hevcSliceParams->slice_data_size, startoffset, sliceIdx));
606         }
607 
608         return MOS_STATUS_SUCCESS;
609     }
610 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)611     MOS_STATUS HevcDecodeSlcPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
612     {
613         DECODE_FUNC_CALL();
614 
615         commandBufferSize      = m_sliceStatesSize;
616         requestedPatchListSize = m_slicePatchListSize;
617         return MOS_STATUS_SUCCESS;
618     }
619 
CalculateSliceStateCommandSize()620     MOS_STATUS HevcDecodeSlcPkt::CalculateSliceStateCommandSize()
621     {
622         DECODE_FUNC_CALL();
623 
624         // Slice Level Commands
625         DECODE_CHK_STATUS(m_hwInterface->GetHcpPrimitiveCommandSize(m_hevcBasicFeature->m_mode,
626                                                                      &m_sliceStatesSize,
627                                                                      &m_slicePatchListSize,
628                                                                      false));
629 
630         return MOS_STATUS_SUCCESS;
631     }
632 
633 }
634