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_vvc_slice_packet.cpp
24 //! \brief    Defines the interface for VVC decode slice packet
25 //!
26 #include "decode_vvc_slice_packet.h"
27 
28 namespace decode
29 {
Init()30     MOS_STATUS VvcDecodeSlicePkt::Init()
31     {
32         DECODE_FUNC_CALL();
33 
34         DECODE_CHK_NULL(m_featureManager);
35         DECODE_CHK_NULL(m_hwInterface);
36         DECODE_CHK_NULL(m_osInterface);
37         DECODE_CHK_NULL(m_vvcPipeline);
38 
39         m_vvcBasicFeature = dynamic_cast<VvcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
40         DECODE_CHK_NULL(m_vvcBasicFeature);
41 
42         m_allocator = m_pipeline ->GetDecodeAllocator();
43         DECODE_CHK_NULL(m_allocator);
44         m_vvcCpSubPkt = m_vvcPipeline->GetSubPacket(DecodePacketId(m_vvcPipeline, vvcCpSubPacketId));
45         m_decodecp    = m_pipeline->GetDecodeCp();
46 
47         DECODE_CHK_STATUS(CalculateSliceStateCommandSize());
48 
49         return MOS_STATUS_SUCCESS;
50     }
51 
Prepare()52     MOS_STATUS VvcDecodeSlicePkt::Prepare()
53     {
54         DECODE_FUNC_CALL();
55 
56         DECODE_CHK_NULL(m_vvcBasicFeature->m_vvcPicParams);
57 
58         m_vvcPicParams = m_vvcBasicFeature->m_vvcPicParams;
59 
60         return MOS_STATUS_SUCCESS;
61     }
62 
GetPartitionInfo(uint16_t sliceIdx)63     MOS_STATUS VvcDecodeSlicePkt::GetPartitionInfo(uint16_t sliceIdx)
64     {
65         DECODE_FUNC_CALL()
66 
67         DECODE_CHK_NULL(m_vvcBasicFeature);
68         DECODE_CHK_NULL(m_vvcPicParams);
69 
70         DECODE_CHK_NULL(m_vvcBasicFeature->m_vvcSliceParams);
71 
72         m_curSliceParams = &m_vvcBasicFeature->m_vvcSliceParams[sliceIdx];
73 
74         //current subPic and slice
75         if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
76         {
77             m_subPicParams  = nullptr;
78             m_sliceDesc     = &m_vvcBasicFeature->m_sliceDesc[sliceIdx];
79         }
80         else if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsSingleSlicePerSubpicFlag)
81         {
82             if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && m_vvcPicParams->m_spsNumSubpicsMinus1 > 0)
83             {
84                 DECODE_CHK_NULL(m_vvcBasicFeature->m_subPicParams);
85                 uint16_t subPicId           = m_curSliceParams->m_shSubpicId;
86                 uint16_t subPicIdx          = m_vvcBasicFeature->GetSubPicIdxFromSubPicId(subPicId);
87                 uint16_t sliceIdxInSubpic   = m_curSliceParams->m_shSliceAddress;
88                 uint16_t sliceIdxInPic      = m_vvcBasicFeature->m_subPicParams[subPicIdx].m_sliceIdx[sliceIdxInSubpic];
89 
90                 m_subPicParams  = &m_vvcBasicFeature->m_subPicParams[subPicIdx];
91                 m_sliceDesc     = &m_vvcBasicFeature->m_sliceDesc[sliceIdxInPic];
92             }
93             else
94             {
95                 uint16_t subPicId           = m_curSliceParams->m_shSubpicId;
96                 DECODE_ASSERT(subPicId == 0);
97                 uint16_t sliceIdxInSubpic   = m_curSliceParams->m_shSliceAddress;
98 
99                 m_subPicParams  = nullptr;
100                 m_sliceDesc     = &m_vvcBasicFeature->m_sliceDesc[sliceIdxInSubpic];
101             }
102         }
103         else
104         {
105             if (m_vvcPicParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && m_vvcPicParams->m_spsNumSubpicsMinus1 > 0)
106             {
107                 DECODE_CHK_NULL(m_vvcBasicFeature->m_subPicParams);
108                 uint16_t subPicId           = m_curSliceParams->m_shSubpicId;
109                 uint16_t subPicIdx          = m_vvcBasicFeature->GetSubPicIdxFromSubPicId(subPicId);
110                 DECODE_ASSERT(m_curSliceParams->m_shSliceAddress == 0);
111 
112                 m_subPicParams  = &m_vvcBasicFeature->m_subPicParams[subPicIdx];
113                 m_sliceDesc     = &m_vvcBasicFeature->m_sliceDesc[subPicIdx];
114             }
115             else
116             {
117                 m_subPicParams  = nullptr;
118                 DECODE_ASSERT(m_curSliceParams->m_shSubpicId == 0);
119                 DECODE_ASSERT(m_curSliceParams->m_shSliceAddress == 0);
120                 m_sliceDesc     = &m_vvcBasicFeature->m_sliceDesc[0];
121             }
122         }
123 
124         //The last slice flag
125         if (m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
126         {
127             uint32_t endTileX = m_sliceDesc->m_startTileX + m_sliceDesc->m_sliceWidthInTiles - 1;
128             if (endTileX >= vvcMaxTileColNum)
129             {
130                 DECODE_ASSERTMESSAGE("Right most tile column of the slice is incorrect!\n");
131                 return MOS_STATUS_INVALID_PARAMETER;
132             }
133             uint32_t sliceWidthInCtb = m_vvcBasicFeature->m_tileCol[endTileX].m_endCtbX + 1 - m_vvcBasicFeature->m_tileCol[m_sliceDesc->m_startTileX].m_startCtbX;
134             uint32_t sliceEndCtbX = m_sliceDesc->m_sliceStartCtbx + sliceWidthInCtb - 1;
135             uint32_t sliceEndCtbY = 0;
136             if (m_sliceDesc->m_multiSlicesInTileFlag)
137             {
138                 sliceEndCtbY = m_sliceDesc->m_sliceStartCtby + m_sliceDesc->m_sliceHeightInCtu - 1;
139             }
140             else
141             {
142                 uint32_t endTileY = m_sliceDesc->m_startTileY + m_sliceDesc->m_sliceHeightInTiles - 1;
143                 if (endTileY >= vvcMaxTileRowNum)
144                 {
145                     DECODE_ASSERTMESSAGE("Bottom most tile row of the slice is incorrect!\n");
146                     return MOS_STATUS_INVALID_PARAMETER;
147                 }
148                 uint32_t sliceHeightInCtb = m_vvcBasicFeature->m_tileRow[endTileY].m_endCtbY + 1 - m_vvcBasicFeature->m_tileRow[m_sliceDesc->m_startTileY].m_startCtbY;
149                 sliceEndCtbY = m_sliceDesc->m_sliceStartCtby + sliceHeightInCtb - 1;
150             }
151 
152             m_sliceDesc->m_sliceEndCtbx = sliceEndCtbX;
153             m_sliceDesc->m_sliceEndCtby = sliceEndCtbY;
154 
155             m_lastSliceOfPic = ((sliceEndCtbX == m_vvcBasicFeature->m_picWidthInCtu - 1) &&
156                 (sliceEndCtbY == m_vvcBasicFeature->m_picHeightInCtu - 1)) ? 1 : 0;
157         }
158         else
159         {
160             uint16_t tileOffset = m_curSliceParams->m_shSliceAddress;
161             uint16_t tileNum = m_curSliceParams->m_shNumTilesInSliceMinus1+1;
162             m_lastSliceOfPic = (tileOffset + tileNum == m_vvcBasicFeature->m_tileCols * m_vvcBasicFeature->m_tileRows) ? 1 : 0;
163         }
164         return MOS_STATUS_SUCCESS;
165     }
166 
Execute(MOS_COMMAND_BUFFER & cmdBuffer,uint16_t sliceIdx)167     MOS_STATUS VvcDecodeSlicePkt::Execute(MOS_COMMAND_BUFFER& cmdBuffer, uint16_t sliceIdx)
168     {
169         DECODE_FUNC_CALL()
170 
171         DECODE_CHK_NULL(m_vvcBasicFeature);
172         DECODE_CHK_NULL(m_vvcPicParams);
173 
174         DECODE_CHK_STATUS(GetPartitionInfo(sliceIdx));
175 
176         // Slice Level Commands
177         SETPAR_AND_ADDCMD(VVCP_SLICE_STATE, m_vvcpItf, &cmdBuffer);
178         DECODE_CHK_STATUS(AddAllCmds_VVCP_REF_IDX_STATE(cmdBuffer));
179         DECODE_CHK_STATUS(AddAllCmds_VVCP_WEIGHTOFFSET_STATE(cmdBuffer));
180         // CP commands
181         if (m_vvcCpSubPkt != nullptr && m_decodecp != nullptr)
182         {
183             DECODE_CHK_STATUS(m_decodecp->ExecuteDecodeCpIndSubPkt(m_vvcCpSubPkt, m_vvcBasicFeature->m_mode, cmdBuffer, sliceIdx));
184         }
185         SETPAR_AND_ADDCMD(VVCP_BSD_OBJECT, m_vvcpItf, &cmdBuffer);
186 
187         // Tile level commands
188         AddAllCmds_VVCP_TILE_CODING(cmdBuffer);
189 
190         return MOS_STATUS_SUCCESS;
191     }
192 
ConstructLmcsReshaper() const193     MOS_STATUS VvcDecodeSlicePkt::ConstructLmcsReshaper() const
194     {
195         DECODE_FUNC_CALL()
196 
197         int32_t reshapeLUTSize = 1 << (m_vvcPicParams->m_spsBitdepthMinus8 + 8);
198         int32_t pwlFwdLUTsize = vvcPicCodeCwBins;
199         int32_t pwlFwdBinLen = reshapeLUTSize / vvcPicCodeCwBins;
200         uint16_t initCW = (uint16_t)pwlFwdBinLen;
201 
202         CodecVvcLmcsData* lmcsData = &m_vvcBasicFeature->m_lmcsApsArray[m_vvcPicParams->m_phLmcsApsId];
203         ApsLmcsReshapeInfo* sliceReshapeInfo = &m_vvcBasicFeature->m_lmcsReshaperInfo[m_vvcPicParams->m_phLmcsApsId];
204         uint32_t reshaperModelMaxBinIdx = vvcPicCodeCwBins - 1 - lmcsData->m_lmcsDeltaMaxBinIdx;
205 
206         for (int32_t i = 0; i < lmcsData->m_lmcsMinBinIdx; i++)
207         {
208             sliceReshapeInfo->m_lmcsCW[i] = 0;
209         }
210         for (auto i = reshaperModelMaxBinIdx + 1; i < vvcPicCodeCwBins; i++)
211         {
212             sliceReshapeInfo->m_lmcsCW[i] = 0;
213         }
214         for (auto i = lmcsData->m_lmcsMinBinIdx; i <= reshaperModelMaxBinIdx; i++)
215         {
216             sliceReshapeInfo->m_lmcsCW[i] = (uint16_t)(lmcsData->m_lmcsDeltaCW[i] + (int32_t)initCW);
217         }
218 
219         for (auto i = 0; i < pwlFwdLUTsize; i++)
220         {
221             sliceReshapeInfo->m_lmcsPivot[i + 1] = sliceReshapeInfo->m_lmcsPivot[i] + sliceReshapeInfo->m_lmcsCW[i];
222             sliceReshapeInfo->m_scaleCoeff[i] = ((int32_t)sliceReshapeInfo->m_lmcsCW[i] * (1 << vvcFpPrec) + (1 << ((int32_t)log2(pwlFwdBinLen) - 1))) >> (int32_t)log2(pwlFwdBinLen);
223             if (sliceReshapeInfo->m_lmcsCW[i] == 0)
224             {
225                 sliceReshapeInfo->m_invScaleCoeff[i] = 0;
226                 sliceReshapeInfo->m_chromaScaleCoeff[i] = 1 << vvcCscaleFpPrec;
227             }
228             else
229             {
230                 int32_t lmcsCwCrs = sliceReshapeInfo->m_lmcsCW[i] + lmcsData->m_lmcsDeltaCrs;
231                 if (lmcsCwCrs < (initCW >> 3) || (lmcsCwCrs > (initCW << 3) -1))
232                 {
233                     DECODE_ASSERTMESSAGE("Error concealed: force sh_lmcs_used_flag = 0 when (lmcsCW[ i ] + lmcsDeltaCrs) out of the range (OrgCW >> 3) to ((OrgCW << 3) - 1) inclusive.\n");
234                     m_curSliceParams->m_longSliceFlags.m_fields.m_shLmcsUsedFlag = 0;
235                 }
236                 else
237                 {
238                     sliceReshapeInfo->m_invScaleCoeff[i] = (int32_t)(initCW * (1 << vvcFpPrec) / sliceReshapeInfo->m_lmcsCW[i]);
239                     sliceReshapeInfo->m_chromaScaleCoeff[i] = (int32_t)(initCW * (1 << vvcFpPrec) / (sliceReshapeInfo->m_lmcsCW[i] + lmcsData->m_lmcsDeltaCrs));
240                 }
241             }
242         }
243 
244         //mark the flag
245         m_vvcBasicFeature->m_lmcsReshaperReady |= 1 << m_vvcPicParams->m_phLmcsApsId;
246 
247         return MOS_STATUS_SUCCESS;
248     }
249 
CalcRefIdxSymLx(int8_t & RefIdxSymL0,int8_t & RefIdxSymL1)250     MOS_STATUS VvcDecodeSlicePkt::CalcRefIdxSymLx(int8_t &RefIdxSymL0, int8_t &RefIdxSymL1)
251     {
252         DECODE_FUNC_CALL();
253 
254         //Calc low delay flag
255         bool lowDelay = true;
256         int32_t  currPOC = m_vvcPicParams->m_picOrderCntVal;
257         uint8_t  refIdx = 0;
258 
259         if (!m_vvcpItf->IsVvcISlice(m_curSliceParams->m_shSliceType))
260         {
261             for (refIdx = 0; refIdx < m_curSliceParams->m_numRefIdxActive[0] && lowDelay; refIdx++)
262             {
263                 uint8_t refPicIdx = m_curSliceParams->m_refPicList[0][refIdx].FrameIdx;
264 
265                 if (m_vvcPicParams->m_refFramePocList[refPicIdx] > currPOC)
266                 {
267                     lowDelay = false;
268                 }
269             }
270             if (m_vvcpItf->IsVvcBSlice(m_curSliceParams->m_shSliceType))
271             {
272                 for (refIdx = 0; refIdx < m_curSliceParams->m_numRefIdxActive[1] && lowDelay; refIdx++)
273                 {
274                     uint8_t refPicIdx = m_curSliceParams->m_refPicList[1][refIdx].FrameIdx;
275                     if (m_vvcPicParams->m_refFramePocList[refPicIdx] > currPOC)
276                     {
277                         lowDelay = false;
278                     }
279                 }
280             }
281         }
282 
283         //Calc RefIdxSymL0/RefIdxSymL1
284         if (m_vvcPicParams->m_spsFlags1.m_fields.m_spsSmvdEnabledFlag && lowDelay == false
285             && m_vvcPicParams->m_phFlags.m_fields.m_phMvdL1ZeroFlag == false)
286         {
287             int32_t forwardPOC = currPOC;
288             int32_t backwardPOC = currPOC;
289             uint8_t ref = 0;
290             int8_t refIdx0 = -1;
291             int8_t refIdx1 = -1;
292 
293             // search nearest forward POC in List 0
294             for ( ref = 0; ref < m_curSliceParams->m_numRefIdxActive[0]; ref++ )
295             {
296                 if (m_curSliceParams->m_refPicList[0][ref].FrameIdx >= vvcMaxNumRefFrame)
297                 {
298                     return MOS_STATUS_INVALID_PARAMETER;
299                 }
300                 int32_t poc = m_vvcPicParams->m_refFramePocList[m_curSliceParams->m_refPicList[0][ref].FrameIdx];
301 
302                 const bool isRefLongTerm = (m_curSliceParams->m_refPicList[0][ref].PicFlags == PICTURE_LONG_TERM_REFERENCE) ? true : false;
303                 if ( poc < currPOC && (poc > forwardPOC || refIdx0 == -1) && !isRefLongTerm )
304                 {
305                     forwardPOC = poc;
306                     refIdx0 = ref;
307                 }
308             }
309 
310             // search nearest backward POC in List 1
311             for ( ref = 0; ref < m_curSliceParams->m_numRefIdxActive[1]; ref++ )
312             {
313                 if (m_curSliceParams->m_refPicList[1][ref].FrameIdx >= vvcMaxNumRefFrame)
314                 {
315                     return MOS_STATUS_INVALID_PARAMETER;
316                 }
317                 int32_t poc = m_vvcPicParams->m_refFramePocList[m_curSliceParams->m_refPicList[1][ref].FrameIdx];
318 
319 
320                 const bool isRefLongTerm = (m_curSliceParams->m_refPicList[1][ref].PicFlags == PICTURE_LONG_TERM_REFERENCE) ? true : false;
321                 if ( poc > currPOC && (poc < backwardPOC || refIdx1 == -1) && !isRefLongTerm )
322                 {
323                     backwardPOC = poc;
324                     refIdx1 = ref;
325                 }
326             }
327 
328             if ( !(forwardPOC < currPOC && backwardPOC > currPOC) )
329             {
330                 forwardPOC = currPOC;
331                 backwardPOC = currPOC;
332                 refIdx0 = -1;
333                 refIdx1 = -1;
334 
335                 // search nearest backward POC in List 0
336                 for ( ref = 0; ref < m_curSliceParams->m_numRefIdxActive[0]; ref++ )
337                 {
338                     if (m_curSliceParams->m_refPicList[0][ref].FrameIdx >= vvcMaxNumRefFrame)
339                     {
340                         return MOS_STATUS_INVALID_PARAMETER;
341                     }
342                     int32_t poc = m_vvcPicParams->m_refFramePocList[m_curSliceParams->m_refPicList[0][ref].FrameIdx];
343 
344                     const bool isRefLongTerm = (m_curSliceParams->m_refPicList[0][ref].PicFlags == PICTURE_LONG_TERM_REFERENCE) ? true : false;
345                     if ( poc > currPOC && (poc < backwardPOC || refIdx0 == -1) && !isRefLongTerm )
346                     {
347                         backwardPOC = poc;
348                         refIdx0 = ref;
349                     }
350                 }
351 
352                 // search nearest forward POC in List 1
353                 for ( ref = 0; ref < m_curSliceParams->m_numRefIdxActive[1]; ref++ )
354                 {
355                     if (m_curSliceParams->m_refPicList[1][ref].FrameIdx >= vvcMaxNumRefFrame)
356                     {
357                         return MOS_STATUS_INVALID_PARAMETER;
358                     }
359                     int32_t poc = m_vvcPicParams->m_refFramePocList[m_curSliceParams->m_refPicList[1][ref].FrameIdx];
360 
361                     const bool isRefLongTerm = (m_curSliceParams->m_refPicList[1][ref].PicFlags == PICTURE_LONG_TERM_REFERENCE) ? true : false;
362                     if ( poc < currPOC && (poc > forwardPOC || refIdx1 == -1) && !isRefLongTerm )
363                     {
364                         forwardPOC = poc;
365                         refIdx1 = ref;
366                     }
367                 }
368             }
369 
370             if ( forwardPOC < currPOC && backwardPOC > currPOC )
371             {
372                 RefIdxSymL0 = refIdx0;
373                 RefIdxSymL1 = refIdx1;
374             }
375             else
376             {
377                 RefIdxSymL0 = -1;
378                 RefIdxSymL1 = -1;
379             }
380         }
381         else
382         {
383             RefIdxSymL0 = -1;
384             RefIdxSymL1 = -1;
385         }
386 
387         return MOS_STATUS_SUCCESS;
388     }
389 
SetRefIdxStateParams()390     MOS_STATUS VvcDecodeSlicePkt::SetRefIdxStateParams()
391     {
392         DECODE_FUNC_CALL();
393 
394         auto &params = m_vvcpItf->MHW_GETPAR_F(VVCP_REF_IDX_STATE)();
395         params       = {};
396 
397         if (!m_vvcpItf->IsVvcISlice(m_curSliceParams->m_shSliceType))
398         {
399             params.listIdx = 0;
400             params.numRefForList = m_curSliceParams->m_numRefIdxActive[0];
401 
402             //Derive RefIdxSymL0/RefIdxSymL1
403             DECODE_CHK_STATUS(CalcRefIdxSymLx(params.refIdxSymLx[0], params.refIdxSymLx[1]));
404 
405             DECODE_CHK_STATUS(MOS_SecureMemcpy(&params.refPicList, sizeof(params.refPicList),
406                                                 &m_curSliceParams->m_refPicList, sizeof(m_curSliceParams->m_refPicList)));
407 
408             for (auto i = 0; i < 2; i++)
409             {
410                 for (auto j = 0; j < m_curSliceParams->m_numRefIdxActive[i]; j++)
411                 {
412                     // Short term reference flag
413                     params.stRefPicFlag[i][j] = (m_curSliceParams->m_refPicList[i][j].PicFlags == PICTURE_SHORT_TERM_REFERENCE) ? true : false;
414 
415                     // Derive RprConstraintsActiveFlag and Unavailable ref pic flag
416                     uint8_t refPicIdx = m_curSliceParams->m_refPicList[i][j].FrameIdx;
417                     if (refPicIdx < vvcMaxNumRefFrame)
418                     {
419                         uint8_t refFrameIdx = m_vvcPicParams->m_refFrameList[refPicIdx].FrameIdx;
420                         DECODE_CHK_STATUS(m_vvcBasicFeature->m_refFrames.CalcRprConstraintsActiveFlag(refFrameIdx, params.rprConstraintsActiveFlag[i][j]));
421                         params.unavailableRefPic[i][j] = (m_vvcPicParams->m_refFrameList[refPicIdx].PicFlags == PICTURE_UNAVAILABLE_FRAME) ? true : false;
422                     }
423                     else
424                     {
425                         return MOS_STATUS_INVALID_PARAMETER;
426                     }
427 
428                     // DiffPicOrderCnt
429                     DECODE_ASSERT(m_curSliceParams->m_refPicList[i][j].FrameIdx < vvcMaxNumRefFrame);//TODO: unavailable? associated flag?
430                     int32_t refPoc = m_vvcPicParams->m_refFramePocList[m_curSliceParams->m_refPicList[i][j].FrameIdx]; //TODO: For error check, compare the poc from ref list and the value here.
431                     params.diffPicOrderCnt[i][j] = m_vvcPicParams->m_picOrderCntVal - refPoc;
432                 }
433             }
434         }
435 
436         return MOS_STATUS_SUCCESS;
437     }
438 
IsTileInRasterSlice(const uint32_t tileRow,const uint32_t tileCol) const439     bool VvcDecodeSlicePkt::IsTileInRasterSlice(const uint32_t tileRow, const uint32_t tileCol) const
440     {
441         const uint32_t startTileIdx = m_curSliceParams->m_shSliceAddress;
442         const uint32_t endTileIdx   = startTileIdx + m_curSliceParams->m_shNumTilesInSliceMinus1;
443 
444         const uint32_t tileIdx = tileRow * m_vvcBasicFeature->m_tileCols + tileCol;
445         return ((tileIdx >= startTileIdx) && (tileIdx <= endTileIdx));
446     }
447 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)448     MOS_STATUS VvcDecodeSlicePkt::CalculateCommandSize(
449         uint32_t &commandBufferSize,
450         uint32_t &requestedPatchListSize)
451     {
452         DECODE_FUNC_CALL();
453 
454         commandBufferSize      = m_sliceStatesSize;
455         requestedPatchListSize = m_slicePatchListSize;
456 
457         return MOS_STATUS_SUCCESS;
458     }
459 
CalculateTileCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)460     MOS_STATUS VvcDecodeSlicePkt::CalculateTileCommandSize(
461         uint32_t &commandBufferSize,
462         uint32_t &requestedPatchListSize)
463     {
464         DECODE_FUNC_CALL();
465 
466         commandBufferSize      = m_tileStateSize;
467         requestedPatchListSize = m_tilePatchListSize;
468 
469         return MOS_STATUS_SUCCESS;
470     }
471 
CalculateSliceStateCommandSize()472     MOS_STATUS VvcDecodeSlicePkt::CalculateSliceStateCommandSize()
473     {
474         DECODE_FUNC_CALL();
475 
476         // Slice Level Commands
477         DECODE_CHK_STATUS(m_hwInterface->GetVvcpPrimitiveCommandSize(
478                                         m_vvcBasicFeature->m_mode,
479                                         &m_sliceStatesSize,
480                                         &m_slicePatchListSize,
481                                         &m_tileStateSize,
482                                         &m_tilePatchListSize));
483 
484         return MOS_STATUS_SUCCESS;
485     }
486 
AddAllCmds_VVCP_REF_IDX_STATE(MOS_COMMAND_BUFFER & cmdBuffer)487     MOS_STATUS VvcDecodeSlicePkt::AddAllCmds_VVCP_REF_IDX_STATE(MOS_COMMAND_BUFFER &cmdBuffer)
488     {
489         DECODE_FUNC_CALL();
490 
491         // Issue RefIdxState command only for non-I slice
492         if (m_vvcpItf->IsVvcISlice(m_curSliceParams->m_shSliceType) &&
493             (!m_vvcBasicFeature->m_useDummyReference || m_osInterface->bSimIsActive))
494         {
495             return MOS_STATUS_SUCCESS;
496         }
497 
498         // L0
499         DECODE_CHK_STATUS(SetRefIdxStateParams());
500         DECODE_CHK_STATUS(m_vvcpItf->MHW_ADDCMD_F(VVCP_REF_IDX_STATE)(&cmdBuffer));
501 
502         // L1
503         if (m_vvcpItf->IsVvcBSlice(m_curSliceParams->m_shSliceType))
504         {
505             auto &params = m_vvcpItf->MHW_GETPAR_F(VVCP_REF_IDX_STATE)();
506 
507             params.listIdx       = 1;
508             params.numRefForList = m_curSliceParams->m_numRefIdxActive[1];
509 
510             DECODE_CHK_STATUS(m_vvcpItf->MHW_ADDCMD_F(VVCP_REF_IDX_STATE)(&cmdBuffer));
511         }
512 
513         return MOS_STATUS_SUCCESS;
514     }
515 
AddAllCmds_VVCP_WEIGHTOFFSET_STATE(MOS_COMMAND_BUFFER & cmdBuffer)516     MOS_STATUS VvcDecodeSlicePkt::AddAllCmds_VVCP_WEIGHTOFFSET_STATE(MOS_COMMAND_BUFFER &cmdBuffer)
517     {
518         DECODE_FUNC_CALL();
519 
520         bool weightedPred = m_vvcPicParams->m_ppsFlags.m_fields.m_ppsWeightedPredFlag && m_vvcpItf->IsVvcPSlice(m_curSliceParams->m_shSliceType);
521         bool weightedBiPred = m_vvcPicParams->m_ppsFlags.m_fields.m_ppsWeightedBipredFlag && m_vvcpItf->IsVvcBSlice(m_curSliceParams->m_shSliceType);
522 
523         if (weightedPred || weightedBiPred)
524         {
525             if(m_vvcBasicFeature->m_shortFormatInUse)
526             {
527                 DECODE_ASSERTMESSAGE("Warning: Long format specific function, short format should not call!\n");
528                 return MOS_STATUS_INVALID_PARAMETER;
529             }
530             auto &params = m_vvcpItf->MHW_GETPAR_F(VVCP_WEIGHTOFFSET_STATE)();
531             params = {};
532             params.wpInfo = &m_curSliceParams->m_wpInfo;
533             DECODE_CHK_STATUS(m_vvcpItf->MHW_ADDCMD_F(VVCP_WEIGHTOFFSET_STATE)(&cmdBuffer));
534 
535             if (weightedBiPred)
536             {
537                 params.listIdx = 1;
538                 DECODE_CHK_STATUS(m_vvcpItf->MHW_ADDCMD_F(VVCP_WEIGHTOFFSET_STATE)(&cmdBuffer));
539             }
540         }
541         return MOS_STATUS_SUCCESS;
542     }
543 
MHW_SETPAR_DECL_SRC(VVCP_SLICE_STATE,VvcDecodeSlicePkt)544     MHW_SETPAR_DECL_SRC(VVCP_SLICE_STATE, VvcDecodeSlicePkt)
545     {
546         params = {};
547 
548         if (m_curSliceParams->m_longSliceFlags.m_fields.m_shLmcsUsedFlag &&
549             !(m_vvcBasicFeature->m_lmcsReshaperReady & (1 << m_vvcPicParams->m_phLmcsApsId)))
550         {
551             MOS_ZeroMemory(&m_vvcBasicFeature->m_lmcsReshaperInfo[m_vvcPicParams->m_phLmcsApsId], sizeof(ApsLmcsReshapeInfo));
552             DECODE_CHK_STATUS(ConstructLmcsReshaper());
553         }
554 
555         CodecVvcPicParams   *picParams   = m_vvcBasicFeature->m_vvcPicParams;
556         CodecVvcSliceParams *sliceParams = m_curSliceParams;
557 
558         if (picParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
559         {
560             MHW_MI_CHK_NULL(m_sliceDesc);
561         }
562 
563         if (picParams->m_spsFlags0.m_fields.m_spsAlfEnabledFlag)
564         {
565             if (picParams->m_ppsFlags.m_fields.m_ppsAlfInfoInPhFlag == 1)
566             {
567                 params.shAlfEnabledFlag     = picParams->m_phFlags.m_fields.m_phAlfEnabledFlag;
568                 params.shAlfCbEnabledFlag   = picParams->m_phFlags.m_fields.m_phAlfCbEnabledFlag;
569                 params.shAlfCrEnabledFlag   = picParams->m_phFlags.m_fields.m_phAlfCrEnabledFlag;
570                 params.shAlfCcCbEnabledFlag = picParams->m_phFlags.m_fields.m_phAlfCcCbEnabledFlag;
571                 params.shAlfCcCrEnabledFlag = picParams->m_phFlags.m_fields.m_phAlfCcCrEnabledFlag;
572             }
573             else
574             {
575                 params.shAlfEnabledFlag     = sliceParams->m_longSliceFlags.m_fields.m_shAlfEnabledFlag;
576                 params.shAlfCbEnabledFlag   = sliceParams->m_longSliceFlags.m_fields.m_shAlfCbEnabledFlag;
577                 params.shAlfCrEnabledFlag   = sliceParams->m_longSliceFlags.m_fields.m_shAlfCrEnabledFlag;
578                 params.shAlfCcCbEnabledFlag = sliceParams->m_longSliceFlags.m_fields.m_shAlfCcCbEnabledFlag;
579                 params.shAlfCcCrEnabledFlag = sliceParams->m_longSliceFlags.m_fields.m_shAlfCcCrEnabledFlag;
580             }
581         }
582 
583         params.shLmcsUsedFlag                 = sliceParams->m_longSliceFlags.m_fields.m_shLmcsUsedFlag;
584         params.shExplicitScalingListUsedFlag  = sliceParams->m_longSliceFlags.m_fields.m_shExplicitScalingListUsedFlag;
585         params.shCabacInitFlag                = sliceParams->m_longSliceFlags.m_fields.m_shCabacInitFlag;
586         params.shCollocatedFromL0Flag         = sliceParams->m_longSliceFlags.m_fields.m_shCollocatedFromL0Flag;
587         params.shCuChromaQpOffsetEnabledFlag  = sliceParams->m_longSliceFlags.m_fields.m_shCuChromaQpOffsetEnabledFlag;
588         params.shSaoLumaUsedFlag              = sliceParams->m_longSliceFlags.m_fields.m_shSaoLumaUsedFlag;
589         params.shSaoChromaUsedFlag            = sliceParams->m_longSliceFlags.m_fields.m_shSaoChromaUsedFlag;
590         params.shDeblockingFilterDisabledFlag = sliceParams->m_longSliceFlags.m_fields.m_shDeblockingFilterDisabledFlag;
591         params.shDepQuantUsedFlag             = sliceParams->m_longSliceFlags.m_fields.m_shDepQuantUsedFlag;
592         params.shSignDataHidingUsedFlag       = sliceParams->m_longSliceFlags.m_fields.m_shSignDataHidingUsedFlag;
593         params.shTsResidualCodingDisabledFlag = sliceParams->m_longSliceFlags.m_fields.m_shTsResidualCodingDisabledFlag;
594         params.nobackwardpredflag             = sliceParams->m_longSliceFlags.m_fields.m_noBackwardPredFlag;
595 
596         // CRC enable
597         params.pVvcpDebugEnable = false;
598 
599         if (picParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
600         {
601             params.dMultipleSlicesInTileFlag    = m_sliceDesc->m_multiSlicesInTileFlag;
602             params.dIsbottommostsliceoftileFlag = m_sliceDesc->m_bottomSliceInTileFlag;
603             params.dIstopmostsliceoftileFlag    = m_sliceDesc->m_topSliceInTileFlag;
604         }
605 
606         // Partition info of SubPic v.s. Slice
607         if (picParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && picParams->m_spsNumSubpicsMinus1 > 0)
608         {
609             params.dSubpicTreatedAsPicFlag            = m_subPicParams->m_subPicFlags.m_fields.m_spsSubpicTreatedAsPicFlag;
610             params.dLoopFilterAcrossSubpicEnabledFlag = m_subPicParams->m_subPicFlags.m_fields.m_spsLoopFilterAcrossSubpicEnabledFlag;
611             params.dIsRightMostSliceOfSubpicFlag      = (m_sliceDesc->m_sliceEndCtbx == m_subPicParams->m_endCtbX) ? 1 : 0;
612             params.dIsLeftMostSliceOfSubpicFlag       = (m_sliceDesc->m_sliceStartCtbx == m_subPicParams->m_spsSubpicCtuTopLeftX) ? 1 : 0;
613             params.dIsBottomMostSliceOfSubpicFlag     = (m_sliceDesc->m_sliceEndCtby == m_subPicParams->m_endCtbY) ? 1 : 0;
614             params.dIsTopMostSliceOfSubpicFlag        = (m_sliceDesc->m_sliceStartCtby == m_subPicParams->m_spsSubpicCtuTopLeftY) ? 1 : 0;
615         }
616         else if (picParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
617         {
618             params.dSubpicTreatedAsPicFlag            = (picParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag && picParams->m_spsNumSubpicsMinus1 == 0) ? 1 : 0;
619             params.dLoopFilterAcrossSubpicEnabledFlag = 0;
620             params.dIsRightMostSliceOfSubpicFlag      = (m_sliceDesc->m_sliceEndCtbx == m_vvcBasicFeature->m_picWidthInCtu - 1) ? 1 : 0;
621             params.dIsLeftMostSliceOfSubpicFlag       = (m_sliceDesc->m_sliceStartCtbx == 0) ? 1 : 0;
622             params.dIsBottomMostSliceOfSubpicFlag     = (m_sliceDesc->m_sliceEndCtby == m_vvcBasicFeature->m_picHeightInCtu - 1) ? 1 : 0;
623             params.dIsTopMostSliceOfSubpicFlag        = (m_sliceDesc->m_sliceStartCtby == 0) ? 1 : 0;
624         }
625         else
626         {
627             uint16_t startSlice = sliceParams->m_shSliceAddress;
628             uint16_t endSlice   = sliceParams->m_shSliceAddress + sliceParams->m_shNumTilesInSliceMinus1;
629             uint16_t startTileX = startSlice % m_vvcBasicFeature->m_tileCols;
630             uint16_t endTileX   = endSlice % m_vvcBasicFeature->m_tileCols;
631 
632             params.dSubpicTreatedAsPicFlag             = 0;
633             params.dLoopFilterAcrossSubpicEnabledFlag  = 0;
634             params.dIsRightMostSliceOfSubpicFlag       = (startTileX + sliceParams->m_shNumTilesInSliceMinus1 < m_vvcBasicFeature->m_tileCols - 1) ? 0 : 1;
635             params.dIsLeftMostSliceOfSubpicFlag        = (endTileX > sliceParams->m_shNumTilesInSliceMinus1) ? 0 : 1;
636             params.dIsBottomMostSliceOfSubpicFlag      = (m_vvcBasicFeature->m_tileCols * m_vvcBasicFeature->m_tileRows - endSlice > m_vvcBasicFeature->m_tileCols) ? 0 : 1;
637             params.dIsTopMostSliceOfSubpicFlag         = (startSlice < m_vvcBasicFeature->m_tileCols) ? 1 : 0;
638         }
639 
640         params.dLastsliceofpicFlag     = m_lastSliceOfPic;
641         params.numctusincurrslice      = m_sliceDesc->m_numCtusInCurrSlice;
642         params.shNumTilesInSliceMinus1 = (picParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag) ? 0 : sliceParams->m_shNumTilesInSliceMinus1;
643         params.shSliceType             = sliceParams->m_shSliceType;
644 
645         if (params.shAlfEnabledFlag)
646         {
647             params.shNumAlfApsIdsLuma = sliceParams->m_shNumAlfApsIdsLuma;
648             if (params.shAlfCbEnabledFlag || params.shAlfCrEnabledFlag)
649             {
650                 MHW_CHK_COND(sliceParams->m_shAlfApsIdChroma >= vvcMaxAlfNum, "sh_alf_aps_id_chroma out of range!");
651                 MHW_CHK_COND(m_vvcBasicFeature->m_alfApsArray[sliceParams->m_shAlfApsIdChroma].m_alfFlags.m_fields.m_alfChromaFilterSignalFlag != 1, "alf_chroma_filter_signal_flag should be equal to 1!");
652                 params.alfChromaNumAltFiltersMinus1 = m_vvcBasicFeature->m_alfApsArray[sliceParams->m_shAlfApsIdChroma].m_alfChromaNumAltFiltersMinus1;
653             }
654             if (params.shAlfCcCbEnabledFlag)
655             {
656                 MHW_CHK_COND(sliceParams->m_shAlfCcCbApsId >= vvcMaxAlfNum, "sh_alf_cc_cb_aps_id out of range!");
657                 MHW_CHK_COND(m_vvcBasicFeature->m_alfApsArray[sliceParams->m_shAlfCcCbApsId].m_alfFlags.m_fields.m_alfCcCbFilterSignalFlag != 1, "alf_cc_cb_filter_signal_flag should be equal to 1!");
658                 params.alfCcCbFiltersSignalledMinus1 = m_vvcBasicFeature->m_alfApsArray[sliceParams->m_shAlfCcCbApsId].m_alfCcCbFiltersSignalledMinus1;
659             }
660             if (params.shAlfCcCrEnabledFlag)
661             {
662                 MHW_CHK_COND(sliceParams->m_shAlfCcCrApsId >= vvcMaxAlfNum, "sh_alf_cc_cr_aps_id out of range!");
663                 MHW_CHK_COND(m_vvcBasicFeature->m_alfApsArray[sliceParams->m_shAlfCcCrApsId].m_alfFlags.m_fields.m_alfCcCrFilterSignalFlag != 1, "alf_cc_cr_filter_signal_flag should be equal to 1!");
664                 params.alfCcCrFiltersSignalledMinus1 = m_vvcBasicFeature->m_alfApsArray[sliceParams->m_shAlfCcCrApsId].m_alfCcCrFiltersSignalledMinus1;
665             }
666             for (auto i = 0; i < sliceParams->m_shNumAlfApsIdsLuma; i++)
667             {
668                 MHW_CHK_COND(sliceParams->m_shAlfApsIdLuma[i] >= vvcMaxAlfNum, "sh_alf_aps_id_luma[] out of range!");
669                 MHW_CHK_COND(m_vvcBasicFeature->m_alfApsArray[sliceParams->m_shAlfApsIdLuma[i]].m_alfFlags.m_fields.m_alfLumaFilterSignalFlag != 1, "alf_luma_filter_signal_flag should be equal to 1!");
670             }
671             params.shAlfApsIdLuma0  = sliceParams->m_shAlfApsIdLuma[0];
672             params.shAlfApsIdLuma1  = sliceParams->m_shAlfApsIdLuma[1];
673             params.shAlfApsIdLuma2  = sliceParams->m_shAlfApsIdLuma[2];
674             params.shAlfApsIdLuma3  = sliceParams->m_shAlfApsIdLuma[3];
675             params.shAlfApsIdLuma4  = sliceParams->m_shAlfApsIdLuma[4];
676             params.shAlfApsIdLuma5  = sliceParams->m_shAlfApsIdLuma[5];
677             params.shAlfApsIdLuma6  = sliceParams->m_shAlfApsIdLuma[6];
678             params.shAlfApsIdChroma = (params.shAlfCbEnabledFlag || params.shAlfCrEnabledFlag) ? sliceParams->m_shAlfApsIdChroma : 0;
679             params.shAlfCcCbApsId   = params.shAlfCcCbEnabledFlag ? sliceParams->m_shAlfCcCbApsId : 0;
680             params.shAlfCcCrApsId   = params.shAlfCcCrEnabledFlag ? sliceParams->m_shAlfCcCrApsId : 0;
681         }
682 
683         if (!m_vvcpItf->IsVvcISlice(sliceParams->m_shSliceType))
684         {
685             params.numrefidxactive0 = sliceParams->m_numRefIdxActive[0];
686             params.numrefidxactive1 = sliceParams->m_numRefIdxActive[1];
687         }
688 
689         params.shCollocatedRefIdx  = sliceParams->m_shCollocatedRefIdx;
690         params.sliceqpy            = sliceParams->m_sliceQpY;
691         params.shCbQpOffset        = sliceParams->m_shCbQpOffset;
692         params.shCrQpOffset        = sliceParams->m_shCrQpOffset;
693         params.shJointCbcrQpOffset = sliceParams->m_shJointCbcrQpOffset;
694 
695         if (!sliceParams->m_longSliceFlags.m_fields.m_shDeblockingFilterDisabledFlag)
696         {
697             params.shLumaBetaOffsetDiv2 = sliceParams->m_shLumaBetaOffsetDiv2;
698             params.shLumaTcOffsetDiv2   = sliceParams->m_shLumaTcOffsetDiv2;
699             params.shCbBetaOffsetDiv2   = sliceParams->m_shCbBetaOffsetDiv2;
700             params.shCbTcOffsetDiv2     = sliceParams->m_shCbTcOffsetDiv2;
701             params.shCrBetaOffsetDiv2   = sliceParams->m_shCrBetaOffsetDiv2;
702             params.shCrTcOffsetDiv2     = sliceParams->m_shCrTcOffsetDiv2;
703         }
704 
705         // LMCS
706         params.spsLmcsEnabledFlag = picParams->m_spsFlags0.m_fields.m_spsLmcsEnabledFlag;
707 
708         if (params.spsLmcsEnabledFlag && params.shLmcsUsedFlag)
709         {
710             params.phLmcsApsId      = m_vvcPicParams->m_phLmcsApsId;
711             params.vvcLmcsData      = m_vvcBasicFeature->m_lmcsApsArray;
712             params.vvcLmcsShapeInfo = m_vvcBasicFeature->m_lmcsReshaperInfo;
713         }
714 
715         // Partition info of SubPic v.s. Slice
716         if (picParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag &&
717             picParams->m_spsFlags0.m_fields.m_spsSubpicInfoPresentFlag &&
718             picParams->m_spsNumSubpicsMinus1 > 0)
719         {
720             params.dSubpicCtuTopLeftX  = m_subPicParams->m_spsSubpicCtuTopLeftX;
721             params.dSubpicCtuTopLeftY  = m_subPicParams->m_spsSubpicCtuTopLeftY;
722             params.dSubpicWidthMinus1  = m_subPicParams->m_spsSubpicWidthMinus1;
723             params.dSubpicHeightMinus1 = m_subPicParams->m_spsSubpicHeightMinus1;
724         }
725         else
726         {
727             params.dSubpicCtuTopLeftX  = 0;
728             params.dSubpicCtuTopLeftY  = 0;
729             params.dSubpicWidthMinus1  = MOS_ROUNDUP_SHIFT(picParams->m_ppsPicWidthInLumaSamples, picParams->m_spsLog2CtuSizeMinus5 + 5) - 1;
730             params.dSubpicHeightMinus1 = MOS_ROUNDUP_SHIFT(picParams->m_ppsPicHeightInLumaSamples, picParams->m_spsLog2CtuSizeMinus5 + 5) - 1;
731         }
732 
733         if (picParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
734         {
735             if (m_sliceDesc->m_sliceWidthInTiles <= 1 && m_sliceDesc->m_sliceHeightInTiles <= 1)
736             {
737                 params.dSliceheightinctus = m_sliceDesc->m_sliceHeightInCtu;
738             }
739         }
740 
741         params.dToplefttilex   = m_sliceDesc->m_startTileX;
742         params.dToplefttiley   = m_sliceDesc->m_startTileY;
743         params.dSlicestartctbx = m_sliceDesc->m_sliceStartCtbx;
744         params.dSlicestartctby = m_sliceDesc->m_sliceStartCtby;
745 
746         return MOS_STATUS_SUCCESS;
747     }
748 
MHW_SETPAR_DECL_SRC(VVCP_BSD_OBJECT,VvcDecodeSlicePkt)749     MHW_SETPAR_DECL_SRC(VVCP_BSD_OBJECT, VvcDecodeSlicePkt)
750     {
751         params = {};
752 
753         uint32_t bsdDataLength = m_curSliceParams->m_sliceBytesInBuffer - m_curSliceParams->m_byteOffsetToSliceData;
754         if (bsdDataLength != 0)
755         {
756             params.bsdDataLength      = bsdDataLength;
757             params.bsdDataStartOffset = m_curSliceParams->m_bSNALunitDataLocation + m_curSliceParams->m_byteOffsetToSliceData;
758         }
759         else
760         {
761             params.bsdDataLength      = 4;
762             params.bsdDataStartOffset = 0;
763         }
764 
765         return MOS_STATUS_SUCCESS;
766     }
767 
AddAllCmds_VVCP_TILE_CODING(MOS_COMMAND_BUFFER & cmdBuffer)768     MOS_STATUS VvcDecodeSlicePkt::AddAllCmds_VVCP_TILE_CODING(MOS_COMMAND_BUFFER &cmdBuffer)
769     {
770         DECODE_FUNC_CALL();
771 
772         m_curTileIdx = 0;
773         if (!m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
774         {
775             m_numTilesInSlice = m_curSliceParams->m_shNumTilesInSliceMinus1 + 1;
776             for (int16_t i = 0; i < m_numTilesInSlice; i++)
777             {
778                 m_curTileIdx = m_curSliceParams->m_shSliceAddress + i;
779                 SETPAR_AND_ADDCMD(VVCP_TILE_CODING, m_vvcpItf, &cmdBuffer);
780             }
781         }
782         else
783         {
784             if (m_sliceDesc->m_multiSlicesInTileFlag)
785             {
786                 m_numTilesInSlice = 1;
787                 m_curTileIdx      = m_sliceDesc->m_tileIdx;
788                 SETPAR_AND_ADDCMD(VVCP_TILE_CODING, m_vvcpItf, &cmdBuffer);
789             }
790             else
791             {
792                 m_numTilesInSlice = m_sliceDesc->m_sliceHeightInTiles * m_sliceDesc->m_sliceWidthInTiles;
793                 for (int16_t y = 0; y < m_sliceDesc->m_sliceHeightInTiles; y++)
794                 {
795                     for (int16_t x = 0; x < m_sliceDesc->m_sliceWidthInTiles; x++)
796                     {
797                         m_curTileIdx = (x + m_sliceDesc->m_startTileX) + (y + m_sliceDesc->m_startTileY) * m_vvcBasicFeature->m_tileCols;
798                         SETPAR_AND_ADDCMD(VVCP_TILE_CODING, m_vvcpItf, &cmdBuffer);
799                     }
800                 }
801             }
802         }
803 
804         return MOS_STATUS_SUCCESS;
805     }
806 
MHW_SETPAR_DECL_SRC(VVCP_TILE_CODING,VvcDecodeSlicePkt)807     MHW_SETPAR_DECL_SRC(VVCP_TILE_CODING, VvcDecodeSlicePkt)
808     {
809         params = {};
810 
811         uint16_t col                     = m_curTileIdx % m_vvcBasicFeature->m_tileCols;
812         uint16_t row                     = m_curTileIdx / m_vvcBasicFeature->m_tileCols;
813         params.tilecolbdval              = m_vvcBasicFeature->m_tileCol[col].m_startCtbX;
814         params.tilerowbdval              = m_vvcBasicFeature->m_tileRow[row].m_startCtbY;
815         params.colwidthval               = m_vvcBasicFeature->m_tileCol[col].m_widthInCtb;
816         params.rowheightval              = m_vvcBasicFeature->m_tileRow[row].m_heightInCtb;
817         params.currenttilecolumnposition = col;
818         params.currenttilerowposition    = row;
819 
820         //Tile v.s. Slice
821         if (m_vvcBasicFeature->m_vvcPicParams->m_ppsFlags.m_fields.m_ppsRectSliceFlag)
822         {
823             DECODE_ASSERT(m_sliceDesc);
824             if (m_sliceDesc->m_multiSlicesInTileFlag)
825             {
826                 params.flags.m_isrightmosttileofsliceFlag  = 1;
827                 params.flags.m_isleftmosttileofsliceFlag   = 1;
828                 params.flags.m_isbottommosttileofsliceFlag = 1;
829                 params.flags.m_istopmosttileofsliceFlag    = 1;
830             }
831             else
832             {
833                 params.flags.m_isrightmosttileofsliceFlag  = (col == m_sliceDesc->m_startTileX + m_sliceDesc->m_sliceWidthInTiles - 1) ? 1 : 0;
834                 params.flags.m_isleftmosttileofsliceFlag   = (col == m_sliceDesc->m_startTileX) ? 1 : 0;
835                 params.flags.m_isbottommosttileofsliceFlag = (row == m_sliceDesc->m_startTileY + m_sliceDesc->m_sliceHeightInTiles - 1) ? 1 : 0;
836                 params.flags.m_istopmosttileofsliceFlag    = (row == m_sliceDesc->m_startTileY) ? 1 : 0;
837             }
838         }
839         else
840         {
841             if (col == m_vvcBasicFeature->m_tileCols - 1)  // frame right most
842             {
843                 params.flags.m_isrightmosttileofsliceFlag = 1;
844             }
845             else
846             {
847                 params.flags.m_isrightmosttileofsliceFlag = !IsTileInRasterSlice(row, col + 1);
848             }
849 
850             if (col == 0)  // frame left most
851             {
852                 params.flags.m_isleftmosttileofsliceFlag = 1;
853             }
854             else
855             {
856                 params.flags.m_isleftmosttileofsliceFlag = !IsTileInRasterSlice(row, col - 1);
857             }
858 
859             if (row == m_vvcBasicFeature->m_tileRows - 1)  // frame bottom most
860             {
861                 params.flags.m_isbottommosttileofsliceFlag = 1;
862             }
863             else
864             {
865                 params.flags.m_isbottommosttileofsliceFlag = !IsTileInRasterSlice(row + 1, col);
866             }
867 
868             if (row == 0)  // frame top most
869             {
870                 params.flags.m_istopmosttileofsliceFlag = 1;
871             }
872             else
873             {
874                 params.flags.m_istopmosttileofsliceFlag = !IsTileInRasterSlice(row - 1, col);
875             }
876         }
877 
878         //tile v.s. frame
879         params.flags.m_isrightmosttileofframeFlag  = (col == m_vvcBasicFeature->m_tileCols - 1) ? 1 : 0;
880         params.flags.m_isleftmosttileofframeFlag   = (col == 0) ? 1 : 0;
881         params.flags.m_isbottommosttileofframeFlag = (row == m_vvcBasicFeature->m_tileRows - 1) ? 1 : 0;
882         params.flags.m_istopmosttileofframeFlag    = (row == 0) ? 1 : 0;
883 
884         m_vvcBasicFeature->m_frameCompletedFlag = (params.flags.m_isrightmosttileofframeFlag == 1) && (params.flags.m_isbottommosttileofframeFlag == 1);
885 
886         return MOS_STATUS_SUCCESS;
887     }
888 
889 }
890 
891