1 /* 2 * Copyright (c) 2014-2018, 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 mhw_vdbox_hcp_generic.h 24 //! \brief MHW interface for constructing HCP commands for the Vdbox engine 25 //! \details Impelements shared Vdbox HCP command construction functions across all platforms as templates 26 //! 27 28 #ifndef _MHW_VDBOX_HCP_GENERIC_H_ 29 #define _MHW_VDBOX_HCP_GENERIC_H_ 30 31 #include "mhw_vdbox_hcp_interface.h" 32 #include "mhw_cp_interface.h" 33 34 //! MHW Vdbox Hcp generic interface 35 /*! 36 This class defines the shared Hcp command construction functions across all platforms as templates 37 */ 38 template <class THcpCmds> 39 class MhwVdboxHcpInterfaceGeneric : public MhwVdboxHcpInterface 40 { 41 protected: 42 static const uint32_t m_vp9ScalingFactor = (1 << 14); 43 static const uint32_t m_rawUVPlaneAlignment = 4; //! starting Gen9 the alignment is relaxed to 4x instead of 16x 44 static const uint32_t m_reconUVPlaneAlignment = 8; 45 static const uint32_t m_uvPlaneAlignmentLegacy = 8; //! starting Gen9 the alignment is relaxed to 4x instead of 16x 46 47 //! 48 //! \brief Constructor 49 //! MhwVdboxHcpInterfaceGeneric(PMOS_INTERFACE osInterface,MhwMiInterface * miInterface,MhwCpInterface * cpInterface,bool decodeInUse)50 MhwVdboxHcpInterfaceGeneric( 51 PMOS_INTERFACE osInterface, 52 MhwMiInterface *miInterface, 53 MhwCpInterface *cpInterface, 54 bool decodeInUse) : 55 MhwVdboxHcpInterface(osInterface, miInterface, cpInterface, decodeInUse) 56 { 57 MHW_FUNCTION_ENTER; 58 } 59 60 //! 61 //! \brief Destructor 62 //! ~MhwVdboxHcpInterfaceGeneric()63 virtual ~MhwVdboxHcpInterfaceGeneric() {} 64 AddHcpDecodeSurfaceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_SURFACE_PARAMS params)65 MOS_STATUS AddHcpDecodeSurfaceStateCmd( 66 PMOS_COMMAND_BUFFER cmdBuffer, 67 PMHW_VDBOX_SURFACE_PARAMS params) 68 { 69 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 70 71 MHW_FUNCTION_ENTER; 72 73 MHW_MI_CHK_NULL(m_osInterface); 74 MHW_MI_CHK_NULL(params); 75 MHW_ASSERT(params->Mode != CODECHAL_UNSUPPORTED_MODE); 76 77 MHW_MI_CHK_NULL(params->psSurface); 78 79 typename THcpCmds::HCP_SURFACE_STATE_CMD cmd; 80 uint32_t uvPlaneAlignment = m_uvPlaneAlignmentLegacy; 81 82 cmd.DW1.SurfaceId = params->ucSurfaceStateId; 83 cmd.DW1.SurfacePitchMinus1 = params->psSurface->dwPitch - 1; 84 85 if (params->ucSurfaceStateId == CODECHAL_HCP_SRC_SURFACE_ID) 86 { 87 uvPlaneAlignment = params->dwUVPlaneAlignment ? params->dwUVPlaneAlignment : m_rawUVPlaneAlignment; 88 } 89 else 90 { 91 uvPlaneAlignment = params->dwUVPlaneAlignment ? params->dwUVPlaneAlignment : m_reconUVPlaneAlignment; 92 } 93 94 cmd.DW2.YOffsetForUCbInPixel = 95 MOS_ALIGN_CEIL(params->psSurface->UPlaneOffset.iYOffset, uvPlaneAlignment); 96 97 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 98 99 return eStatus; 100 } 101 AddHcpEncodeSurfaceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_SURFACE_PARAMS params)102 MOS_STATUS AddHcpEncodeSurfaceStateCmd( 103 PMOS_COMMAND_BUFFER cmdBuffer, 104 PMHW_VDBOX_SURFACE_PARAMS params) 105 { 106 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 107 108 MHW_FUNCTION_ENTER; 109 110 MHW_MI_CHK_NULL(m_osInterface); 111 MHW_MI_CHK_NULL(params); 112 MHW_ASSERT(params->Mode != CODECHAL_UNSUPPORTED_MODE); 113 114 MHW_MI_CHK_NULL(params->psSurface); 115 116 typename THcpCmds::HCP_SURFACE_STATE_CMD cmd; 117 118 cmd.DW1.SurfaceId = params->ucSurfaceStateId; 119 cmd.DW1.SurfacePitchMinus1 = params->psSurface->dwPitch - 1; 120 121 /* Handling of reconstructed surface is different for Y410 & AYUV formats */ 122 if ((params->ucSurfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) && 123 (params->psSurface->Format == Format_Y410)) 124 cmd.DW1.SurfacePitchMinus1 = params->psSurface->dwPitch / 2 - 1; 125 126 if ((params->ucSurfaceStateId != CODECHAL_HCP_SRC_SURFACE_ID) && 127 (params->psSurface->Format == Format_AYUV)) 128 cmd.DW1.SurfacePitchMinus1 = params->psSurface->dwPitch / 4 - 1; 129 130 cmd.DW2.YOffsetForUCbInPixel = params->psSurface->UPlaneOffset.iYOffset; 131 132 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 133 134 return eStatus; 135 } 136 AddHcpIndObjBaseAddrCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS params)137 MOS_STATUS AddHcpIndObjBaseAddrCmd( 138 PMOS_COMMAND_BUFFER cmdBuffer, 139 PMHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS params) 140 { 141 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 142 143 MHW_FUNCTION_ENTER; 144 145 MHW_MI_CHK_NULL(m_osInterface); 146 MHW_MI_CHK_NULL(params); 147 148 MHW_RESOURCE_PARAMS resourceParams; 149 typename THcpCmds::HCP_IND_OBJ_BASE_ADDR_STATE_CMD cmd; 150 151 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 152 resourceParams.dwLsbNum = MHW_VDBOX_HCP_UPPER_BOUND_STATE_SHIFT; 153 resourceParams.HwCommandType = MOS_MFX_INDIRECT_OBJ_BASE_ADDR; 154 155 // mode specific settings 156 if (CodecHalIsDecodeModeVLD(params->Mode)) 157 { 158 MHW_MI_CHK_NULL(params->presDataBuffer); 159 160 cmd.HcpIndirectBitstreamObjectMemoryAddressAttributes.DW0.Value |= 161 m_cacheabilitySettings[MOS_CODEC_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE].Value; 162 163 resourceParams.presResource = params->presDataBuffer; 164 resourceParams.dwOffset = params->dwDataOffset; 165 resourceParams.pdwCmd = cmd.HcpIndirectBitstreamObjectBaseAddress.DW0_1.Value; 166 resourceParams.dwLocationInCmd = 1; 167 resourceParams.dwSize = params->dwDataSize; 168 resourceParams.bIsWritable = false; 169 170 // upper bound of the allocated resource will be set at 3 DW apart from address location 171 resourceParams.dwUpperBoundLocationOffsetFromCmd = 3; 172 173 MHW_MI_CHK_STATUS(pfnAddResourceToCmd( 174 m_osInterface, 175 cmdBuffer, 176 &resourceParams)); 177 } 178 179 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 180 181 return eStatus; 182 } 183 AddHcpQmStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_QM_PARAMS params)184 MOS_STATUS AddHcpQmStateCmd( 185 PMOS_COMMAND_BUFFER cmdBuffer, 186 PMHW_VDBOX_QM_PARAMS params) 187 { 188 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 189 190 MHW_FUNCTION_ENTER; 191 192 MHW_MI_CHK_NULL(m_osInterface); 193 MHW_MI_CHK_NULL(cmdBuffer); 194 MHW_MI_CHK_NULL(params); 195 196 if (params->Standard == CODECHAL_HEVC) 197 { 198 typename THcpCmds::HCP_QM_STATE_CMD cmd; 199 uint8_t* qMatrix = nullptr; 200 201 MHW_MI_CHK_NULL(params->pHevcIqMatrix); 202 203 qMatrix = (uint8_t*)cmd.Quantizermatrix; 204 205 for (uint8_t sizeId = 0; sizeId < 4; sizeId++) // 4x4, 8x8, 16x16, 32x32 206 { 207 for (uint8_t predType = 0; predType < 2; predType++) // Intra, Inter 208 { 209 for (uint8_t color = 0; color < 3; color++) // Y, Cb, Cr 210 { 211 if ((sizeId == 3) && (color != 0)) 212 break; 213 214 cmd.DW1.Sizeid = sizeId; 215 cmd.DW1.PredictionType = predType; 216 cmd.DW1.ColorComponent = color; 217 switch (sizeId) 218 { 219 case cmd.SIZEID_4X4: 220 case cmd.SIZEID_8X8: 221 default: 222 cmd.DW1.DcCoefficient = 0; 223 break; 224 case cmd.SIZEID_16X16: 225 cmd.DW1.DcCoefficient = params->pHevcIqMatrix->ListDC16x16[3 * predType + color]; 226 break; 227 case cmd.SIZEID_32X32: 228 cmd.DW1.DcCoefficient = params->pHevcIqMatrix->ListDC32x32[predType]; 229 break; 230 } 231 232 if (sizeId == cmd.SIZEID_4X4) 233 { 234 for (uint8_t i = 0; i < 4; i++) 235 { 236 for (uint8_t ii = 0; ii < 4; ii++) 237 { 238 qMatrix[4 * i + ii] = params->pHevcIqMatrix->List4x4[3 * predType + color][4 * i + ii]; 239 } 240 } 241 } 242 else if (sizeId == cmd.SIZEID_8X8) 243 { 244 for (uint8_t i = 0; i < 8; i++) 245 { 246 for (uint8_t ii = 0; ii < 8; ii++) 247 { 248 qMatrix[8 * i + ii] = params->pHevcIqMatrix->List8x8[3 * predType + color][8 * i + ii]; 249 } 250 } 251 } 252 else if (sizeId == cmd.SIZEID_16X16) 253 { 254 for (uint8_t i = 0; i < 8; i++) 255 { 256 for (uint8_t ii = 0; ii < 8; ii++) 257 { 258 qMatrix[8 * i + ii] = params->pHevcIqMatrix->List16x16[3 * predType + color][8 * i + ii]; 259 } 260 } 261 } 262 else // 32x32 263 { 264 for (uint8_t i = 0; i < 8; i++) 265 { 266 for (uint8_t ii = 0; ii < 8; ii++) 267 { 268 qMatrix[8 * i + ii] = params->pHevcIqMatrix->List32x32[predType][8 * i + ii]; 269 } 270 } 271 } 272 273 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 274 } 275 } 276 } 277 } 278 else 279 { 280 eStatus = MOS_STATUS_INVALID_PARAMETER; 281 } 282 283 return eStatus; 284 } 285 AddHcpDecodePicStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_PIC_STATE params)286 MOS_STATUS AddHcpDecodePicStateCmd( 287 PMOS_COMMAND_BUFFER cmdBuffer, 288 PMHW_VDBOX_HEVC_PIC_STATE params) 289 { 290 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 291 292 MHW_FUNCTION_ENTER; 293 294 MHW_MI_CHK_NULL(m_osInterface); 295 MHW_MI_CHK_NULL(params); 296 MHW_MI_CHK_NULL(params->pHevcPicParams); 297 298 typename THcpCmds::HCP_PIC_STATE_CMD cmd; 299 300 auto hevcPicParams = params->pHevcPicParams; 301 302 cmd.DW1.Framewidthinmincbminus1 = hevcPicParams->PicWidthInMinCbsY - 1; 303 cmd.DW1.Frameheightinmincbminus1 = hevcPicParams->PicHeightInMinCbsY - 1; 304 305 cmd.DW2.Mincusize = (hevcPicParams->log2_min_luma_coding_block_size_minus3) & 0x3; 306 cmd.DW2.CtbsizeLcusize = (hevcPicParams->log2_diff_max_min_luma_coding_block_size 307 + hevcPicParams->log2_min_luma_coding_block_size_minus3) & 0x3; 308 cmd.DW2.Maxtusize = (hevcPicParams->log2_diff_max_min_transform_block_size 309 + hevcPicParams->log2_min_transform_block_size_minus2) & 0x3; 310 cmd.DW2.Mintusize = (hevcPicParams->log2_min_transform_block_size_minus2) & 0x3; 311 cmd.DW2.Minpcmsize = (hevcPicParams->log2_min_pcm_luma_coding_block_size_minus3) & 0x3; 312 cmd.DW2.Maxpcmsize = (hevcPicParams->log2_diff_max_min_pcm_luma_coding_block_size 313 + hevcPicParams->log2_min_pcm_luma_coding_block_size_minus3) & 0x3; 314 315 // As per HW requirement, CurPicIsI and ColPicIsI should be set to either both correct or both zero 316 // Since driver doesn't know Collocated_Ref_Idx for SF, and cannot get accurate CurPicIsI for both LF/SF 317 // Have to make ColPicIsI = CurPicIsI = 0 for both LF/SF 318 cmd.DW3.Colpicisi = 0; 319 cmd.DW3.Curpicisi = 0; 320 321 cmd.DW4.SampleAdaptiveOffsetEnabledFlag = hevcPicParams->sample_adaptive_offset_enabled_flag; 322 cmd.DW4.PcmEnabledFlag = hevcPicParams->pcm_enabled_flag; 323 cmd.DW4.CuQpDeltaEnabledFlag = hevcPicParams->cu_qp_delta_enabled_flag; 324 cmd.DW4.DiffCuQpDeltaDepthOrNamedAsMaxDqpDepth = hevcPicParams->diff_cu_qp_delta_depth; 325 cmd.DW4.PcmLoopFilterDisableFlag = hevcPicParams->pcm_loop_filter_disabled_flag; 326 cmd.DW4.ConstrainedIntraPredFlag = hevcPicParams->constrained_intra_pred_flag; 327 cmd.DW4.Log2ParallelMergeLevelMinus2 = hevcPicParams->log2_parallel_merge_level_minus2; 328 cmd.DW4.SignDataHidingFlag = hevcPicParams->sign_data_hiding_enabled_flag; 329 cmd.DW4.LoopFilterAcrossTilesEnabledFlag = hevcPicParams->loop_filter_across_tiles_enabled_flag; 330 cmd.DW4.EntropyCodingSyncEnabledFlag = hevcPicParams->entropy_coding_sync_enabled_flag; 331 cmd.DW4.TilesEnabledFlag = hevcPicParams->tiles_enabled_flag; 332 cmd.DW4.WeightedPredFlag = hevcPicParams->weighted_pred_flag; 333 cmd.DW4.WeightedBipredFlag = hevcPicParams->weighted_bipred_flag; 334 cmd.DW4.Fieldpic = (hevcPicParams->RefFieldPicFlag >> 15) & 0x01; 335 cmd.DW4.Bottomfield = ((hevcPicParams->RefBottomFieldFlag >> 15) & 0x01) ? 0 : 1; 336 cmd.DW4.TransformSkipEnabledFlag = hevcPicParams->transform_skip_enabled_flag; 337 cmd.DW4.AmpEnabledFlag = hevcPicParams->amp_enabled_flag; 338 cmd.DW4.TransquantBypassEnableFlag = hevcPicParams->transquant_bypass_enabled_flag; 339 cmd.DW4.StrongIntraSmoothingEnableFlag = hevcPicParams->strong_intra_smoothing_enabled_flag; 340 341 cmd.DW5.PicCbQpOffset = hevcPicParams->pps_cb_qp_offset & 0x1f; 342 cmd.DW5.PicCrQpOffset = hevcPicParams->pps_cr_qp_offset & 0x1f; 343 cmd.DW5.MaxTransformHierarchyDepthIntraOrNamedAsTuMaxDepthIntra = hevcPicParams->max_transform_hierarchy_depth_intra & 0x7; 344 cmd.DW5.MaxTransformHierarchyDepthInterOrNamedAsTuMaxDepthInter = hevcPicParams->max_transform_hierarchy_depth_inter & 0x7; 345 cmd.DW5.PcmSampleBitDepthChromaMinus1 = hevcPicParams->pcm_sample_bit_depth_chroma_minus1; 346 cmd.DW5.PcmSampleBitDepthLumaMinus1 = hevcPicParams->pcm_sample_bit_depth_luma_minus1; 347 348 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 349 350 return eStatus; 351 } 352 AddHcpBsdObjectCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HCP_BSD_PARAMS params)353 MOS_STATUS AddHcpBsdObjectCmd( 354 PMOS_COMMAND_BUFFER cmdBuffer, 355 PMHW_VDBOX_HCP_BSD_PARAMS params) 356 { 357 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 358 359 MHW_FUNCTION_ENTER; 360 361 MHW_MI_CHK_NULL(m_osInterface); 362 typename THcpCmds::HCP_BSD_OBJECT_CMD cmd; 363 364 cmd.DW1.IndirectBsdDataLength = params->dwBsdDataLength; 365 cmd.DW2.IndirectDataStartAddress = params->dwBsdDataStartOffset; 366 367 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 368 369 return eStatus; 370 } 371 AddHcpTileStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_TILE_STATE params)372 MOS_STATUS AddHcpTileStateCmd( 373 PMOS_COMMAND_BUFFER cmdBuffer, 374 PMHW_VDBOX_HEVC_TILE_STATE params) 375 { 376 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 377 378 MHW_FUNCTION_ENTER; 379 380 typename THcpCmds::HCP_TILE_STATE_CMD cmd; 381 382 MHW_MI_CHK_NULL(m_osInterface); 383 MHW_MI_CHK_NULL(params); 384 MHW_MI_CHK_NULL(params->pTileColWidth); 385 MHW_MI_CHK_NULL(params->pTileRowHeight); 386 387 auto hevcPicParams = params->pHevcPicParams; 388 uint32_t colCumulativeValue = 0; 389 uint32_t rowCumulativeValue = 0; 390 391 MHW_ASSERT(hevcPicParams->num_tile_rows_minus1 < HEVC_NUM_MAX_TILE_ROW); 392 MHW_ASSERT(hevcPicParams->num_tile_columns_minus1 < HEVC_NUM_MAX_TILE_COLUMN); 393 394 cmd.DW1.Numtilecolumnsminus1 = hevcPicParams->num_tile_columns_minus1; 395 cmd.DW1.Numtilerowsminus1 = hevcPicParams->num_tile_rows_minus1; 396 397 for (uint8_t i = 0; i < 5; i++) 398 { 399 cmd.CtbColumnPositionOfTileColumn[i].DW0.Ctbpos0I = colCumulativeValue; 400 if ((4 * i) == hevcPicParams->num_tile_columns_minus1) 401 { 402 break; 403 } 404 405 colCumulativeValue += params->pTileColWidth[4 * i]; 406 cmd.CtbColumnPositionOfTileColumn[i].DW0.Ctbpos1I = colCumulativeValue; 407 if ((4 * i + 1) == hevcPicParams->num_tile_columns_minus1) 408 { 409 break; 410 } 411 412 colCumulativeValue += params->pTileColWidth[4 * i + 1]; 413 cmd.CtbColumnPositionOfTileColumn[i].DW0.Ctbpos2I = colCumulativeValue; 414 if ((4 * i + 2) == hevcPicParams->num_tile_columns_minus1) 415 { 416 break; 417 } 418 419 colCumulativeValue += params->pTileColWidth[4 * i + 2]; 420 cmd.CtbColumnPositionOfTileColumn[i].DW0.Ctbpos3I = colCumulativeValue; 421 if ((4 * i + 3) == hevcPicParams->num_tile_columns_minus1) 422 { 423 break; 424 } 425 426 colCumulativeValue += params->pTileColWidth[4 * i + 3]; 427 } 428 429 for (uint8_t i = 0; i < 5; i++) 430 { 431 cmd.CtbRowPositionOfTileRow[i].DW0.Ctbpos0I = rowCumulativeValue; 432 if ((4 * i) == hevcPicParams->num_tile_rows_minus1) 433 { 434 break; 435 } 436 437 rowCumulativeValue += params->pTileRowHeight[4 * i]; 438 cmd.CtbRowPositionOfTileRow[i].DW0.Ctbpos1I = rowCumulativeValue; 439 if ((4 * i + 1) == hevcPicParams->num_tile_rows_minus1) 440 { 441 break; 442 } 443 444 rowCumulativeValue += params->pTileRowHeight[4 * i + 1]; 445 cmd.CtbRowPositionOfTileRow[i].DW0.Ctbpos2I = rowCumulativeValue; 446 if ((4 * i + 2) == hevcPicParams->num_tile_rows_minus1) 447 { 448 break; 449 } 450 451 rowCumulativeValue += params->pTileRowHeight[4 * i + 2]; 452 cmd.CtbRowPositionOfTileRow[i].DW0.Ctbpos3I = rowCumulativeValue; 453 if ((4 * i + 3) == hevcPicParams->num_tile_rows_minus1) 454 { 455 break; 456 } 457 458 rowCumulativeValue += params->pTileRowHeight[4 * i + 3]; 459 } 460 461 if (hevcPicParams->num_tile_rows_minus1 == 20) 462 { 463 cmd.CtbRowPositionOfTileRow[5].DW0.Ctbpos0I = rowCumulativeValue; 464 } 465 466 if (hevcPicParams->num_tile_rows_minus1 == 21) 467 { 468 cmd.CtbRowPositionOfTileRow[5].DW0.Ctbpos0I = rowCumulativeValue; 469 rowCumulativeValue += params->pTileRowHeight[20]; 470 cmd.CtbRowPositionOfTileRow[5].DW0.Ctbpos1I = rowCumulativeValue; 471 } 472 473 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 474 475 return eStatus; 476 } 477 AddHcpRefIdxStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_HEVC_REF_IDX_PARAMS params)478 MOS_STATUS AddHcpRefIdxStateCmd( 479 PMOS_COMMAND_BUFFER cmdBuffer, 480 PMHW_BATCH_BUFFER batchBuffer, 481 PMHW_VDBOX_HEVC_REF_IDX_PARAMS params) 482 { 483 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 484 485 MHW_FUNCTION_ENTER; 486 487 MHW_MI_CHK_NULL(params); 488 489 typename THcpCmds::HCP_REF_IDX_STATE_CMD cmd; 490 491 // Need to add an empty HCP_REF_IDX_STATE_CMD for dummy reference on I-Frame 492 // ucNumRefForList could be 0 for encode 493 if (!params->bDummyReference) 494 { 495 MHW_ASSERT(params->CurrPic.FrameIdx != 0x7F); 496 497 cmd.DW1.Refpiclistnum = params->ucList; 498 cmd.DW1.NumRefIdxLRefpiclistnumActiveMinus1 = params->ucNumRefForList - 1; 499 500 for (uint8_t i = 0; i < params->ucNumRefForList; i++) 501 { 502 uint8_t refFrameIDx = params->RefPicList[params->ucList][i].FrameIdx; 503 if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC) 504 { 505 MHW_ASSERT(*(params->pRefIdxMapping + refFrameIDx) >= 0); 506 507 cmd.Entries[i].DW0.ListEntryLxReferencePictureFrameIdRefaddr07 = *(params->pRefIdxMapping + refFrameIDx); 508 int32_t pocDiff = params->poc_curr_pic - params->poc_list[refFrameIDx]; 509 cmd.Entries[i].DW0.ReferencePictureTbValue = CodecHal_Clip3(-128, 127, pocDiff); 510 CODEC_REF_LIST** refList = (CODEC_REF_LIST**)params->hevcRefList; 511 cmd.Entries[i].DW0.Longtermreference = CodecHal_PictureIsLongTermRef(refList[params->CurrPic.FrameIdx]->RefList[refFrameIDx]); 512 cmd.Entries[i].DW0.FieldPicFlag = (params->RefFieldPicFlag >> refFrameIDx) & 0x01; 513 cmd.Entries[i].DW0.BottomFieldFlag = ((params->RefBottomFieldFlag >> refFrameIDx) & 0x01) ? 0 : 1; 514 } 515 else 516 { 517 cmd.Entries[i].DW0.ListEntryLxReferencePictureFrameIdRefaddr07 = 0; 518 cmd.Entries[i].DW0.ReferencePictureTbValue = 0; 519 cmd.Entries[i].DW0.Longtermreference = false; 520 cmd.Entries[i].DW0.FieldPicFlag = 0; 521 cmd.Entries[i].DW0.BottomFieldFlag = 0; 522 } 523 } 524 525 for (uint8_t i = (uint8_t)params->ucNumRefForList; i < 16; i++) 526 { 527 cmd.Entries[i].DW0.Value = 0x00; 528 } 529 } 530 531 if (cmdBuffer == nullptr && batchBuffer == nullptr) 532 { 533 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 534 return MOS_STATUS_INVALID_PARAMETER; 535 } 536 537 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize)); 538 539 return eStatus; 540 } 541 AddHcpWeightOffsetStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS params)542 MOS_STATUS AddHcpWeightOffsetStateCmd( 543 PMOS_COMMAND_BUFFER cmdBuffer, 544 PMHW_BATCH_BUFFER batchBuffer, 545 PMHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS params) 546 { 547 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 548 549 MHW_FUNCTION_ENTER; 550 551 MHW_MI_CHK_NULL(params); 552 553 typename THcpCmds::HCP_WEIGHTOFFSET_STATE_CMD cmd; 554 uint8_t i = 0; 555 556 cmd.DW1.Refpiclistnum = i = params->ucList; 557 558 // Luma 559 for (uint8_t refIdx = 0; refIdx < CODEC_MAX_NUM_REF_FRAME_HEVC; refIdx++) 560 { 561 cmd.Lumaoffsets[refIdx].DW0.DeltaLumaWeightLxI = params->LumaWeights[i][refIdx]; 562 cmd.Lumaoffsets[refIdx].DW0.LumaOffsetLxI = params->LumaOffsets[i][refIdx]; 563 } 564 565 // Chroma 566 for (uint8_t refIdx = 0; refIdx < CODEC_MAX_NUM_REF_FRAME_HEVC; refIdx++) 567 { 568 cmd.Chromaoffsets[refIdx].DW0.DeltaChromaWeightLxI0 = params->ChromaWeights[i][refIdx][0]; 569 cmd.Chromaoffsets[refIdx].DW0.ChromaoffsetlxI0 = params->ChromaOffsets[i][refIdx][0]; 570 cmd.Chromaoffsets[refIdx].DW0.DeltaChromaWeightLxI1 = params->ChromaWeights[i][refIdx][1]; 571 cmd.Chromaoffsets[refIdx].DW0.ChromaoffsetlxI1 = params->ChromaOffsets[i][refIdx][1]; 572 } 573 574 //cmd.DW2[15] and cmd.DW18[15] not be used 575 576 if (cmdBuffer == nullptr && batchBuffer == nullptr) 577 { 578 MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to."); 579 return MOS_STATUS_INVALID_PARAMETER; 580 } 581 582 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize)); 583 584 return eStatus; 585 } 586 AddHcpDecodeSliceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState)587 MOS_STATUS AddHcpDecodeSliceStateCmd( 588 PMOS_COMMAND_BUFFER cmdBuffer, 589 PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState) 590 { 591 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 592 593 MHW_FUNCTION_ENTER; 594 595 MHW_MI_CHK_NULL(m_osInterface); 596 MHW_MI_CHK_NULL(hevcSliceState); 597 598 typename THcpCmds::HCP_SLICE_STATE_CMD cmd; 599 600 auto hevcSliceParams = hevcSliceState->pHevcSliceParams; 601 auto hevcPicParams = hevcSliceState->pHevcPicParams; 602 603 uint32_t ctbSize = 1 << (hevcPicParams->log2_diff_max_min_luma_coding_block_size + 604 hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3); 605 uint32_t widthInPix = (1 << (hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) * 606 (hevcPicParams->PicWidthInMinCbsY); 607 uint32_t widthInCtb = MOS_ROUNDUP_DIVIDE(widthInPix, ctbSize); 608 609 // It is a hardware requirement that the first HCP_SLICE_STATE of the workload starts at LCU X,Y = 0,0. 610 // If first slice doesn't starts from (0,0), that means this is error bitstream. 611 if (hevcSliceState->dwSliceIndex == 0) 612 { 613 cmd.DW1.SlicestartctbxOrSliceStartLcuXEncoder = 0; 614 cmd.DW1.SlicestartctbyOrSliceStartLcuYEncoder = 0; 615 } 616 else 617 { 618 cmd.DW1.SlicestartctbxOrSliceStartLcuXEncoder = hevcSliceParams->slice_segment_address % widthInCtb; 619 cmd.DW1.SlicestartctbyOrSliceStartLcuYEncoder = hevcSliceParams->slice_segment_address / widthInCtb; 620 } 621 622 if (hevcSliceState->bLastSlice) 623 { 624 cmd.DW2.NextslicestartctbxOrNextSliceStartLcuXEncoder = 0; 625 cmd.DW2.NextslicestartctbyOrNextSliceStartLcuYEncoder = 0; 626 } 627 else 628 { 629 cmd.DW2.NextslicestartctbxOrNextSliceStartLcuXEncoder = (hevcSliceParams + 1)->slice_segment_address % widthInCtb; 630 cmd.DW2.NextslicestartctbyOrNextSliceStartLcuYEncoder = (hevcSliceParams + 1)->slice_segment_address / widthInCtb; 631 } 632 633 cmd.DW3.SliceType = hevcSliceParams->LongSliceFlags.fields.slice_type; 634 cmd.DW3.Lastsliceofpic = hevcSliceState->bLastSlice; 635 cmd.DW3.DependentSliceFlag = hevcSliceParams->LongSliceFlags.fields.dependent_slice_segment_flag; 636 cmd.DW3.SliceTemporalMvpEnableFlag = hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag; 637 cmd.DW3.SliceCbQpOffset = hevcSliceParams->slice_cb_qp_offset; 638 cmd.DW3.SliceCrQpOffset = hevcSliceParams->slice_cr_qp_offset; 639 640 cmd.DW4.SliceHeaderDisableDeblockingFilterFlag = hevcSliceParams->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag; 641 cmd.DW4.SliceTcOffsetDiv2OrFinalTcOffsetDiv2Encoder = hevcSliceParams->slice_tc_offset_div2; 642 cmd.DW4.SliceBetaOffsetDiv2OrFinalBetaOffsetDiv2Encoder = hevcSliceParams->slice_beta_offset_div2; 643 cmd.DW4.SliceLoopFilterAcrossSlicesEnabledFlag = hevcSliceParams->LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag; 644 cmd.DW4.SliceSaoChromaFlag = hevcSliceParams->LongSliceFlags.fields.slice_sao_chroma_flag; 645 cmd.DW4.SliceSaoLumaFlag = hevcSliceParams->LongSliceFlags.fields.slice_sao_luma_flag; 646 cmd.DW4.MvdL1ZeroFlag = hevcSliceParams->LongSliceFlags.fields.mvd_l1_zero_flag; 647 648 uint8_t isLowDelay = 1; 649 650 if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE) 651 { 652 isLowDelay = 0; 653 } 654 else 655 { 656 for (uint8_t i = 0; i < hevcSliceParams->num_ref_idx_l0_active_minus1 + 1; i++) 657 { 658 uint8_t refFrameID = hevcSliceParams->RefPicList[0][i].FrameIdx; 659 if (hevcPicParams->PicOrderCntValList[refFrameID] > hevcPicParams->CurrPicOrderCntVal) 660 { 661 isLowDelay = 0; 662 break; 663 } 664 } 665 666 if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_B_SLICE) 667 { 668 for (uint8_t i = 0; i < hevcSliceParams->num_ref_idx_l1_active_minus1 + 1; i++) 669 { 670 uint8_t refFrameID = hevcSliceParams->RefPicList[1][i].FrameIdx; 671 if (hevcPicParams->PicOrderCntValList[refFrameID] > hevcPicParams->CurrPicOrderCntVal) 672 { 673 isLowDelay = 0; 674 break; 675 } 676 } 677 } 678 } 679 680 cmd.DW4.Islowdelay = isLowDelay & 0x1; 681 682 cmd.DW4.CollocatedFromL0Flag = hevcSliceParams->LongSliceFlags.fields.collocated_from_l0_flag; 683 cmd.DW4.Chromalog2Weightdenom = hevcSliceParams->luma_log2_weight_denom + hevcSliceParams->delta_chroma_log2_weight_denom; 684 cmd.DW4.LumaLog2WeightDenom = hevcSliceParams->luma_log2_weight_denom; 685 cmd.DW4.CabacInitFlag = hevcSliceParams->LongSliceFlags.fields.cabac_init_flag; 686 cmd.DW4.Maxmergeidx = 5 - hevcSliceParams->five_minus_max_num_merge_cand - 1; 687 688 uint8_t collocatedRefIndex, collocatedFrameIdx, collocatedFromL0Flag; 689 690 if (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1) 691 { 692 //Get Collocated Picture POC 693 collocatedRefIndex = hevcSliceParams->collocated_ref_idx; 694 collocatedFrameIdx = 0; 695 collocatedFromL0Flag = hevcSliceParams->LongSliceFlags.fields.collocated_from_l0_flag; 696 if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_P_SLICE) 697 { 698 collocatedFrameIdx = hevcSliceParams->RefPicList[0][collocatedRefIndex].FrameIdx; 699 } 700 else if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_B_SLICE) 701 { 702 collocatedFrameIdx = hevcSliceParams->RefPicList[!collocatedFromL0Flag][collocatedRefIndex].FrameIdx; 703 } 704 705 if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE) 706 { 707 cmd.DW4.Collocatedrefidx = 0; 708 } 709 else 710 { 711 MHW_CHK_COND(*(hevcSliceState->pRefIdxMapping + collocatedFrameIdx) < 0, "Invalid parameter"); 712 cmd.DW4.Collocatedrefidx = *(hevcSliceState->pRefIdxMapping + collocatedFrameIdx); 713 } 714 } 715 else 716 { 717 cmd.DW4.Collocatedrefidx = 0; 718 } 719 720 static uint8_t ucFirstInterSliceCollocatedFrameIdx; 721 static uint8_t ucFirstInterSliceCollocatedFromL0Flag; 722 static bool bFinishFirstInterSlice; 723 724 //Need to save the first interSlice collocatedRefIdx value to use on subsequent intra slices 725 //this is a HW requrement as collcoated ref fetching from memory may not be complete yet 726 if (hevcSliceState->dwSliceIndex == 0) 727 { 728 ucFirstInterSliceCollocatedFrameIdx = 0; 729 ucFirstInterSliceCollocatedFromL0Flag = 0; 730 bFinishFirstInterSlice = false; 731 } 732 733 if ((!bFinishFirstInterSlice) && 734 (hevcSliceParams->LongSliceFlags.fields.slice_type != cmd.SLICE_TYPE_I_SLICE) && 735 (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1)) 736 { 737 ucFirstInterSliceCollocatedFrameIdx = cmd.DW4.Collocatedrefidx; 738 ucFirstInterSliceCollocatedFromL0Flag = cmd.DW4.CollocatedFromL0Flag; 739 bFinishFirstInterSlice = true; 740 } 741 742 if (bFinishFirstInterSlice && 743 ((hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE) || 744 (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 0))) 745 { 746 cmd.DW4.Collocatedrefidx = ucFirstInterSliceCollocatedFrameIdx; 747 cmd.DW4.CollocatedFromL0Flag = ucFirstInterSliceCollocatedFromL0Flag; 748 } 749 750 cmd.DW5.Sliceheaderlength = hevcSliceParams->ByteOffsetToSliceData; 751 752 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 753 754 return eStatus; 755 } 756 AddHcpEncodeSliceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState)757 MOS_STATUS AddHcpEncodeSliceStateCmd( 758 PMOS_COMMAND_BUFFER cmdBuffer, 759 PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState) 760 { 761 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 762 763 MHW_FUNCTION_ENTER; 764 765 MHW_MI_CHK_NULL(cmdBuffer); 766 MHW_MI_CHK_NULL(m_osInterface); 767 MHW_MI_CHK_NULL(hevcSliceState); 768 769 typename THcpCmds::HCP_SLICE_STATE_CMD cmd; 770 771 auto hevcSliceParams = hevcSliceState->pHevcSliceParams; 772 auto hevcPicParams = hevcSliceState->pHevcPicParams; 773 774 uint32_t ctbSize = 1 << (hevcPicParams->log2_diff_max_min_luma_coding_block_size + 775 hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3); 776 uint32_t widthInPix = (1 << (hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) * 777 (hevcPicParams->PicWidthInMinCbsY); 778 uint32_t widthInCtb = MOS_ROUNDUP_DIVIDE(widthInPix, ctbSize); 779 780 // It is a hardware requirement that the first HCP_SLICE_STATE of the workload starts at LCU X,Y = 0,0. 781 // If first slice doesn't starts from (0,0), that means this is error bitstream. 782 if (hevcSliceState->dwSliceIndex == 0) 783 { 784 cmd.DW1.SlicestartctbxOrSliceStartLcuXEncoder = 0; 785 cmd.DW1.SlicestartctbyOrSliceStartLcuYEncoder = 0; 786 } 787 else 788 { 789 cmd.DW1.SlicestartctbxOrSliceStartLcuXEncoder = hevcSliceParams->slice_segment_address % widthInCtb; 790 cmd.DW1.SlicestartctbyOrSliceStartLcuYEncoder = hevcSliceParams->slice_segment_address / widthInCtb; 791 } 792 793 if (hevcSliceState->bLastSlice) 794 { 795 cmd.DW2.NextslicestartctbxOrNextSliceStartLcuXEncoder = 0; 796 cmd.DW2.NextslicestartctbyOrNextSliceStartLcuYEncoder = 0; 797 } 798 else 799 { 800 cmd.DW2.NextslicestartctbxOrNextSliceStartLcuXEncoder = (hevcSliceParams + 1)->slice_segment_address % widthInCtb; 801 cmd.DW2.NextslicestartctbyOrNextSliceStartLcuYEncoder = (hevcSliceParams + 1)->slice_segment_address / widthInCtb; 802 } 803 804 cmd.DW3.SliceType = hevcSliceParams->LongSliceFlags.fields.slice_type; 805 cmd.DW3.Lastsliceofpic = hevcSliceState->bLastSlice; 806 cmd.DW3.DependentSliceFlag = hevcSliceParams->LongSliceFlags.fields.dependent_slice_segment_flag; 807 cmd.DW3.SliceTemporalMvpEnableFlag = hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag; 808 cmd.DW3.Sliceqp = hevcSliceParams->slice_qp_delta + hevcPicParams->init_qp_minus26 + 26; 809 cmd.DW3.SliceCbQpOffset = hevcSliceParams->slice_cb_qp_offset; 810 cmd.DW3.SliceCrQpOffset = hevcSliceParams->slice_cr_qp_offset; 811 812 cmd.DW4.SliceHeaderDisableDeblockingFilterFlag = hevcSliceParams->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag; 813 cmd.DW4.SliceTcOffsetDiv2OrFinalTcOffsetDiv2Encoder = hevcSliceParams->slice_tc_offset_div2; 814 cmd.DW4.SliceBetaOffsetDiv2OrFinalBetaOffsetDiv2Encoder = hevcSliceParams->slice_beta_offset_div2; 815 cmd.DW4.SliceLoopFilterAcrossSlicesEnabledFlag = hevcSliceParams->LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag; 816 cmd.DW4.SliceSaoChromaFlag = hevcSliceParams->LongSliceFlags.fields.slice_sao_chroma_flag; 817 cmd.DW4.SliceSaoLumaFlag = hevcSliceParams->LongSliceFlags.fields.slice_sao_luma_flag; 818 cmd.DW4.MvdL1ZeroFlag = hevcSliceParams->LongSliceFlags.fields.mvd_l1_zero_flag; 819 820 uint32_t numNegativePic = 0; 821 uint32_t numPositivePic = 0; 822 823 if (hevcSliceParams->LongSliceFlags.fields.slice_type != cmd.SLICE_TYPE_I_SLICE) 824 { 825 for (uint8_t i = 0; i < hevcSliceParams->num_ref_idx_l0_active_minus1 + 1; i++) 826 { 827 uint8_t refFrameID = hevcSliceParams->RefPicList[0][i].FrameIdx; 828 int32_t pocDiff = hevcPicParams->CurrPicOrderCntVal - hevcPicParams->PicOrderCntValList[refFrameID]; 829 if (pocDiff > 0) 830 { 831 numNegativePic++; 832 } 833 } 834 } 835 else 836 { 837 numNegativePic = 0; 838 } 839 840 if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_B_SLICE) 841 { 842 for (uint8_t i = 0; i < hevcSliceParams->num_ref_idx_l1_active_minus1 + 1; i++) 843 { 844 uint8_t refFrameID = hevcSliceParams->RefPicList[1][i].FrameIdx; 845 int32_t pocDiff = hevcPicParams->CurrPicOrderCntVal - hevcPicParams->PicOrderCntValList[refFrameID]; 846 if (pocDiff < 0) 847 { 848 numPositivePic++; 849 } 850 } 851 } 852 else 853 { 854 numPositivePic = 0; 855 } 856 857 if ((numNegativePic == (hevcSliceParams->num_ref_idx_l0_active_minus1 + 1)) && 858 (numPositivePic == 0)) 859 { 860 cmd.DW4.Islowdelay = 1; 861 } 862 else 863 { 864 cmd.DW4.Islowdelay = 0; 865 } 866 867 cmd.DW4.CollocatedFromL0Flag = hevcSliceParams->LongSliceFlags.fields.collocated_from_l0_flag; 868 cmd.DW4.Chromalog2Weightdenom = (hevcPicParams->weighted_pred_flag || hevcPicParams->weighted_bipred_flag) ? 869 (hevcSliceParams->luma_log2_weight_denom + hevcSliceParams->delta_chroma_log2_weight_denom) : 0; 870 cmd.DW4.LumaLog2WeightDenom = (hevcPicParams->weighted_pred_flag || hevcPicParams->weighted_bipred_flag) ? 871 hevcSliceParams->luma_log2_weight_denom : 0; 872 cmd.DW4.CabacInitFlag = hevcSliceParams->LongSliceFlags.fields.cabac_init_flag; 873 cmd.DW4.Maxmergeidx = 5 - hevcSliceParams->five_minus_max_num_merge_cand - 1; 874 875 uint8_t collocatedRefIndex, collocatedFrameIdx, collocatedFromL0Flag; 876 877 if (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1) 878 { 879 //Get Collocated Picture POC 880 collocatedRefIndex = hevcSliceParams->collocated_ref_idx; 881 collocatedFrameIdx = 0; 882 collocatedFromL0Flag = hevcSliceParams->LongSliceFlags.fields.collocated_from_l0_flag; 883 if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_P_SLICE) 884 { 885 collocatedFrameIdx = hevcSliceParams->RefPicList[0][collocatedRefIndex].FrameIdx; 886 } 887 else if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_B_SLICE) 888 { 889 collocatedFrameIdx = hevcSliceParams->RefPicList[!collocatedFromL0Flag][collocatedRefIndex].FrameIdx; 890 } 891 892 if (hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE) 893 { 894 cmd.DW4.Collocatedrefidx = 0; 895 } 896 else 897 { 898 MHW_CHK_COND(*(hevcSliceState->pRefIdxMapping + collocatedFrameIdx) < 0, "Invalid parameter"); 899 cmd.DW4.Collocatedrefidx = *(hevcSliceState->pRefIdxMapping + collocatedFrameIdx); 900 } 901 } 902 else 903 { 904 cmd.DW4.Collocatedrefidx = 0; 905 } 906 907 static uint8_t ucFirstInterSliceCollocatedFrameIdx; 908 static uint8_t ucFirstInterSliceCollocatedFromL0Flag; 909 static bool bFinishFirstInterSlice; 910 911 //Need to save the first interSlice collocatedRefIdx value to use on subsequent intra slices 912 //this is a HW requrement as collcoated ref fetching from memory may not be complete yet 913 if (hevcSliceState->dwSliceIndex == 0) 914 { 915 ucFirstInterSliceCollocatedFrameIdx = 0; 916 ucFirstInterSliceCollocatedFromL0Flag = 0; 917 bFinishFirstInterSlice = false; 918 } 919 920 if ((!bFinishFirstInterSlice) && 921 (hevcSliceParams->LongSliceFlags.fields.slice_type != cmd.SLICE_TYPE_I_SLICE) && 922 (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 1)) 923 { 924 ucFirstInterSliceCollocatedFrameIdx = cmd.DW4.Collocatedrefidx; 925 ucFirstInterSliceCollocatedFromL0Flag = cmd.DW4.CollocatedFromL0Flag; 926 bFinishFirstInterSlice = true; 927 } 928 929 if (bFinishFirstInterSlice && 930 ((hevcSliceParams->LongSliceFlags.fields.slice_type == cmd.SLICE_TYPE_I_SLICE) || 931 (hevcSliceParams->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag == 0))) 932 { 933 cmd.DW4.Collocatedrefidx = ucFirstInterSliceCollocatedFrameIdx; 934 cmd.DW4.CollocatedFromL0Flag = ucFirstInterSliceCollocatedFromL0Flag; 935 } 936 937 cmd.DW5.Sliceheaderlength = hevcSliceParams->ByteOffsetToSliceData; 938 939 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize)); 940 941 return eStatus; 942 } 943 AddHcpDecodeProtectStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState)944 MOS_STATUS AddHcpDecodeProtectStateCmd( 945 PMOS_COMMAND_BUFFER cmdBuffer, 946 PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState) 947 { 948 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 949 950 MHW_FUNCTION_ENTER; 951 952 MHW_MI_CHK_NULL(hevcSliceState); 953 954 MHW_CP_SLICE_INFO_PARAMS sliceInfoParam; 955 sliceInfoParam.presDataBuffer = hevcSliceState->presDataBuffer; 956 sliceInfoParam.dwSliceIndex = hevcSliceState->dwSliceIndex; 957 sliceInfoParam.dwTotalBytesConsumed = 0; 958 sliceInfoParam.bLastPass = hevcSliceState->bLastSlice; 959 sliceInfoParam.dwDataStartOffset[0] = hevcSliceState->pHevcSliceParams->slice_data_offset + hevcSliceState->dwOffset; 960 sliceInfoParam.dwDataStartOffset[1] = hevcSliceState->pHevcSliceParams->slice_data_offset + hevcSliceState->dwOffset; 961 sliceInfoParam.dwDataLength[0] = hevcSliceState->pHevcSliceParams->slice_data_size; 962 sliceInfoParam.dwDataLength[1] = hevcSliceState->pHevcSliceParams->slice_data_size; 963 964 MHW_MI_CHK_STATUS(m_cpInterface->SetHcpProtectionState( 965 true, 966 cmdBuffer, 967 nullptr, 968 &sliceInfoParam)); 969 970 return eStatus; 971 } 972 }; 973 974 #endif 975