1 /*
2 * Copyright (c) 2017-2019, 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     codechal_decode_hevc_long_g12.cpp
24 //! \brief    Implements HEVC slice level command processing for HEVC long format.
25 //! \details  Implement HEVC slice level command processing for all HEVC/SCC configuration and
26 //!           generate tile/slice level commands into second level buffer as short format.
27 //!
28 
29 #include "codechal_decode_hevc_long_g12.h"
30 #include "mos_os_cp_interface_specific.h"
31 
32 // HEVC Long format
HevcDecodeSliceLongG12(CodechalDecodeHevcG12 * decoder,MhwVdboxHcpInterface * hcpInterface,MhwMiInterface * miInterface)33 HevcDecodeSliceLongG12::HevcDecodeSliceLongG12(
34     CodechalDecodeHevcG12       *decoder,
35     MhwVdboxHcpInterface        *hcpInterface,
36     MhwMiInterface              *miInterface)
37 {
38     m_decoder = decoder;
39     m_hcpInterface = static_cast<MhwVdboxHcpInterfaceG12*>(hcpInterface);
40     m_miInterface = miInterface;
41     m_osInterface  = m_decoder->GetOsInterface();
42     m_hwInterface    = decoder->GetHwInterface();
43     m_vdencInterface = m_hwInterface->GetVdencInterface();
44 
45     //copy other params from decoder
46     m_numSlices = m_decoder->m_numSlices;
47     m_hevcPicParams = m_decoder->m_hevcPicParams;
48     m_hevcSliceParams = m_decoder->m_hevcSliceParams;
49     m_hevcExtPicParams = m_decoder->m_hevcExtPicParams;
50     m_hevcExtSliceParams = m_decoder->m_hevcExtSliceParams;
51     m_hevcSccPicParams = m_decoder->m_hevcSccPicParams;
52     m_hevcSubsetParams = m_decoder->m_hevcSubsetParams;
53 
54     m_widthInCtb = MOS_ROUNDUP_DIVIDE(m_decoder->m_width, m_decoder->m_ctbSize);
55 
56     m_secureDecoder = m_decoder->m_secureDecoder;
57     m_scalabilityState = m_decoder->m_scalabilityState;
58 
59     m_tileColWidth = &decoder->m_tileColWidth[0];
60     m_tileRowHeight = &decoder->m_tileRowHeight[0];
61 
62     m_copyDataBufferInUse = m_decoder->m_copyDataBufferInUse;
63     m_resCopyDataBuffer = &m_decoder->m_resCopyDataBuffer;
64     m_resDataBuffer = &m_decoder->m_resDataBuffer;
65 
66     m_refIdxMapping = &m_decoder->m_refIdxMapping[0];
67     m_hevcRefList = m_decoder->m_hevcRefList;
68 
69     m_isRealTile = m_decoder->m_isRealTile;
70     m_isSeparateTileDecoding = m_decoder->m_isSeparateTileDecoding;
71     m_isSccPaletteMode = CodecHalDecodeIsSCCPLTMode(m_hevcSccPicParams);
72     m_tileDecoding = (m_isRealTile || m_isSeparateTileDecoding);
73 }
74 
ProcessSliceLong(uint8_t * cmdResBase,uint32_t cmdBufSize)75 MOS_STATUS HevcDecodeSliceLongG12::ProcessSliceLong(uint8_t *cmdResBase, uint32_t cmdBufSize)
76 {
77     MEDIA_WA_TABLE *m_waTable = m_osInterface->pfnGetWaTable(m_osInterface);
78     MHW_CHK_NULL_RETURN(m_waTable);
79 
80     auto eStatus = MOS_STATUS_SUCCESS;
81     auto slc = m_hevcSliceParams;
82     auto slcBase = slc;
83     auto slcExt = m_hevcExtSliceParams;
84     auto pic = m_hevcPicParams;
85 
86     PMOS_COMMAND_BUFFER cmdBufArray, cmdBuf;
87 
88     // Init fake cmd buffers on client buffer
89     int cmdBufArraySize = m_isRealTile ? m_hevcPicParams->num_tile_columns_minus1 + 1 : 1;
90 
91     cmdBufArray = (MOS_COMMAND_BUFFER*)MOS_AllocAndZeroMemory(sizeof(MOS_COMMAND_BUFFER) * cmdBufArraySize);
92     CODECHAL_DECODE_CHK_NULL_RETURN(cmdBufArray);
93 
94     for (int i = 0; i < cmdBufArraySize; i++)
95     {
96         cmdBufArray[i].pCmdBase = (uint32_t*)(cmdResBase + cmdBufSize * i);
97         cmdBufArray[i].pCmdPtr = cmdBufArray[i].pCmdBase;
98         cmdBufArray[i].iRemaining = cmdBufSize;
99     }
100 
101     bool                    isFirstSliceOfTile = true;
102     HEVC_TILE_SLICE_PARAMS  tileSliceParams = {0,};
103 
104     for (uint32_t i = 0; i < m_numSlices; i++)
105     {
106         uint16_t numTiles = 0;
107         uint16_t tileX = 0, tileY = 0;
108         uint16_t origCtbX = 0, origCtbY = 0;
109 
110         PHEVC_SLICE_TILE_PARAMS     sliceTileParams = nullptr;
111 
112         bool isIndependentSlice = (i == 0) || !slc->LongSliceFlags.fields.dependent_slice_segment_flag;
113 
114         if(slc->slice_data_offset + slc->slice_data_size > m_decoder->m_dataSize)
115         {
116             CODECHAL_DECODE_ASSERTMESSAGE("invalid slice %d, data size overflow\n", i);
117             MOS_SafeFreeMemory(cmdBufArray);
118             return MOS_STATUS_INVALID_PARAMETER;
119         }
120 
121         if (isIndependentSlice)
122         {
123             origCtbX = slc->slice_segment_address % m_widthInCtb;
124             origCtbY = slc->slice_segment_address / m_widthInCtb;
125 
126             if(i == 0 && slc->slice_segment_address != 0)
127             {
128                 //Spec reequires that segment address in first slice must be 0
129                 CODECHAL_DECODE_ASSERTMESSAGE("invalid independent slice %d, slice_segment_address=%d\n",
130                     i, slc->slice_segment_address);
131                 MOS_SafeFreeMemory(cmdBufArray);
132                 return MOS_STATUS_INVALID_PARAMETER;
133             }
134         }
135         else //dependent
136         {
137             int index;
138             for (index = i - 1; index >= 0; --index) //search backword
139             {
140                 if(!(slcBase + index)->LongSliceFlags.fields.dependent_slice_segment_flag) //independent slice
141                 {
142                     origCtbX = (slcBase + index)->slice_segment_address % m_widthInCtb;
143                     origCtbY = (slcBase + index)->slice_segment_address / m_widthInCtb;
144 
145                     if(index == 0 && (slcBase + index)->slice_segment_address != 0)
146                     {
147                         CODECHAL_DECODE_ASSERTMESSAGE("invalid dependent slice %d, index %d, slice_segment_address=%d\n",
148                             index, slc->slice_segment_address);
149                         MOS_SafeFreeMemory(cmdBufArray);
150                         return MOS_STATUS_INVALID_PARAMETER;
151                     }
152                     break;
153                 }
154             }
155         }
156 
157         if (m_hevcRefList[pic->CurrPic.FrameIdx]->bIsIntra &&
158             !m_hcpInterface->IsHevcISlice(slc->LongSliceFlags.fields.slice_type))
159         {
160             slc->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag = 0;
161         }
162 
163         if (m_isSeparateTileDecoding || m_isRealTile)
164         {
165             tileX = GetSliceTileX(slc);
166             tileY = GetSliceTileY(slc);
167 
168             if (i == m_numSlices || slc->LongSliceFlags.fields.LastSliceOfPic)
169             {
170                 numTiles = (m_hevcPicParams->num_tile_columns_minus1 + 1) * (m_hevcPicParams->num_tile_rows_minus1 + 1 - tileY) - tileX;
171             }
172             else
173             {
174                 uint32_t nextTileX = GetSliceTileX(slc + 1);
175                 uint32_t nextTileY = GetSliceTileY(slc + 1);
176 
177                 numTiles = (m_hevcPicParams->num_tile_columns_minus1 + 1) * (nextTileY - tileY) + nextTileX - tileX;
178             }
179 
180             tileSliceParams.tileX = tileX;
181             tileSliceParams.tileY = tileY;
182             tileSliceParams.lastSliceOfTile = (numTiles > 0);
183 
184             if (numTiles > 1)
185             {
186                 sliceTileParams = (PHEVC_SLICE_TILE_PARAMS)MOS_AllocAndZeroMemory(sizeof(HEVC_SLICE_TILE_PARAMS)
187                     + (numTiles - 1) * sizeof(HEVC_SLICE_TILE_PARAMS::PER_TILE_INFO));
188                 if (sliceTileParams == nullptr)
189                 {
190                     MOS_FreeMemory(sliceTileParams);
191                     MOS_FreeMemory(cmdBufArray);
192                     CODECHAL_DECODE_CHK_NULL_RETURN(nullptr);
193                 }
194 
195                 sliceTileParams->numTiles = numTiles;
196                 sliceTileParams->slc = slc;
197                 sliceTileParams->tileX = tileX;
198                 sliceTileParams->tileY = tileY;
199                 eStatus = (MOS_STATUS)(InitSliceTileParams(sliceTileParams));
200                 if (eStatus != MOS_STATUS_SUCCESS)
201                 {
202                     MOS_SafeFreeMemory(sliceTileParams);
203                     MOS_SafeFreeMemory(cmdBufArray);
204                     CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
205                 }
206             }
207         }
208 
209         uint16_t subStreamCount = (numTiles > 0) ? numTiles : 1;
210         for (uint16_t j = 0; j < subStreamCount; j++)
211         {
212             cmdBuf = m_isRealTile ? &cmdBufArray[tileX] : &cmdBufArray[0];
213 
214             if (isFirstSliceOfTile && (m_isSeparateTileDecoding || m_isRealTile))
215             {
216                 MHW_VDBOX_HCP_TILE_CODING_PARAMS_G12 tileCodingParams;
217 
218                 eStatus = (MOS_STATUS)(InitTileCodingParams(tileX, tileY, &tileCodingParams));
219                 if (eStatus != MOS_STATUS_SUCCESS)
220                 {
221                     MOS_SafeFreeMemory(sliceTileParams);
222                     MOS_SafeFreeMemory(cmdBufArray);
223                     CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
224                 }
225                 //insert 2 dummy VD_CONTROL_STATE packets with data=0 before every HCP_TILE_CODING
226                 if (MEDIA_IS_WA(m_waTable, Wa_14010222001))
227                 {
228                     MHW_MI_VD_CONTROL_STATE_PARAMS vdCtrlParam;
229                     MOS_ZeroMemory(&vdCtrlParam, sizeof(MHW_MI_VD_CONTROL_STATE_PARAMS));
230                     for (int i = 0; i < 2; i++)
231                     {
232                         eStatus = (static_cast<MhwMiInterfaceG12 *>(m_miInterface)->AddMiVdControlStateCmd(cmdBuf, &vdCtrlParam));
233                         if (eStatus != MOS_STATUS_SUCCESS)
234                         {
235                             MOS_SafeFreeMemory(sliceTileParams);
236                             MOS_SafeFreeMemory(cmdBufArray);
237                             CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
238                         }
239                     }
240                 }
241                 eStatus = (MOS_STATUS)(m_hcpInterface->AddHcpTileCodingCmd(cmdBuf, &tileCodingParams));
242                 if (eStatus != MOS_STATUS_SUCCESS)
243                 {
244                     MOS_SafeFreeMemory(sliceTileParams);
245                     MOS_SafeFreeMemory(cmdBufArray);
246                     CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
247                 }
248 
249             }
250 
251             if (m_isSccPaletteMode && (isFirstSliceOfTile || isIndependentSlice))
252             {
253                 eStatus = (MOS_STATUS)(m_hcpInterface->AddHcpPaletteInitializerStateCmd(
254                     cmdBuf,
255                     m_hevcSccPicParams));
256                 if (eStatus != MOS_STATUS_SUCCESS)
257                 {
258                     MOS_SafeFreeMemory(sliceTileParams);
259                     MOS_SafeFreeMemory(cmdBufArray);
260                     CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
261                 }
262             }
263 
264             MHW_VDBOX_HEVC_SLICE_STATE_G12  sliceState;
265 
266             sliceState.dwSliceIndex = i;
267             sliceState.u16OrigCtbX = origCtbX;
268             sliceState.u16OrigCtbY = origCtbY;
269 
270             eStatus = (MOS_STATUS)(InitSliceStateParams(&sliceState, slc, slcExt,
271                 &tileSliceParams, sliceTileParams, j));
272             if (eStatus != MOS_STATUS_SUCCESS)
273             {
274                 MOS_SafeFreeMemory(sliceTileParams);
275                 MOS_SafeFreeMemory(cmdBufArray);
276                 CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
277             }
278 
279             eStatus = (MOS_STATUS)(m_hcpInterface->AddHcpSliceStateCmd(
280                 cmdBuf,
281                 &sliceState));
282             if (eStatus != MOS_STATUS_SUCCESS)
283             {
284                 MOS_SafeFreeMemory(sliceTileParams);
285                 MOS_SafeFreeMemory(cmdBufArray);
286                 CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
287             }
288 
289             eStatus = (MOS_STATUS)(SendRefIdxState(cmdBuf, &sliceState));
290             if (eStatus != MOS_STATUS_SUCCESS)
291             {
292                 MOS_SafeFreeMemory(sliceTileParams);
293                 MOS_SafeFreeMemory(cmdBufArray);
294                 CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
295             }
296 
297             eStatus = (MOS_STATUS)(SendWeightOffset(cmdBuf, &sliceState));
298             if (eStatus != MOS_STATUS_SUCCESS)
299             {
300                 MOS_SafeFreeMemory(sliceTileParams);
301                 MOS_SafeFreeMemory(cmdBufArray);
302                 CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
303             }
304 
305             eStatus = (MOS_STATUS)(SendSecureDecodeState(cmdBuf, &sliceState));
306             if (eStatus != MOS_STATUS_SUCCESS)
307             {
308                 MOS_SafeFreeMemory(sliceTileParams);
309                 MOS_SafeFreeMemory(cmdBufArray);
310                 CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
311             }
312 
313             eStatus = (MOS_STATUS)(SendBsdObj(cmdBuf, &sliceState));
314             if (eStatus != MOS_STATUS_SUCCESS)
315             {
316                 MOS_SafeFreeMemory(sliceTileParams);
317                 MOS_SafeFreeMemory(cmdBufArray);
318                 CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
319             }
320 
321             if (MEDIA_IS_WA(m_waTable, Wa_2209620131) && m_isRealTile)
322             {
323                 // Send MFX_WAIT command
324                 eStatus = (MOS_STATUS)(m_miInterface->AddMfxWaitCmd(cmdBuf, nullptr, true));
325                 if (eStatus != MOS_STATUS_SUCCESS)
326                 {
327                     MOS_SafeFreeMemory(sliceTileParams);
328                     MOS_SafeFreeMemory(cmdBufArray);
329                     CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
330                 }
331                 // Send VD_PIPELINE_FLUSH command
332                 MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipelineFlushParams;
333                 MOS_ZeroMemory(&vdPipelineFlushParams, sizeof(vdPipelineFlushParams));
334                 vdPipelineFlushParams.Flags.bWaitDoneHEVC           = 1;
335                 vdPipelineFlushParams.Flags.bFlushHEVC              = 1;
336                 vdPipelineFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1;
337                 eStatus = (MOS_STATUS)(m_vdencInterface->AddVdPipelineFlushCmd(cmdBuf, &vdPipelineFlushParams));
338                 if (eStatus != MOS_STATUS_SUCCESS)
339                 {
340                     MOS_SafeFreeMemory(sliceTileParams);
341                     MOS_SafeFreeMemory(cmdBufArray);
342                     CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
343                 }
344             }
345 
346             if (++tileX > m_hevcPicParams->num_tile_columns_minus1)
347             {
348                 tileX = 0;  ++tileY;
349             }
350         }
351 
352         // Update it for next slice
353         isFirstSliceOfTile = (numTiles > 0);
354         if (sliceTileParams)
355         {
356             MOS_FreeMemory(sliceTileParams);
357             sliceTileParams = nullptr;
358         }
359 
360         slc++;
361         if (slcExt)
362             slcExt++;
363     }
364 
365     for (int i = 0; i < cmdBufArraySize; i++)
366     {
367         eStatus = (MOS_STATUS)m_miInterface->AddMiBatchBufferEnd(
368             &cmdBufArray[i],
369             nullptr);
370 
371         if (eStatus != MOS_STATUS_SUCCESS)
372         {
373             MOS_SafeFreeMemory(cmdBufArray);
374             CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
375         }
376     }
377 
378     if (cmdBufArray)
379     {
380         MOS_FreeMemory(cmdBufArray);
381         cmdBufArray = nullptr;
382     }
383     return MOS_STATUS_SUCCESS;
384 }
385 
InitTileCodingParams(uint32_t col,uint32_t row,MHW_VDBOX_HCP_TILE_CODING_PARAMS_G12 * hcpTileCodingParam)386 MOS_STATUS HevcDecodeSliceLongG12::InitTileCodingParams(
387     uint32_t                              col,
388     uint32_t                              row,
389     MHW_VDBOX_HCP_TILE_CODING_PARAMS_G12 *hcpTileCodingParam)
390 {
391     uint16_t    startCtbX = 0, startCtbY = 0;
392 
393     CODECHAL_DECODE_CHK_NULL_RETURN(hcpTileCodingParam);
394 
395     MOS_ZeroMemory(hcpTileCodingParam, sizeof(MHW_VDBOX_HCP_TILE_CODING_PARAMS_G12));
396 
397     uint32_t minCbSize = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
398     uint32_t LCUSize = 1 << (m_hevcPicParams->log2_diff_max_min_luma_coding_block_size + m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
399 
400     for (uint8_t i = 0; i < col; i++)
401     {
402         startCtbX += m_tileColWidth[i];
403     }
404     for (uint8_t i = 0; i < row; i++)
405     {
406         startCtbY += m_tileRowHeight[i];
407     }
408 
409     if (col < m_hevcPicParams->num_tile_columns_minus1)
410     {
411         hcpTileCodingParam->TileWidthInMinCbMinus1 = (m_tileColWidth[col] << m_hevcPicParams->log2_diff_max_min_luma_coding_block_size) - 1;
412     }
413     else
414     {
415         hcpTileCodingParam->TileWidthInMinCbMinus1 = m_hevcPicParams->PicWidthInMinCbsY - ((startCtbX * LCUSize) / minCbSize) - 1;
416     }
417 
418     if (row < m_hevcPicParams->num_tile_rows_minus1)
419     {
420         hcpTileCodingParam->TileHeightInMinCbMinus1 = (m_tileRowHeight[row] << m_hevcPicParams->log2_diff_max_min_luma_coding_block_size) - 1;
421     }
422     else
423     {
424         hcpTileCodingParam->TileHeightInMinCbMinus1 = m_hevcPicParams->PicHeightInMinCbsY - ((startCtbY * LCUSize) / minCbSize) - 1;
425     }
426 
427     hcpTileCodingParam->TileStartLCUX = startCtbX;
428     hcpTileCodingParam->TileStartLCUY = startCtbY;
429     hcpTileCodingParam->ucNumDecodePipes = m_scalabilityState ? m_scalabilityState->ucScalablePipeNum : 1;
430     hcpTileCodingParam->ucPipeIdx = m_scalabilityState ? m_scalabilityState->u8RtCurPipe : 0;
431     hcpTileCodingParam->IsLastTileofColumn = (row == m_hevcPicParams->num_tile_rows_minus1);
432     hcpTileCodingParam->IsLastTileofRow = (col == m_hevcPicParams->num_tile_columns_minus1);
433 
434     return MOS_STATUS_SUCCESS;
435 }
436 
InitSliceTileParams(PHEVC_SLICE_TILE_PARAMS sliceTileParams)437 MOS_STATUS HevcDecodeSliceLongG12::InitSliceTileParams(
438     PHEVC_SLICE_TILE_PARAMS sliceTileParams)
439 {
440     PCODEC_HEVC_SLICE_PARAMS    slc;
441     uint16_t                    tileX, tileY;
442     uint32_t*                   entryPointOffsets;
443     uint32_t                    bsdOffset = 0;
444 
445     CODECHAL_DECODE_CHK_NULL_RETURN(sliceTileParams);
446 
447     slc = sliceTileParams->slc;
448     CODECHAL_DECODE_CHK_NULL_RETURN(slc);
449     CODECHAL_DECODE_ASSERT(sliceTileParams->numTiles == slc->num_entry_point_offsets + 1);
450 
451     tileX = sliceTileParams->tileX;
452     tileY = sliceTileParams->tileY;
453 
454     if (m_hevcSubsetParams)
455         entryPointOffsets = &m_hevcSubsetParams->entry_point_offset_minus1[slc->EntryOffsetToSubsetArray];
456     else
457         entryPointOffsets = NULL;
458 
459     for (uint16_t i = 0; i < sliceTileParams->numTiles; i++)
460     {
461         sliceTileParams->TileArray[i].ctbX = GetTileCtbX(tileX);
462         sliceTileParams->TileArray[i].ctbY = GetTileCtbY(tileY);
463         sliceTileParams->TileArray[i].bsdOffset = bsdOffset;
464         if (i == 0)
465         {
466             sliceTileParams->TileArray[i].bsdLength = slc->ByteOffsetToSliceData + slc->NumEmuPrevnBytesInSliceHdr;
467             sliceTileParams->TileArray[i].bsdLength += entryPointOffsets ? entryPointOffsets[i] + 1 : 1;
468         }
469         else if (i == sliceTileParams->numTiles - 1)
470         {
471             sliceTileParams->TileArray[i].bsdLength = slc->slice_data_size - sliceTileParams->TileArray[i].bsdOffset;
472         }
473         else
474         {
475             sliceTileParams->TileArray[i].bsdLength = entryPointOffsets ? entryPointOffsets[i] + 1 : 1;
476         }
477         bsdOffset += sliceTileParams->TileArray[i].bsdLength;
478         if (++tileX > m_hevcPicParams->num_tile_columns_minus1)
479         {
480             tileX = 0;  ++tileY;
481         }
482     }
483     return MOS_STATUS_SUCCESS;
484 }
485 
InitSliceStateParams(PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState,PCODEC_HEVC_SLICE_PARAMS sliceParams,PCODEC_HEVC_EXT_SLICE_PARAMS extSliceParams,PHEVC_TILE_SLICE_PARAMS tileSliceParams,PHEVC_SLICE_TILE_PARAMS sliceTileParams,uint16_t tileIndex)486 MOS_STATUS HevcDecodeSliceLongG12::InitSliceStateParams(
487     PMHW_VDBOX_HEVC_SLICE_STATE_G12  sliceState,
488     PCODEC_HEVC_SLICE_PARAMS         sliceParams,
489     PCODEC_HEVC_EXT_SLICE_PARAMS     extSliceParams,
490     PHEVC_TILE_SLICE_PARAMS          tileSliceParams,
491     PHEVC_SLICE_TILE_PARAMS          sliceTileParams,
492     uint16_t                         tileIndex)
493 {
494     CODECHAL_DECODE_CHK_NULL_RETURN(sliceState);
495     CODECHAL_DECODE_CHK_NULL_RETURN(sliceParams);
496 
497     sliceState->presDataBuffer = m_copyDataBufferInUse ? m_resCopyDataBuffer : m_resDataBuffer;
498     sliceState->pHevcPicParams = m_hevcPicParams;
499     sliceState->pHevcExtPicParam = m_hevcExtPicParams;
500     sliceState->pHevcSccPicParam = m_hevcSccPicParams;
501     sliceState->pRefIdxMapping = m_refIdxMapping;
502     sliceState->bTileInSlice = (sliceTileParams != nullptr);
503     sliceState->pHevcSliceParams = sliceParams;
504     sliceState->pHevcExtSliceParams = extSliceParams;
505     if (tileSliceParams)
506     {
507         sliceState->bLastSliceInTile       = tileSliceParams->lastSliceOfTile;
508         sliceState->bLastSliceInTileColumn = (sliceState->bLastSliceInTile && (tileSliceParams->tileY == m_hevcPicParams->num_tile_rows_minus1));
509     }
510     if (sliceTileParams)
511     {
512         uint16_t tileY = sliceTileParams->tileY + (sliceTileParams->tileX + tileIndex) / (m_hevcPicParams->num_tile_columns_minus1 + 1);
513         sliceState->u16SliceHeaderLength = (tileIndex == 0) ? sliceParams->ByteOffsetToSliceData : 0;
514         sliceState->u16TileCtbX = sliceTileParams->TileArray[tileIndex].ctbX;
515         sliceState->u16TileCtbY = sliceTileParams->TileArray[tileIndex].ctbY;
516         sliceState->dwOffset = sliceTileParams->TileArray[tileIndex].bsdOffset;
517         sliceState->dwLength = sliceTileParams->TileArray[tileIndex].bsdLength;
518         sliceState->bLastSlice = sliceParams->LongSliceFlags.fields.LastSliceOfPic && (tileIndex == sliceTileParams->numTiles - 1);
519         sliceState->bIsNotFirstTile = (tileIndex != 0);
520         sliceState->bLastSliceInTile = true;
521         sliceState->bLastSliceInTileColumn = (tileY == m_hevcPicParams->num_tile_rows_minus1);
522 
523         if (sliceState->bLastSlice)
524         {
525             sliceState->u16NextTileCtbX = 0;
526             sliceState->u16NextTileCtbY = 0;
527         }
528         else if (tileIndex == sliceTileParams->numTiles - 1)
529         {
530             sliceState->u16NextTileCtbX = (sliceParams + 1)->slice_segment_address % m_widthInCtb;
531             sliceState->u16NextTileCtbY = (sliceParams + 1)->slice_segment_address / m_widthInCtb;
532         }
533         else
534         {
535             sliceState->u16NextTileCtbX = sliceTileParams->TileArray[tileIndex + 1].ctbX;
536             sliceState->u16NextTileCtbY = sliceTileParams->TileArray[tileIndex + 1].ctbY;
537         }
538     }
539     else
540     {
541         sliceState->bLastSlice = sliceParams->LongSliceFlags.fields.LastSliceOfPic;
542         sliceState->dwLength = sliceParams->slice_data_size;
543         sliceState->bIsNotFirstTile = false;
544     }
545     return MOS_STATUS_SUCCESS;
546 }
547 
SendRefIdxState(PMOS_COMMAND_BUFFER cmdBuf,PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState)548 MOS_STATUS HevcDecodeSliceLongG12::SendRefIdxState(
549     PMOS_COMMAND_BUFFER             cmdBuf,
550     PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState)
551 {
552     PCODEC_HEVC_SLICE_PARAMS slc = sliceState->pHevcSliceParams;
553 
554     if (!m_hcpInterface->IsHevcISlice(slc->LongSliceFlags.fields.slice_type))
555     {
556         MHW_VDBOX_HEVC_REF_IDX_PARAMS_G12 refIdxParams;
557 
558         FixSliceRefList(slc);
559 
560         refIdxParams.CurrPic = m_hevcPicParams->CurrPic;
561         refIdxParams.ucNumRefForList = slc->num_ref_idx_l0_active_minus1 + 1;
562 
563         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
564             &refIdxParams.RefPicList,
565             sizeof(refIdxParams.RefPicList),
566             &slc->RefPicList,
567             sizeof(slc->RefPicList)));
568 
569         refIdxParams.hevcRefList = (void**)m_hevcRefList;
570         refIdxParams.poc_curr_pic = m_hevcPicParams->CurrPicOrderCntVal;
571         for (uint8_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
572         {
573             refIdxParams.poc_list[i] = m_hevcPicParams->PicOrderCntValList[i];
574         }
575 
576         refIdxParams.pRefIdxMapping = sliceState->pRefIdxMapping;
577         refIdxParams.RefFieldPicFlag = m_hevcPicParams->RefFieldPicFlag;
578         refIdxParams.RefBottomFieldFlag = m_hevcPicParams->RefBottomFieldFlag;
579         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpRefIdxStateCmd(
580             cmdBuf,
581             nullptr,
582             &refIdxParams));
583 
584         if (m_hcpInterface->IsHevcBSlice(slc->LongSliceFlags.fields.slice_type))
585         {
586             refIdxParams.ucList = 1;
587             refIdxParams.ucNumRefForList = slc->num_ref_idx_l1_active_minus1 + 1;
588             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpRefIdxStateCmd(
589                 cmdBuf,
590                 nullptr,
591                 &refIdxParams));
592         }
593     }
594     else if (MEDIA_IS_WA(m_decoder->GetOsInterface()->pfnGetWaTable(m_decoder->GetOsInterface()), WaDummyReference) &&
595         !m_decoder->GetOsInterface()->bSimIsActive)
596     {
597         MHW_VDBOX_HEVC_REF_IDX_PARAMS_G12 refIdxParams;
598         MOS_ZeroMemory(&refIdxParams, sizeof(MHW_VDBOX_HEVC_REF_IDX_PARAMS_G12));
599         refIdxParams.bDummyReference = true;
600         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpRefIdxStateCmd(
601             cmdBuf,
602             nullptr,
603             &refIdxParams));
604     }
605 
606     return MOS_STATUS_SUCCESS;
607 }
608 
SendWeightOffset(PMOS_COMMAND_BUFFER cmdBuf,PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState)609 MOS_STATUS HevcDecodeSliceLongG12::SendWeightOffset(
610     PMOS_COMMAND_BUFFER             cmdBuf,
611     PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState)
612 {
613     PCODEC_HEVC_SLICE_PARAMS        slc = sliceState->pHevcSliceParams;
614     PCODEC_HEVC_EXT_SLICE_PARAMS    slcExt = sliceState->pHevcExtSliceParams;
615 
616     if ((m_hevcPicParams->weighted_pred_flag &&
617         m_hcpInterface->IsHevcPSlice(slc->LongSliceFlags.fields.slice_type)) ||
618         (m_hevcPicParams->weighted_bipred_flag &&
619             m_hcpInterface->IsHevcBSlice(slc->LongSliceFlags.fields.slice_type)))
620     {
621         MHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS weightOffsetParams;
622 
623         weightOffsetParams.ucList = 0;
624 
625         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
626             &weightOffsetParams.LumaWeights[0],
627             sizeof(weightOffsetParams.LumaWeights[0]),
628             &slc->delta_luma_weight_l0,
629             sizeof(slc->delta_luma_weight_l0)));
630 
631         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
632             &weightOffsetParams.LumaWeights[1],
633             sizeof(weightOffsetParams.LumaWeights[1]),
634             &slc->delta_luma_weight_l1,
635             sizeof(slc->delta_luma_weight_l1)));
636 
637         if (slcExt) //REXT
638         {
639             CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
640                 &weightOffsetParams.LumaOffsets[0],
641                 sizeof(weightOffsetParams.LumaOffsets[0]),
642                 &slcExt->luma_offset_l0,
643                 sizeof(slcExt->luma_offset_l0)));
644 
645             CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
646                 &weightOffsetParams.LumaOffsets[1],
647                 sizeof(weightOffsetParams.LumaOffsets[1]),
648                 &slcExt->luma_offset_l1,
649                 sizeof(slcExt->luma_offset_l1)));
650 
651             CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
652                 &weightOffsetParams.ChromaOffsets[0],
653                 sizeof(weightOffsetParams.ChromaOffsets[0]),
654                 &slcExt->ChromaOffsetL0,
655                 sizeof(slcExt->ChromaOffsetL0)));
656 
657             CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
658                 &weightOffsetParams.ChromaOffsets[1],
659                 sizeof(weightOffsetParams.ChromaOffsets[1]),
660                 &slcExt->ChromaOffsetL1,
661                 sizeof(slcExt->ChromaOffsetL1)));
662         }
663         else
664         {
665             for (int32_t i = 0; i < 15; i++)
666             {
667                 weightOffsetParams.LumaOffsets[0][i] = (int16_t)slc->luma_offset_l0[i];
668                 weightOffsetParams.LumaOffsets[1][i] = (int16_t)slc->luma_offset_l1[i];
669 
670                 for (int32_t j = 0; j < 2; j++)
671                 {
672                     weightOffsetParams.ChromaOffsets[0][i][j] = (int16_t)slc->ChromaOffsetL0[i][j];
673                     weightOffsetParams.ChromaOffsets[1][i][j] = (int16_t)slc->ChromaOffsetL1[i][j];
674                 }
675             }
676         }
677 
678         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
679             &weightOffsetParams.ChromaWeights[0],
680             sizeof(weightOffsetParams.ChromaWeights[0]),
681             &slc->delta_chroma_weight_l0,
682             sizeof(slc->delta_chroma_weight_l0)));
683 
684         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
685             &weightOffsetParams.ChromaWeights[1],
686             sizeof(weightOffsetParams.ChromaWeights[1]),
687             &slc->delta_chroma_weight_l1,
688             sizeof(slc->delta_chroma_weight_l1)));
689 
690         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpWeightOffsetStateCmd(
691             cmdBuf,
692             nullptr,
693             &weightOffsetParams));
694 
695         if (m_hcpInterface->IsHevcBSlice(slc->LongSliceFlags.fields.slice_type))
696         {
697             weightOffsetParams.ucList = 1;
698             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpWeightOffsetStateCmd(
699                 cmdBuf,
700                 nullptr,
701                 &weightOffsetParams));
702         }
703     }
704     return MOS_STATUS_SUCCESS;
705 }
706 
SendSecureDecodeState(PMOS_COMMAND_BUFFER cmdBuf,PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState)707 MOS_STATUS HevcDecodeSliceLongG12::SendSecureDecodeState(
708     PMOS_COMMAND_BUFFER             cmdBuf,
709     PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState)
710 {
711     if (m_secureDecoder)
712     {
713         CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AddHcpSecureState(
714             cmdBuf,
715             sliceState));
716     }
717     return MOS_STATUS_SUCCESS;
718 }
719 
SendBsdObj(PMOS_COMMAND_BUFFER cmdBuf,PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState)720 MOS_STATUS HevcDecodeSliceLongG12::SendBsdObj(
721     PMOS_COMMAND_BUFFER             cmdBuf,
722     PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState)
723 {
724     MHW_VDBOX_HCP_BSD_PARAMS    bsdParams;
725     PCODEC_HEVC_SLICE_PARAMS    slc = sliceState->pHevcSliceParams;
726 
727     MOS_ZeroMemory(&bsdParams, sizeof(bsdParams));
728     bsdParams.dwBsdDataLength = sliceState->dwLength;
729     bsdParams.dwBsdDataStartOffset = slc->slice_data_offset + sliceState->dwOffset;
730 
731     CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<MhwVdboxHcpInterface*>(m_hcpInterface)->AddHcpBsdObjectCmd(
732         cmdBuf,
733         &bsdParams));
734 
735     return MOS_STATUS_SUCCESS;
736 }
737