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