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