1 /* 2 * Copyright (c) 2020-2022, 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 encode_preenc_packet.cpp 24 //! \brief Defines the interface for preenc packet 25 //! 26 27 #include "encode_preenc_packet.h" 28 #include "encode_status_report_defs.h" 29 #include "media_perf_profiler.h" 30 #include "encode_utils.h" 31 #include "encode_status_report_defs.h" 32 #include "mos_solo_generic.h" 33 #include "encode_status_report_defs.h" 34 #include "codec_hw_next.h" 35 36 using namespace mhw::vdbox; 37 38 namespace encode 39 { Init()40 MOS_STATUS EncodePreEncPacket::Init() 41 { 42 ENCODE_FUNC_CALL(); 43 ENCODE_CHK_NULL_RETURN(m_statusReport); 44 45 ENCODE_CHK_STATUS_RETURN(CmdPacket::Init()); 46 m_basicFeature = dynamic_cast<PreEncBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::preEncFeature)); 47 ENCODE_CHK_NULL_RETURN(m_basicFeature); 48 ENCODE_CHK_STATUS_RETURN(m_basicFeature->GetEncodeMode(m_encodeMode)); 49 50 #ifdef _MMC_SUPPORTED 51 m_mmcState = m_pipeline->GetMmcState(); 52 ENCODE_CHK_NULL_RETURN(m_mmcState); 53 m_basicFeature->m_mmcState = m_mmcState; 54 #endif 55 56 m_allocator = m_pipeline->GetEncodeAllocator(); 57 ENCODE_CHK_STATUS_RETURN(AllocateResources()); 58 59 if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC) 60 { 61 ENCODE_CHK_STATUS_RETURN(m_statusReport->RegistObserver(this)); 62 } 63 64 CalculatePictureStateCommandSize(); 65 66 uint32_t vdencPictureStatesSize = 0, vdencPicturePatchListSize = 0; 67 GetVdencStateCommandsDataSize(vdencPictureStatesSize, vdencPicturePatchListSize); 68 m_defaultPictureStatesSize += vdencPictureStatesSize; 69 m_defaultPicturePatchListSize += vdencPicturePatchListSize; 70 71 GetHxxPrimitiveCommandSize(); 72 73 m_usePatchList = m_osInterface->bUsesPatchList; 74 75 return MOS_STATUS_SUCCESS; 76 } 77 Prepare()78 MOS_STATUS EncodePreEncPacket::Prepare() 79 { 80 ENCODE_FUNC_CALL(); 81 82 m_pictureStatesSize = m_defaultPictureStatesSize; 83 m_picturePatchListSize = m_defaultPicturePatchListSize; 84 m_sliceStatesSize = m_defaultSliceStatesSize; 85 m_slicePatchListSize = m_defaultSlicePatchListSize; 86 87 MediaPipeline *pipeline = dynamic_cast<MediaPipeline *>(m_pipeline); 88 ENCODE_CHK_NULL_RETURN(pipeline); 89 90 m_hevcIqMatrixParams = &(m_basicFeature->m_hevcIqMatrixParams); 91 m_nalUnitParams = m_basicFeature->m_nalUnitParams; 92 93 return MOS_STATUS_SUCCESS; 94 } 95 Destroy()96 MOS_STATUS EncodePreEncPacket::Destroy() 97 { 98 if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC) 99 { 100 m_statusReport->UnregistObserver(this); 101 } 102 return MOS_STATUS_SUCCESS; 103 } 104 AllocateResources()105 MOS_STATUS EncodePreEncPacket::AllocateResources() 106 { 107 ENCODE_FUNC_CALL(); 108 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 109 ENCODE_CHK_NULL_RETURN(m_allocator); 110 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 111 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 112 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 113 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 114 allocParamsForBufferLinear.Format = Format_Buffer; 115 116 allocParamsForBufferLinear.dwBytes = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameWidth, m_basicFeature->m_maxLCUSize) * CODECHAL_CACHELINE_SIZE * 2 * 2; 117 allocParamsForBufferLinear.pBufName = "vdencIntraRowStoreScratch"; 118 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ; 119 m_vdencIntraRowStoreScratch = m_allocator->AllocateResource(allocParamsForBufferLinear, false); 120 121 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 122 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 123 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 124 allocParamsForBufferLinear.Format = Format_Buffer; 125 126 // VDENC tile row store buffer 127 allocParamsForBufferLinear.dwBytes = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameWidth, 32) * CODECHAL_CACHELINE_SIZE * 2; 128 allocParamsForBufferLinear.pBufName = "VDENC Tile Row Store Buffer"; 129 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ; 130 m_vdencTileRowStoreBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, false); 131 132 hcp::HcpBufferSizePar hcpBufSizePar; 133 MOS_ZeroMemory(&hcpBufSizePar, sizeof(hcpBufSizePar)); 134 135 hcpBufSizePar.ucMaxBitDepth = m_basicFeature->m_bitDepth; 136 hcpBufSizePar.ucChromaFormat = m_basicFeature->m_chromaFormat; 137 // We should move the buffer allocation to picture level if the size is dependent on LCU size 138 hcpBufSizePar.dwCtbLog2SizeY = 6; //assume Max LCU size 139 hcpBufSizePar.dwPicWidth = MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, m_basicFeature->m_maxLCUSize); 140 hcpBufSizePar.dwPicHeight = MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, m_basicFeature->m_maxLCUSize); 141 142 auto AllocateHcpBuffer = [&](PMOS_RESOURCE &res, const hcp::HCP_INTERNAL_BUFFER_TYPE bufferType, const char *bufferName) { 143 uint32_t bufSize = 0; 144 hcpBufSizePar.bufferType = bufferType; 145 eStatus = m_hcpItf->GetHcpBufSize(hcpBufSizePar, bufSize); 146 if (eStatus != MOS_STATUS_SUCCESS) 147 { 148 ENCODE_ASSERTMESSAGE("Failed to get hcp buffer size."); 149 return eStatus; 150 } 151 allocParamsForBufferLinear.dwBytes = bufSize; 152 allocParamsForBufferLinear.pBufName = bufferName; 153 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ; 154 res = m_allocator->AllocateResource(allocParamsForBufferLinear, false); 155 return MOS_STATUS_SUCCESS; 156 }; 157 158 // Metadata Line buffer 159 ENCODE_CHK_STATUS_RETURN(AllocateHcpBuffer(m_resMetadataLineBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::META_LINE, "MetadataLineBuffer")); 160 // Metadata Tile Line buffer 161 ENCODE_CHK_STATUS_RETURN(AllocateHcpBuffer(m_resMetadataTileLineBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::META_TILE_LINE, "MetadataTileLineBuffer")); 162 // Metadata Tile Column buffer 163 ENCODE_CHK_STATUS_RETURN(AllocateHcpBuffer(m_resMetadataTileColumnBuffer, hcp::HCP_INTERNAL_BUFFER_TYPE::META_TILE_COL, "MetadataTileColumnBuffer")); 164 165 return eStatus; 166 } 167 SetPerfTag(uint16_t type,uint16_t mode,uint16_t picCodingType)168 void EncodePreEncPacket::SetPerfTag(uint16_t type, uint16_t mode, uint16_t picCodingType) 169 { 170 ENCODE_FUNC_CALL(); 171 172 PerfTagSetting perfTag = {}; 173 perfTag.Value = 0; 174 perfTag.Mode = mode & CODECHAL_ENCODE_MODE_BIT_MASK; 175 perfTag.CallType = type; 176 perfTag.PictureCodingType = picCodingType > 3 ? 0 : picCodingType; 177 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); 178 m_osInterface->pfnIncPerfBufferID(m_osInterface); 179 } 180 SendPrologCmds(MOS_COMMAND_BUFFER & cmdBuffer)181 MOS_STATUS EncodePreEncPacket::SendPrologCmds( 182 MOS_COMMAND_BUFFER &cmdBuffer) 183 { 184 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 185 186 ENCODE_FUNC_CALL(); 187 188 #ifdef _MMC_SUPPORTED 189 ENCODE_CHK_NULL_RETURN(m_mmcState); 190 ENCODE_CHK_STATUS_RETURN(m_mmcState->SendPrologCmd(&cmdBuffer, false)); 191 #endif 192 193 MHW_GENERIC_PROLOG_PARAMS genericPrologParams; 194 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams)); 195 genericPrologParams.pOsInterface = m_osInterface; 196 genericPrologParams.pvMiInterface = nullptr; 197 genericPrologParams.bMmcEnabled = m_mmcState ? m_mmcState->IsMmcEnabled() : false; 198 ENCODE_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf)); 199 200 return eStatus; 201 } 202 AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)203 MOS_STATUS EncodePreEncPacket::AddForceWakeup(MOS_COMMAND_BUFFER &cmdBuffer) 204 { 205 ENCODE_FUNC_CALL(); 206 207 auto &forceWakeupParams = m_miItf->MHW_GETPAR_F(MI_FORCE_WAKEUP)(); 208 forceWakeupParams = {}; 209 forceWakeupParams.bMFXPowerWellControl = true; 210 forceWakeupParams.bMFXPowerWellControlMask = true; 211 forceWakeupParams.bHEVCPowerWellControl = true; 212 forceWakeupParams.bHEVCPowerWellControlMask = true; 213 214 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FORCE_WAKEUP)(&cmdBuffer)); 215 216 return MOS_STATUS_SUCCESS; 217 } 218 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT,EncodePreEncPacket)219 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT, EncodePreEncPacket) 220 { 221 ENCODE_FUNC_CALL(); 222 223 params.codecStandardSelect = CODECHAL_HEVC - CODECHAL_HCP_BASE; 224 params.bStreamOutEnabled = false; 225 params.bVdencEnabled = true; 226 params.codecSelect = 1; 227 228 params.multiEngineMode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_FE_LEGACY; 229 params.pipeWorkMode = MHW_VDBOX_HCP_PIPE_WORK_MODE_LEGACY; 230 231 params.bTileBasedReplayMode = 0; 232 233 return MOS_STATUS_SUCCESS; 234 } 235 AddHcpSurfaceStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const236 MOS_STATUS EncodePreEncPacket::AddHcpSurfaceStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const 237 { 238 ENCODE_FUNC_CALL(); 239 ENCODE_CHK_NULL_RETURN(cmdBuffer); 240 241 m_curHcpSurfStateId = CODECHAL_HCP_SRC_SURFACE_ID; 242 SETPAR_AND_ADDCMD(HCP_SURFACE_STATE, m_hcpItf, cmdBuffer); 243 244 m_curHcpSurfStateId = CODECHAL_HCP_DECODED_SURFACE_ID; 245 SETPAR_AND_ADDCMD(HCP_SURFACE_STATE, m_hcpItf, cmdBuffer); 246 247 m_curHcpSurfStateId = CODECHAL_HCP_REF_SURFACE_ID; 248 SETPAR_AND_ADDCMD(HCP_SURFACE_STATE, m_hcpItf, cmdBuffer); 249 250 return MOS_STATUS_SUCCESS; 251 } 252 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE,EncodePreEncPacket)253 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE, EncodePreEncPacket) 254 { 255 ENCODE_FUNC_CALL(); 256 257 params.Mode = m_basicFeature->m_mode; 258 params.psPreDeblockSurface = &m_basicFeature->m_reconSurface; 259 params.psPostDeblockSurface = &m_basicFeature->m_reconSurface; 260 params.psRawSurface = m_basicFeature->m_preEncRawSurface; 261 262 params.presMetadataLineBuffer = m_resMetadataLineBuffer; 263 params.presMetadataTileLineBuffer = m_resMetadataTileLineBuffer; 264 params.presMetadataTileColumnBuffer = m_resMetadataTileColumnBuffer; 265 266 params.bRawIs10Bit = m_basicFeature->m_is10Bit; 267 268 return MOS_STATUS_SUCCESS; 269 } 270 MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE,EncodePreEncPacket)271 MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE, EncodePreEncPacket) 272 { 273 ENCODE_FUNC_CALL(); 274 275 params.presMvObjectBuffer = m_basicFeature->m_resMbCodeBuffer; 276 params.dwMvObjectOffset = 0; 277 params.dwMvObjectSize = m_basicFeature->m_mbCodeSize; 278 params.presPakBaseObjectBuffer = &m_basicFeature->m_resBitstreamBuffer; 279 params.dwPakBaseObjectSize = m_basicFeature->m_bitstreamSize; 280 281 return MOS_STATUS_SUCCESS; 282 } 283 StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)284 MOS_STATUS EncodePreEncPacket::StartStatusReport( 285 uint32_t srType, 286 MOS_COMMAND_BUFFER *cmdBuffer) 287 { 288 ENCODE_FUNC_CALL(); 289 ENCODE_CHK_NULL_RETURN(cmdBuffer); 290 291 if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC) 292 { 293 ENCODE_CHK_STATUS_RETURN(MediaPacket::StartStatusReportNext(srType, cmdBuffer)); 294 } 295 296 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance(); 297 ENCODE_CHK_NULL_RETURN(perfProfiler); 298 ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectStartCmd( 299 (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer)); 300 301 return MOS_STATUS_SUCCESS; 302 } 303 EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)304 MOS_STATUS EncodePreEncPacket::EndStatusReport( 305 uint32_t srType, 306 MOS_COMMAND_BUFFER *cmdBuffer) 307 { 308 ENCODE_FUNC_CALL(); 309 ENCODE_CHK_NULL_RETURN(cmdBuffer); 310 311 if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC) 312 { 313 ENCODE_CHK_STATUS_RETURN(MediaPacket::EndStatusReportNext(srType, cmdBuffer)); 314 } 315 316 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance(); 317 ENCODE_CHK_NULL_RETURN(perfProfiler); 318 ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectEndCmd( 319 (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer)); 320 321 return MOS_STATUS_SUCCESS; 322 } 323 ReadHcpStatus(MHW_VDBOX_NODE_IND vdboxIndex,MediaStatusReport * statusReport,MOS_COMMAND_BUFFER & cmdBuffer)324 MOS_STATUS EncodePreEncPacket::ReadHcpStatus( 325 MHW_VDBOX_NODE_IND vdboxIndex, 326 MediaStatusReport * statusReport, 327 MOS_COMMAND_BUFFER &cmdBuffer) 328 { 329 ENCODE_FUNC_CALL(); 330 331 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 332 333 CODEC_HW_FUNCTION_ENTER; 334 335 ENCODE_CHK_NULL_RETURN(statusReport); 336 ENCODE_CHK_NULL_RETURN(m_hwInterface); 337 338 MOS_RESOURCE *osResource = nullptr; 339 uint32_t offset = 0; 340 341 EncodeStatusReadParams params; 342 MOS_ZeroMemory(¶ms, sizeof(params)); 343 344 ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportMfxBitstreamByteCountPerFrame, osResource, offset)); 345 params.resBitstreamByteCountPerFrame = osResource; 346 params.bitstreamByteCountPerFrameOffset = offset; 347 348 ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportMfxBitstreamSyntaxElementOnlyBitCount, osResource, offset)); 349 params.resBitstreamSyntaxElementOnlyBitCount = osResource; 350 params.bitstreamSyntaxElementOnlyBitCountOffset = offset; 351 352 ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportQPStatusCount, osResource, offset)); 353 params.resQpStatusCount = osResource; 354 params.qpStatusCountOffset = offset; 355 356 ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportImageStatusMask, osResource, offset)); 357 params.resImageStatusMask = osResource; 358 params.imageStatusMaskOffset = offset; 359 360 ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportImageStatusCtrl, osResource, offset)); 361 params.resImageStatusCtrl = osResource; 362 params.imageStatusCtrlOffset = offset; 363 364 ENCODE_CHK_STATUS_RETURN(statusReport->GetAddress(encode::statusReportNumSlices, osResource, offset)); 365 params.resNumSlices = osResource; 366 params.numSlicesOffset = offset; 367 368 ENCODE_CHK_STATUS_RETURN(m_hwInterface->ReadHcpStatus(vdboxIndex, params, &cmdBuffer)); 369 370 ENCODE_CHK_STATUS_RETURN(m_hwInterface->ReadImageStatusForHcp(vdboxIndex, params, &cmdBuffer)); 371 return eStatus; 372 } 373 Completed(void * mfxStatus,void * rcsStatus,void * statusReport)374 MOS_STATUS EncodePreEncPacket::Completed(void *mfxStatus, void *rcsStatus, void *statusReport) 375 { 376 ENCODE_FUNC_CALL(); 377 378 ENCODE_CHK_NULL_RETURN(statusReport); 379 ENCODE_CHK_NULL_RETURN(m_basicFeature); 380 381 EncodeStatusReportData *statusReportData = (EncodeStatusReportData *)statusReport; 382 #if USE_CODECHAL_DEBUG_TOOL 383 auto preencFeature = dynamic_cast<PreEncBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::preEncFeature)); 384 ENCODE_CHK_NULL_RETURN(preencFeature); 385 preencFeature->EncodePreencBasicFuntion1(); 386 #endif 387 388 m_basicFeature->Reset((CODEC_REF_LIST *)statusReportData->currRefList); 389 return MOS_STATUS_SUCCESS; 390 } 391 GetVdencStateCommandsDataSize(uint32_t & vdencPictureStatesSize,uint32_t & vdencPicturePatchListSize)392 MOS_STATUS EncodePreEncPacket::GetVdencStateCommandsDataSize(uint32_t &vdencPictureStatesSize, uint32_t &vdencPicturePatchListSize) 393 { 394 vdencPictureStatesSize = 395 m_vdencItf->MHW_GETSIZE_F(VDENC_PIPE_MODE_SELECT)() + 396 m_vdencItf->MHW_GETSIZE_F(VDENC_SRC_SURFACE_STATE)() + 397 m_vdencItf->MHW_GETSIZE_F(VDENC_REF_SURFACE_STATE)() + 398 m_vdencItf->MHW_GETSIZE_F(VDENC_DS_REF_SURFACE_STATE)() + 399 m_vdencItf->MHW_GETSIZE_F(VDENC_PIPE_BUF_ADDR_STATE)() + 400 m_vdencItf->MHW_GETSIZE_F(VDENC_WEIGHTSOFFSETS_STATE)() + 401 m_vdencItf->MHW_GETSIZE_F(VDENC_WALKER_STATE)() + 402 m_vdencItf->MHW_GETSIZE_F(VD_PIPELINE_FLUSH)() + 403 m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_IMM)()*8 + 404 m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() + 405 m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)() + 406 m_hcpItf->MHW_GETSIZE_F(HEVC_VP9_RDOQ_STATE)() + 407 m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)(); 408 409 vdencPicturePatchListSize = PATCH_LIST_COMMAND(mhw::vdbox::vdenc::Itf::VDENC_PIPE_BUF_ADDR_STATE_CMD); 410 411 return MOS_STATUS_SUCCESS; 412 } 413 GetHxxPrimitiveCommandSize()414 MOS_STATUS EncodePreEncPacket::GetHxxPrimitiveCommandSize() 415 { 416 uint32_t hcpCommandsSize = 0; 417 uint32_t hcpPatchListSize = 0; 418 hcpCommandsSize = 419 m_hcpItf->MHW_GETSIZE_F(HCP_REF_IDX_STATE)() * 2 + 420 m_hcpItf->MHW_GETSIZE_F(HCP_WEIGHTOFFSET_STATE)() * 2 + 421 m_hcpItf->MHW_GETSIZE_F(HCP_SLICE_STATE)() + 422 m_hcpItf->MHW_GETSIZE_F(HCP_PAK_INSERT_OBJECT)() + 423 m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_START)() * 2 + 424 m_hcpItf->MHW_GETSIZE_F(HCP_TILE_CODING)(); // one slice cannot be with more than one tile 425 426 hcpPatchListSize = 427 mhw::vdbox::hcp::Itf::HCP_REF_IDX_STATE_CMD_NUMBER_OF_ADDRESSES * 2 + 428 mhw::vdbox::hcp::Itf::HCP_WEIGHTOFFSET_STATE_CMD_NUMBER_OF_ADDRESSES * 2 + 429 mhw::vdbox::hcp::Itf::HCP_SLICE_STATE_CMD_NUMBER_OF_ADDRESSES + 430 mhw::vdbox::hcp::Itf::HCP_PAK_INSERT_OBJECT_CMD_NUMBER_OF_ADDRESSES + 431 mhw::vdbox::hcp::Itf::MI_BATCH_BUFFER_START_CMD_NUMBER_OF_ADDRESSES * 2 + // One is for the PAK command and another one is for the BB when BRC and single task mode are on 432 mhw::vdbox::hcp::Itf::HCP_TILE_CODING_COMMAND_NUMBER_OF_ADDRESSES; // HCP_TILE_CODING_STATE command 433 434 uint32_t cpCmdsize = 0; 435 uint32_t cpPatchListSize = 0; 436 if (m_hwInterface->GetCpInterface()) 437 { 438 m_hwInterface->GetCpInterface()->GetCpSliceLevelCmdSize(cpCmdsize, cpPatchListSize); 439 } 440 441 m_defaultSliceStatesSize = hcpCommandsSize + (uint32_t)cpCmdsize; 442 m_defaultSlicePatchListSize = hcpPatchListSize + (uint32_t)cpPatchListSize; 443 return MOS_STATUS_SUCCESS; 444 } 445 CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)446 MOS_STATUS EncodePreEncPacket::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize) 447 { 448 m_pictureStatesSize = m_defaultPictureStatesSize; 449 m_picturePatchListSize = m_defaultPicturePatchListSize; 450 m_sliceStatesSize = m_defaultSliceStatesSize; 451 m_slicePatchListSize = m_defaultSlicePatchListSize; 452 453 commandBufferSize = CalculateCommandBufferSize(); 454 requestedPatchListSize = CalculatePatchListSize(); 455 return MOS_STATUS_SUCCESS; 456 } 457 CalculateCommandBufferSize()458 uint32_t EncodePreEncPacket::CalculateCommandBufferSize() 459 { 460 ENCODE_FUNC_CALL(); 461 uint32_t commandBufferSize = 0; 462 463 commandBufferSize = m_pictureStatesSize + m_sliceStatesSize; 464 465 if (m_pipeline->IsSingleTaskPhaseSupported()) 466 { 467 commandBufferSize *= m_pipeline->GetPassNum(); 468 } 469 470 // 4K align since allocation is in chunks of 4K bytes. 471 commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE); 472 473 return commandBufferSize; 474 } 475 CalculatePatchListSize()476 uint32_t EncodePreEncPacket::CalculatePatchListSize() 477 { 478 ENCODE_FUNC_CALL(); 479 uint32_t requestedPatchListSize = 0; 480 if (m_usePatchList) 481 { 482 requestedPatchListSize = m_picturePatchListSize + m_slicePatchListSize; 483 484 if (m_pipeline->IsSingleTaskPhaseSupported()) 485 { 486 requestedPatchListSize *= m_pipeline->GetPassNum(); 487 } 488 489 // Multi pipes are sharing one patchlist 490 requestedPatchListSize *= m_pipeline->GetPipeNum(); 491 } 492 return requestedPatchListSize; 493 } 494 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,EncodePreEncPacket)495 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, EncodePreEncPacket) 496 { 497 //params.tlbPrefetch = true; 498 499 // can be enabled by reg key (disabled by default) 500 params.pakObjCmdStreamOut = false; 501 502 if (!MEDIA_IS_WA(m_osInterface->pfnGetWaTable(m_osInterface), WaEnableOnlyASteppingFeatures)) 503 { 504 params.VdencPipeModeSelectPar0 = 1; 505 } 506 507 params.rgbEncodingMode = false; 508 509 return MOS_STATUS_SUCCESS; 510 } 511 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,EncodePreEncPacket)512 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, EncodePreEncPacket) 513 { 514 params.intraRowStoreScratchBuffer = m_vdencIntraRowStoreScratch; 515 params.tileRowStoreBuffer = m_vdencTileRowStoreBuffer; 516 517 return MOS_STATUS_SUCCESS; 518 } 519 MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH,EncodePreEncPacket)520 MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH, EncodePreEncPacket) 521 { 522 switch (m_flushCmd) 523 { 524 case waitHevc: 525 params.waitDoneHEVC = true; 526 params.flushHEVC = true; 527 params.waitDoneVDCmdMsgParser = true; 528 break; 529 case waitVdenc: 530 params.waitDoneMFX = true; 531 params.waitDoneVDENC = true; 532 params.flushVDENC = true; 533 params.waitDoneVDCmdMsgParser = true; 534 break; 535 case waitHevcVdenc: 536 params.waitDoneMFX = true; 537 params.waitDoneVDENC = true; 538 params.flushVDENC = true; 539 params.flushHEVC = true; 540 params.waitDoneVDCmdMsgParser = true; 541 break; 542 } 543 544 return MOS_STATUS_SUCCESS; 545 } 546 547 #if USE_CODECHAL_DEBUG_TOOL DumpResources(EncodeStatusMfx * encodeStatusMfx,EncodeStatusReportData * statusReportData)548 MOS_STATUS EncodePreEncPacket::DumpResources( 549 EncodeStatusMfx * encodeStatusMfx, 550 EncodeStatusReportData *statusReportData) 551 { 552 ENCODE_FUNC_CALL(); 553 ENCODE_CHK_NULL_RETURN(encodeStatusMfx); 554 ENCODE_CHK_NULL_RETURN(statusReportData); 555 ENCODE_CHK_NULL_RETURN(m_pipeline); 556 ENCODE_CHK_NULL_RETURN(m_statusReport); 557 ENCODE_CHK_NULL_RETURN(m_basicFeature); 558 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_trackedBuf); 559 560 CodechalDebugInterface *debugInterface = m_pipeline->GetStatusReportDebugInterface(); 561 ENCODE_CHK_NULL_RETURN(debugInterface); 562 563 CODEC_REF_LIST currRefList = *((CODEC_REF_LIST *)statusReportData->currRefList); 564 currRefList.RefPic = statusReportData->currOriginalPic; 565 566 debugInterface->m_currPic = statusReportData->currOriginalPic; 567 debugInterface->m_bufferDumpFrameNum = m_statusReport->GetReportedCount(); 568 debugInterface->m_frameType = encodeStatusMfx->pictureCodingType; 569 570 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer( 571 &currRefList.resBitstreamBuffer, 572 CodechalDbgAttr::attrBitstream, 573 "_PAK", 574 statusReportData->bitstreamSize, 575 0, 576 CODECHAL_NUM_MEDIA_STATES)); 577 578 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpData( 579 statusReportData, 580 sizeof(EncodeStatusReportData), 581 CodechalDbgAttr::attrStatusReport, 582 "EncodeStatusReport_Buffer")); 583 584 MOS_SURFACE *ds4xSurface = m_basicFeature->m_trackedBuf->GetSurface( 585 BufferType::ds4xSurface, currRefList.ucScalingIdx); 586 587 if (ds4xSurface != nullptr) 588 { 589 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface( 590 ds4xSurface, 591 CodechalDbgAttr::attrReconstructedSurface, 592 "4xScaledSurf")) 593 } 594 595 MOS_SURFACE *ds8xSurface = m_basicFeature->m_trackedBuf->GetSurface( 596 BufferType::ds8xSurface, currRefList.ucScalingIdx); 597 598 if (ds8xSurface != nullptr) 599 { 600 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface( 601 ds8xSurface, 602 CodechalDbgAttr::attrReconstructedSurface, 603 "8xScaledSurf")) 604 } 605 606 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface( 607 &currRefList.sRefReconBuffer, 608 CodechalDbgAttr::attrReconstructedSurface, 609 "ReconSurf")) 610 611 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface( 612 &currRefList.sRefRawBuffer, 613 CodechalDbgAttr::attrEncodeRawInputSurface, 614 "SrcSurf")) 615 616 return MOS_STATUS_SUCCESS; 617 } 618 619 #endif 620 SubmitPictureLevel(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)621 MOS_STATUS EncodePreEncPacket::SubmitPictureLevel( 622 MOS_COMMAND_BUFFER *commandBuffer, 623 uint8_t packetPhase) 624 { 625 ENCODE_FUNC_CALL(); 626 627 MOS_COMMAND_BUFFER &cmdBuffer = *commandBuffer; 628 ENCODE_CHK_STATUS_RETURN(Mos_Solo_PreProcessEncode(m_osInterface, &m_basicFeature->m_resBitstreamBuffer, &m_basicFeature->m_reconSurface)); 629 630 MOS_SYNC_PARAMS syncParams; 631 syncParams = g_cInitSyncParams; 632 syncParams.GpuContext = m_osInterface->pfnGetGpuContext(m_osInterface); 633 syncParams.presSyncResource = &m_basicFeature->m_preEncRawSurface->OsResource; 634 syncParams.bReadOnly = true; 635 ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams)); 636 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams); 637 638 ENCODE_CHK_STATUS_RETURN(PatchPictureLevelCommands(packetPhase, cmdBuffer)); 639 640 return MOS_STATUS_SUCCESS; 641 } 642 Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)643 MOS_STATUS EncodePreEncPacket::Submit( 644 MOS_COMMAND_BUFFER *commandBuffer, 645 uint8_t packetPhase) 646 { 647 ENCODE_FUNC_CALL(); 648 649 ENCODE_CHK_STATUS_RETURN(PrepareRawSurface()); 650 651 ENCODE_CHK_STATUS_RETURN(SubmitPictureLevel(commandBuffer, packetPhase)); 652 653 MOS_COMMAND_BUFFER &cmdBuffer = *commandBuffer; 654 655 ENCODE_CHK_STATUS_RETURN(PatchSliceLevelCommands(cmdBuffer, packetPhase)); 656 657 ENCODE_CHK_STATUS_RETURN(Mos_Solo_PostProcessEncode(m_osInterface, &m_basicFeature->m_resBitstreamBuffer, &m_basicFeature->m_reconSurface)); 658 659 m_enablePreEncStatusReport = true; 660 661 return MOS_STATUS_SUCCESS; 662 } 663 PrepareRawSurface()664 MOS_STATUS EncodePreEncPacket::PrepareRawSurface() 665 { 666 ENCODE_FUNC_CALL(); 667 668 if (m_basicFeature->m_rawDsSurface != nullptr) 669 { 670 ENCODE_CHK_STATUS_RETURN(RawSurfaceDownScaling(&m_basicFeature->m_rawSurface, m_basicFeature->m_rawDsSurface)); 671 m_basicFeature->m_preEncRawSurface = m_basicFeature->m_rawDsSurface; 672 } 673 else 674 { 675 m_basicFeature->m_preEncRawSurface = &m_basicFeature->m_rawSurface; 676 } 677 678 return MOS_STATUS_SUCCESS; 679 } 680 RawSurfaceDownScaling(const PMOS_SURFACE inSurf,PMOS_SURFACE outSurf)681 MOS_STATUS EncodePreEncPacket::RawSurfaceDownScaling(const PMOS_SURFACE inSurf, PMOS_SURFACE outSurf) 682 { 683 ENCODE_FUNC_CALL(); 684 685 if (outSurf == nullptr) 686 { 687 return MOS_STATUS_SUCCESS; 688 } 689 690 VEBOX_SFC_PARAMS params = {}; 691 692 params.input.surface = inSurf; 693 params.input.colorSpace = CSpace_Any; 694 params.input.chromaSiting = 0; 695 params.input.rcSrc = {0, 0, (long)inSurf->dwWidth, (long)inSurf->dwHeight}; 696 params.input.rotation = ROTATION_IDENTITY; 697 698 params.output.surface = outSurf; 699 params.output.colorSpace = CSpace_Any; 700 params.output.chromaSiting = 0; 701 params.output.rcDst = {0, 0, (long)outSurf->dwWidth, (long)outSurf->dwHeight}; 702 703 ENCODE_CHK_STATUS_RETURN(m_sfcItf->Render(params)); 704 705 m_pipeline->ContextSwitchBack(); 706 707 return MOS_STATUS_SUCCESS; 708 } 709 PatchPictureLevelCommands(const uint8_t & packetPhase,MOS_COMMAND_BUFFER & cmdBuffer)710 MOS_STATUS EncodePreEncPacket::PatchPictureLevelCommands(const uint8_t &packetPhase, MOS_COMMAND_BUFFER &cmdBuffer) 711 { 712 ENCODE_FUNC_CALL(); 713 714 ENCODE_CHK_STATUS_RETURN(m_miItf->SetWatchdogTimerThreshold(m_basicFeature->m_frameWidth, m_basicFeature->m_frameHeight, true)); 715 716 SetPerfTag(CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE, (uint16_t)m_basicFeature->m_mode, m_basicFeature->GetPictureCodingType()); 717 718 bool firstTaskInPhase = packetPhase & firstPacket; 719 if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase) 720 { 721 ENCODE_CHK_STATUS_RETURN(AddForceWakeup(cmdBuffer)); 722 723 // Send command buffer header at the beginning (OS dependent) 724 ENCODE_CHK_STATUS_RETURN(SendPrologCmds(cmdBuffer)); 725 } 726 727 ENCODE_CHK_STATUS_RETURN(StartStatusReport(statusReportMfx, &cmdBuffer)); 728 729 ENCODE_CHK_STATUS_RETURN(AddPictureHcpCommands(cmdBuffer)); 730 731 ENCODE_CHK_STATUS_RETURN(AddPictureVdencCommands(cmdBuffer)); 732 733 ENCODE_CHK_STATUS_RETURN(AddPicStateWithNoTile(cmdBuffer)); 734 735 return MOS_STATUS_SUCCESS; 736 } 737 PatchSliceLevelCommands(MOS_COMMAND_BUFFER & cmdBuffer,uint8_t packetPhase)738 MOS_STATUS EncodePreEncPacket::PatchSliceLevelCommands(MOS_COMMAND_BUFFER &cmdBuffer, uint8_t packetPhase) 739 { 740 ENCODE_FUNC_CALL(); 741 742 ENCODE_CHK_STATUS_RETURN(SendHwSliceEncodeCommand(cmdBuffer)); 743 744 m_flushCmd = waitVdenc; 745 SETPAR_AND_ADDCMD(VD_PIPELINE_FLUSH, m_vdencItf, &cmdBuffer); 746 747 ENCODE_CHK_STATUS_RETURN(EnsureAllCommandsExecuted(cmdBuffer)); 748 749 m_flushCmd = waitHevc; 750 SETPAR_AND_ADDCMD(VD_PIPELINE_FLUSH, m_vdencItf, &cmdBuffer); 751 752 ENCODE_CHK_STATUS_RETURN(EnsureAllCommandsExecuted(cmdBuffer)); 753 754 if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC) 755 { 756 ENCODE_CHK_STATUS_RETURN(ReadHcpStatus(MHW_VDBOX_NODE_1, m_statusReport, cmdBuffer)); 757 } 758 759 ENCODE_CHK_STATUS_RETURN(EndStatusReport(statusReportMfx, &cmdBuffer)); 760 761 if (m_encodeMode == MediaEncodeMode::MANUAL_RES_PRE_ENC || m_encodeMode == MediaEncodeMode::AUTO_RES_PRE_ENC) 762 { 763 ENCODE_CHK_STATUS_RETURN(MediaPacket::UpdateStatusReportNext(statusReportGlobalCount, &cmdBuffer)); 764 } 765 766 return MOS_STATUS_SUCCESS; 767 } 768 AddPicStateWithNoTile(MOS_COMMAND_BUFFER & cmdBuffer)769 MOS_STATUS EncodePreEncPacket::AddPicStateWithNoTile( 770 MOS_COMMAND_BUFFER &cmdBuffer) 771 { 772 ENCODE_FUNC_CALL(); 773 774 SETPAR_AND_ADDCMD(VDENC_CMD1, m_vdencItf, &cmdBuffer); 775 776 SETPAR_AND_ADDCMD(HCP_PIC_STATE, m_hcpItf, &cmdBuffer); 777 778 SETPAR_AND_ADDCMD(VDENC_CMD2, m_vdencItf, &cmdBuffer); 779 780 // Send HEVC_VP9_RDOQ_STATE command 781 SETPAR_AND_ADDCMD(HEVC_VP9_RDOQ_STATE, m_hcpItf, &cmdBuffer); 782 783 return MOS_STATUS_SUCCESS; 784 } 785 EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER & cmdBuffer)786 MOS_STATUS EncodePreEncPacket::EnsureAllCommandsExecuted(MOS_COMMAND_BUFFER &cmdBuffer) 787 { 788 ENCODE_FUNC_CALL(); 789 790 // Send MI_FLUSH command 791 auto &flushDwParams = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)(); 792 flushDwParams = {}; 793 flushDwParams.bVideoPipelineCacheInvalidate = true; 794 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer)); 795 796 return MOS_STATUS_SUCCESS; 797 } 798 AddPictureVdencCommands(MOS_COMMAND_BUFFER & cmdBuffer)799 MOS_STATUS EncodePreEncPacket::AddPictureVdencCommands(MOS_COMMAND_BUFFER &cmdBuffer) 800 { 801 ENCODE_FUNC_CALL(); 802 803 SETPAR_AND_ADDCMD(VDENC_PIPE_MODE_SELECT, m_vdencItf, &cmdBuffer); 804 SETPAR_AND_ADDCMD(VDENC_SRC_SURFACE_STATE, m_vdencItf, &cmdBuffer); 805 SETPAR_AND_ADDCMD(VDENC_REF_SURFACE_STATE, m_vdencItf, &cmdBuffer); 806 SETPAR_AND_ADDCMD(VDENC_DS_REF_SURFACE_STATE, m_vdencItf, &cmdBuffer); 807 SETPAR_AND_ADDCMD(VDENC_PIPE_BUF_ADDR_STATE, m_vdencItf, &cmdBuffer); 808 809 return MOS_STATUS_SUCCESS; 810 } 811 AddPictureHcpCommands(MOS_COMMAND_BUFFER & cmdBuffer)812 MOS_STATUS EncodePreEncPacket::AddPictureHcpCommands( 813 MOS_COMMAND_BUFFER &cmdBuffer) 814 { 815 ENCODE_FUNC_CALL(); 816 817 ENCODE_CHK_STATUS_RETURN(AddHcpPipeModeSelect(cmdBuffer)); 818 819 ENCODE_CHK_STATUS_RETURN(AddHcpSurfaceStateCmds(&cmdBuffer)); 820 821 SETPAR_AND_ADDCMD(HCP_PIPE_BUF_ADDR_STATE, m_hcpItf, &cmdBuffer); 822 823 SETPAR_AND_ADDCMD(HCP_IND_OBJ_BASE_ADDR_STATE, m_hcpItf, &cmdBuffer); 824 825 ENCODE_CHK_STATUS_RETURN(AddHcpFqmStateCmds(&cmdBuffer)); 826 ENCODE_CHK_STATUS_RETURN(AddHcpQMStateCmds(&cmdBuffer)); 827 828 return MOS_STATUS_SUCCESS; 829 } 830 AddHcpPipeModeSelect(MOS_COMMAND_BUFFER & cmdBuffer)831 MOS_STATUS EncodePreEncPacket::AddHcpPipeModeSelect( 832 MOS_COMMAND_BUFFER &cmdBuffer) 833 { 834 ENCODE_FUNC_CALL(); 835 836 SETPAR_AND_ADDCMD(VDENC_CONTROL_STATE, m_vdencItf, &cmdBuffer); 837 838 auto &vdControlStateParams = m_miItf->MHW_GETPAR_F(VD_CONTROL_STATE)(); 839 vdControlStateParams = {}; 840 vdControlStateParams.initialization = true; 841 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(VD_CONTROL_STATE)(&cmdBuffer)); 842 843 // for Gen11+, we need to add MFX wait for both KIN and VRT before and after HCP Pipemode select... 844 auto &mfxWaitParams = m_miItf->MHW_GETPAR_F(MFX_WAIT)(); 845 mfxWaitParams = {}; 846 mfxWaitParams.iStallVdboxPipeline = true; 847 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)); 848 849 SETPAR_AND_ADDCMD(HCP_PIPE_MODE_SELECT, m_hcpItf, &cmdBuffer); 850 851 mfxWaitParams = {}; 852 mfxWaitParams.iStallVdboxPipeline = true; 853 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer)); 854 855 return MOS_STATUS_SUCCESS; 856 } 857 CalculatePictureStateCommandSize()858 MOS_STATUS EncodePreEncPacket::CalculatePictureStateCommandSize() 859 { 860 ENCODE_FUNC_CALL(); 861 862 uint32_t hcpCommandsSize = 0; 863 uint32_t hcpPatchListSize = 0; 864 uint32_t cpCmdsize = 0; 865 uint32_t cpPatchListSize = 0; 866 uint32_t hucCommandsSize = 0; 867 uint32_t hucPatchListSize = 0; 868 869 MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams; 870 871 hcpCommandsSize = 872 m_vdencItf->MHW_GETSIZE_F(VD_PIPELINE_FLUSH)() + 873 m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() + 874 m_hcpItf->MHW_GETSIZE_F(HCP_PIPE_MODE_SELECT)() + 875 m_hcpItf->MHW_GETSIZE_F(HCP_SURFACE_STATE)() + 876 m_hcpItf->MHW_GETSIZE_F(HCP_PIPE_BUF_ADDR_STATE)() + 877 m_hcpItf->MHW_GETSIZE_F(HCP_IND_OBJ_BASE_ADDR_STATE)() + 878 m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_REG)() * 8; 879 880 hcpPatchListSize = 881 PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::VD_PIPELINE_FLUSH_CMD) + 882 PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_FLUSH_DW_CMD) + 883 PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_PIPE_MODE_SELECT_CMD) + 884 PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_SURFACE_STATE_CMD) + 885 PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_PIPE_BUF_ADDR_STATE_CMD) + 886 PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_IND_OBJ_BASE_ADDR_STATE_CMD); 887 888 // HCP_QM_STATE_CMD may be issued up to 20 times: 3x Colour Component plus 2x intra/inter plus 4x SizeID minus 4 for the 32x32 chroma components. 889 // HCP_FQP_STATE_CMD may be issued up to 8 times: 4 scaling list per intra and inter. 890 hcpCommandsSize += 891 2 * m_miItf->MHW_GETSIZE_F(VD_CONTROL_STATE)() + 892 m_hcpItf->MHW_GETSIZE_F(HCP_SURFACE_STATE)() + // encoder needs two surface state commands. One is for raw and another one is for recon surfaces. 893 20 * m_hcpItf->MHW_GETSIZE_F(HCP_QM_STATE)() + 894 8 * m_hcpItf->MHW_GETSIZE_F(HCP_FQM_STATE)() + 895 m_hcpItf->MHW_GETSIZE_F(HCP_PIC_STATE)() + 896 m_hcpItf->MHW_GETSIZE_F(HEVC_VP9_RDOQ_STATE)() + // RDOQ 897 2 * m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() + // Slice level commands 898 2 * m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() + // need for Status report, Mfc Status and 899 10 * m_miItf->MHW_GETSIZE_F(MI_STORE_REGISTER_MEM)() + // 8 for BRCStatistics and 2 for RC6 WAs 900 m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_MEM)() + // 1 for RC6 WA 901 2 * m_hcpItf->MHW_GETSIZE_F(HCP_PAK_INSERT_OBJECT)() + // Two PAK insert object commands are for headers before the slice header and the header for the end of stream 902 4 * m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() + // two (BRC+reference frame) for clean-up HW semaphore memory and another two for signal it 903 17 * m_miItf->MHW_GETSIZE_F(MI_SEMAPHORE_WAIT)() + // Use HW wait command for each reference and one wait for current semaphore object 904 m_miItf->MHW_GETSIZE_F(MI_SEMAPHORE_WAIT)() + // Use HW wait command for each BRC pass 905 +m_miItf->MHW_GETSIZE_F(MI_SEMAPHORE_WAIT)() // Use HW wait command for each VDBOX 906 + 2 * m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() // One is for reset and another one for set per VDBOX 907 + 8 * m_miItf->MHW_GETSIZE_F(MI_COPY_MEM_MEM)() // Need to copy SSE statistics/ Slice Size overflow into memory 908 ; 909 910 hcpPatchListSize += 911 20 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_QM_STATE_CMD) + 912 8 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_FQM_STATE_CMD) + 913 PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::HCP_PIC_STATE_CMD) + 914 PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_BATCH_BUFFER_START_CMD) + // When BRC is on, HCP_PIC_STATE_CMD command is in the BB 915 2 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD) + // Slice level commands 916 2 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_FLUSH_DW_CMD) + // need for Status report, Mfc Status and 917 11 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_STORE_REGISTER_MEM_CMD) + // 8 for BRCStatistics and 3 for RC6 WAs 918 22 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD) // Use HW wait commands plus its memory clean-up and signal (4+ 16 + 1 + 1) 919 + 8 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_BATCH_BUFFER_START_CMD) // At maximal, there are 8 batch buffers for 8 VDBOXes for VE. Each box has one BB. 920 + PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_FLUSH_DW_CMD) // Need one flush before copy command 921 + PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MFX_WAIT_CMD) // Need one wait after copy command 922 + 3 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_STORE_DATA_IMM_CMD) // one wait commands and two for reset and set semaphore memory 923 + 8 * PATCH_LIST_COMMAND(mhw::vdbox::hcp::Itf::MI_COPY_MEM_MEM_CMD) // Need to copy SSE statistics/ Slice Size overflow into memory 924 ; 925 926 auto cpInterface = m_hwInterface->GetCpInterface(); 927 cpInterface->GetCpStateLevelCmdSize(cpCmdsize, cpPatchListSize); 928 929 ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize( 930 m_basicFeature->m_mode, (uint32_t *)&hucCommandsSize, (uint32_t *)&hucPatchListSize, &stateCmdSizeParams)); 931 932 m_defaultPictureStatesSize = hcpCommandsSize + hucCommandsSize + (uint32_t)cpCmdsize; 933 m_defaultPicturePatchListSize = hcpPatchListSize + hucPatchListSize + (uint32_t)cpPatchListSize; 934 935 return MOS_STATUS_SUCCESS; 936 } 937 SendHwSliceEncodeCommand(MOS_COMMAND_BUFFER & cmdBuffer)938 MOS_STATUS EncodePreEncPacket::SendHwSliceEncodeCommand( 939 MOS_COMMAND_BUFFER &cmdBuffer) 940 { 941 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 942 943 ENCODE_FUNC_CALL(); 944 945 // VDENC does not use batch buffer for slice state 946 // add HCP_REF_IDX command 947 ENCODE_CHK_STATUS_RETURN(AddHcpRefIdxStateCmds(&cmdBuffer)); 948 949 // add HEVC Slice state commands 950 SETPAR_AND_ADDCMD(HCP_SLICE_STATE, m_hcpItf, &cmdBuffer); 951 952 // add HCP_PAK_INSERT_OBJECTS command 953 ENCODE_CHK_STATUS_RETURN(AddHcpPakInsertObjectCmds(&cmdBuffer)); 954 955 // Send VDENC_WEIGHT_OFFSETS_STATE command 956 SETPAR_AND_ADDCMD(VDENC_WEIGHTSOFFSETS_STATE, m_vdencItf, &cmdBuffer); 957 958 SETPAR_AND_ADDCMD(VDENC_HEVC_VP9_TILE_SLICE_STATE, m_vdencItf, &cmdBuffer); 959 960 // Send VDENC_WALKER_STATE command 961 SETPAR_AND_ADDCMD(VDENC_WALKER_STATE, m_vdencItf, &cmdBuffer); 962 963 return eStatus; 964 } 965 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,EncodePreEncPacket)966 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, EncodePreEncPacket) 967 { 968 969 params.numPipe = VDENC_PIPE_SINGLE_PIPE; 970 971 return MOS_STATUS_SUCCESS; 972 } 973 MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE,EncodePreEncPacket)974 MHW_SETPAR_DECL_SRC(HCP_SURFACE_STATE, EncodePreEncPacket) 975 { 976 params.surfaceStateId = m_curHcpSurfStateId; 977 978 return MOS_STATUS_SUCCESS; 979 } 980 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE,EncodePreEncPacket)981 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE, EncodePreEncPacket) 982 { 983 ENCODE_FUNC_CALL(); 984 985 params.intrareffetchdisable = false; 986 987 return MOS_STATUS_SUCCESS; 988 } 989 AddHcpFqmStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const990 MOS_STATUS EncodePreEncPacket::AddHcpFqmStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const 991 { 992 ENCODE_FUNC_CALL(); 993 ENCODE_CHK_NULL_RETURN(cmdBuffer); 994 995 MHW_MI_CHK_NULL(m_hevcIqMatrixParams); 996 997 auto ¶ms = m_hcpItf->MHW_GETPAR_F(HCP_FQM_STATE)(); 998 params = {}; 999 1000 auto iqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams; 1001 uint16_t *fqMatrix = (uint16_t *)params.quantizermatrix; 1002 1003 /* 4x4 */ 1004 for (uint8_t i = 0; i < 32; i++) 1005 { 1006 params.quantizermatrix[i] = 0; 1007 } 1008 for (uint8_t intraInter = 0; intraInter <= 1; intraInter++) 1009 { 1010 params.intraInter = intraInter; 1011 params.sizeid = 0; 1012 params.colorComponent = 0; 1013 1014 for (uint8_t i = 0; i < 16; i++) 1015 { 1016 fqMatrix[i] = 1017 GetReciprocalScalingValue(iqMatrix->List4x4[3 * intraInter][i]); 1018 } 1019 1020 m_hcpItf->MHW_ADDCMD_F(HCP_FQM_STATE)(cmdBuffer); 1021 } 1022 1023 /* 8x8, 16x16 and 32x32 */ 1024 for (uint8_t i = 0; i < 32; i++) 1025 { 1026 params.quantizermatrix[i] = 0; 1027 } 1028 for (uint8_t intraInter = 0; intraInter <= 1; intraInter++) 1029 { 1030 params.intraInter = intraInter; 1031 params.sizeid = 1; 1032 params.colorComponent = 0; 1033 1034 for (uint8_t i = 0; i < 64; i++) 1035 { 1036 fqMatrix[i] = 1037 GetReciprocalScalingValue(iqMatrix->List8x8[3 * intraInter][i]); 1038 } 1039 1040 m_hcpItf->MHW_ADDCMD_F(HCP_FQM_STATE)(cmdBuffer); 1041 } 1042 1043 /* 16x16 DC */ 1044 for (uint8_t i = 0; i < 32; i++) 1045 { 1046 params.quantizermatrix[i] = 0; 1047 } 1048 for (uint8_t intraInter = 0; intraInter <= 1; intraInter++) 1049 { 1050 params.intraInter = intraInter; 1051 params.sizeid = 2; 1052 params.colorComponent = 0; 1053 params.fqmDcValue1Dc = GetReciprocalScalingValue(iqMatrix->ListDC16x16[3 * intraInter]); 1054 1055 for (uint8_t i = 0; i < 64; i++) 1056 { 1057 fqMatrix[i] = 1058 GetReciprocalScalingValue(iqMatrix->List16x16[3 * intraInter][i]); 1059 } 1060 1061 m_hcpItf->MHW_ADDCMD_F(HCP_FQM_STATE)(cmdBuffer); 1062 } 1063 1064 /* 32x32 DC */ 1065 for (uint8_t i = 0; i < 32; i++) 1066 { 1067 params.quantizermatrix[i] = 0; 1068 } 1069 for (uint8_t intraInter = 0; intraInter <= 1; intraInter++) 1070 { 1071 params.intraInter = intraInter; 1072 params.sizeid = 3; 1073 params.colorComponent = 0; 1074 params.fqmDcValue1Dc = GetReciprocalScalingValue(iqMatrix->ListDC32x32[intraInter]); 1075 1076 for (uint8_t i = 0; i < 64; i++) 1077 { 1078 fqMatrix[i] = 1079 GetReciprocalScalingValue(iqMatrix->List32x32[intraInter][i]); 1080 } 1081 1082 m_hcpItf->MHW_ADDCMD_F(HCP_FQM_STATE)(cmdBuffer); 1083 } 1084 1085 return MOS_STATUS_SUCCESS; 1086 } 1087 AddHcpQMStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const1088 MOS_STATUS EncodePreEncPacket::AddHcpQMStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const 1089 { 1090 ENCODE_FUNC_CALL(); 1091 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1092 1093 MHW_MI_CHK_NULL(m_hevcIqMatrixParams); 1094 1095 auto ¶ms = m_hcpItf->MHW_GETPAR_F(HCP_QM_STATE)(); 1096 params = {}; 1097 1098 auto iqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams; 1099 uint8_t *qMatrix = (uint8_t *)params.quantizermatrix; 1100 1101 for (uint8_t sizeId = 0; sizeId < 4; sizeId++) // 4x4, 8x8, 16x16, 32x32 1102 { 1103 for (uint8_t predType = 0; predType < 2; predType++) // Intra, Inter 1104 { 1105 for (uint8_t color = 0; color < 3; color++) // Y, Cb, Cr 1106 { 1107 if ((sizeId == 3) && (color != 0)) 1108 break; 1109 1110 params.sizeid = sizeId; 1111 params.predictionType = predType; 1112 params.colorComponent = color; 1113 switch (sizeId) 1114 { 1115 case 0: 1116 case 1: 1117 default: 1118 params.dcCoefficient = 0; 1119 break; 1120 case 2: 1121 params.dcCoefficient = iqMatrix->ListDC16x16[3 * predType + color]; 1122 break; 1123 case 3: 1124 params.dcCoefficient = iqMatrix->ListDC32x32[predType]; 1125 break; 1126 } 1127 1128 if (sizeId == 0) 1129 { 1130 for (uint8_t i = 0; i < 4; i++) 1131 { 1132 for (uint8_t ii = 0; ii < 4; ii++) 1133 { 1134 qMatrix[4 * i + ii] = iqMatrix->List4x4[3 * predType + color][4 * i + ii]; 1135 } 1136 } 1137 } 1138 else if (sizeId == 1) 1139 { 1140 for (uint8_t i = 0; i < 8; i++) 1141 { 1142 for (uint8_t ii = 0; ii < 8; ii++) 1143 { 1144 qMatrix[8 * i + ii] = iqMatrix->List8x8[3 * predType + color][8 * i + ii]; 1145 } 1146 } 1147 } 1148 else if (sizeId == 2) 1149 { 1150 for (uint8_t i = 0; i < 8; i++) 1151 { 1152 for (uint8_t ii = 0; ii < 8; ii++) 1153 { 1154 qMatrix[8 * i + ii] = iqMatrix->List16x16[3 * predType + color][8 * i + ii]; 1155 } 1156 } 1157 } 1158 else // 32x32 1159 { 1160 for (uint8_t i = 0; i < 8; i++) 1161 { 1162 for (uint8_t ii = 0; ii < 8; ii++) 1163 { 1164 qMatrix[8 * i + ii] = iqMatrix->List32x32[predType][8 * i + ii]; 1165 } 1166 } 1167 } 1168 1169 m_hcpItf->MHW_ADDCMD_F(HCP_QM_STATE)(cmdBuffer); 1170 } 1171 } 1172 } 1173 1174 return MOS_STATUS_SUCCESS; 1175 } 1176 AddHcpPakInsertObjectCmds(PMOS_COMMAND_BUFFER cmdBuffer) const1177 MOS_STATUS EncodePreEncPacket::AddHcpPakInsertObjectCmds(PMOS_COMMAND_BUFFER cmdBuffer) const 1178 { 1179 ENCODE_FUNC_CALL(); 1180 1181 ENCODE_CHK_NULL_RETURN(m_osInterface); 1182 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1183 1184 auto ¶ms = m_hcpItf->MHW_GETPAR_F(HCP_PAK_INSERT_OBJECT)(); 1185 params = {}; 1186 1187 PCODECHAL_NAL_UNIT_PARAMS *ppNalUnitParams = (CODECHAL_NAL_UNIT_PARAMS **)m_nalUnitParams; 1188 1189 PBSBuffer pBsBuffer = &(m_basicFeature->m_bsBuffer); 1190 uint32_t bitSize = 0; 1191 uint32_t offSet = 0; 1192 1193 //insert AU, SPS, PSP headers before first slice header 1194 uint32_t maxBytesInPakInsertObjCmd = ((2 << 11) - 1) * 4; // 12 bits for Length field in PAK_INSERT_OBJ cmd 1195 1196 for (uint32_t i = 0; i < m_basicFeature->m_NumNalUnits; i++) 1197 { 1198 uint32_t nalunitPosiSize = ppNalUnitParams[i]->uiSize; 1199 uint32_t nalunitPosiOffset = ppNalUnitParams[i]->uiOffset; 1200 1201 while (nalunitPosiSize > 0) 1202 { 1203 bitSize = MOS_MIN(maxBytesInPakInsertObjCmd * 8, nalunitPosiSize * 8); 1204 offSet = nalunitPosiOffset; 1205 1206 params = {}; 1207 1208 params.dwPadding = (MOS_ALIGN_CEIL((bitSize + 7) >> 3, sizeof(uint32_t))) / sizeof(uint32_t); 1209 params.bEmulationByteBitsInsert = ppNalUnitParams[i]->bInsertEmulationBytes; 1210 params.uiSkipEmulationCheckCount = ppNalUnitParams[i]->uiSkipEmulationCheckCount; 1211 params.dataBitsInLastDw = bitSize % 32; 1212 if (params.dataBitsInLastDw == 0) 1213 { 1214 params.dataBitsInLastDw = 32; 1215 } 1216 1217 if (nalunitPosiSize > maxBytesInPakInsertObjCmd) 1218 { 1219 nalunitPosiSize -= maxBytesInPakInsertObjCmd; 1220 nalunitPosiOffset += maxBytesInPakInsertObjCmd; 1221 } 1222 else 1223 { 1224 nalunitPosiSize = 0; 1225 } 1226 m_hcpItf->MHW_ADDCMD_F(HCP_PAK_INSERT_OBJECT)(cmdBuffer); 1227 uint32_t byteSize = (bitSize + 7) >> 3; 1228 if (byteSize) 1229 { 1230 MHW_MI_CHK_NULL(pBsBuffer); 1231 MHW_MI_CHK_NULL(pBsBuffer->pBase); 1232 uint8_t *data = (uint8_t *)(pBsBuffer->pBase + offSet); 1233 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, data, byteSize)); 1234 } 1235 } 1236 } 1237 1238 params = {}; 1239 // Insert slice header 1240 params.bLastHeader = true; 1241 params.bEmulationByteBitsInsert = true; 1242 1243 // App does the slice header packing, set the skip count passed by the app 1244 PCODEC_ENCODER_SLCDATA slcData = m_basicFeature->m_slcData; 1245 1246 params.uiSkipEmulationCheckCount = slcData->SkipEmulationByteCount; 1247 bitSize = slcData->BitSize; 1248 offSet = slcData->SliceOffset; 1249 1250 // Hevc header needs slcData->BitSize > 0 to caculate params.dwPadding and params.dataBitsInLastDw for cmd HCP_PAK_INSERT_OBJECT. 1251 // For Av1, slcData params are zeros. Av1 use Hevc preEnc packet, need to set bitSize>0. 1252 // The bitstream header size will have no effect on the mv. 1253 if (bitSize == 0) 1254 { 1255 bitSize = sizeof(uint8_t) * 8; 1256 } 1257 1258 params.dwPadding = (MOS_ALIGN_CEIL((bitSize + 7) >> 3, sizeof(uint32_t))) / sizeof(uint32_t); 1259 params.dataBitsInLastDw = bitSize % 32; 1260 if (params.dataBitsInLastDw == 0) 1261 { 1262 params.dataBitsInLastDw = 32; 1263 } 1264 m_hcpItf->MHW_ADDCMD_F(HCP_PAK_INSERT_OBJECT)(cmdBuffer); 1265 uint32_t byteSize = (bitSize + 7) >> 3; 1266 if (byteSize) 1267 { 1268 MHW_MI_CHK_NULL(pBsBuffer); 1269 MHW_MI_CHK_NULL(pBsBuffer->pBase); 1270 uint8_t *data = (uint8_t *)(pBsBuffer->pBase + offSet); 1271 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, data, byteSize)); 1272 } 1273 1274 return MOS_STATUS_SUCCESS; 1275 } 1276 AddHcpRefIdxStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const1277 MOS_STATUS EncodePreEncPacket::AddHcpRefIdxStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const 1278 { 1279 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1280 ENCODE_FUNC_CALL(); 1281 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1282 1283 auto ¶ms = m_hcpItf->MHW_GETPAR_F(HCP_REF_IDX_STATE)(); 1284 params = {}; 1285 1286 CODEC_PICTURE currPic = {}; 1287 CODEC_PICTURE refPicList[2][CODEC_MAX_NUM_REF_FRAME_HEVC] = {}; 1288 void ** hevcRefList = nullptr; 1289 int32_t pocCurrPic = 0; 1290 int8_t * pRefIdxMapping = nullptr; 1291 int32_t pocList[CODEC_MAX_NUM_REF_FRAME_HEVC] = {}; 1292 1293 if (m_basicFeature->m_preEncConfig.SliceType != encodeHevcISlice) 1294 { 1295 currPic = m_basicFeature->m_preEncConfig.CurrReconstructedPic; 1296 params.ucList = LIST_0; 1297 params.numRefIdxLRefpiclistnumActiveMinus1 = 0; 1298 eStatus = MOS_SecureMemcpy(&refPicList, sizeof(refPicList), &m_basicFeature->m_preEncConfig.RefPicList, sizeof(m_basicFeature->m_preEncConfig.RefPicList)); 1299 if (eStatus != MOS_STATUS_SUCCESS) 1300 { 1301 ENCODE_ASSERTMESSAGE("Failed to copy memory."); 1302 return eStatus; 1303 } 1304 1305 hevcRefList = (void **)m_basicFeature->GetRefList(); 1306 pocCurrPic = m_basicFeature->m_preEncConfig.CurrPicOrderCnt; 1307 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) 1308 { 1309 pocList[i] = m_basicFeature->m_preEncConfig.RefFramePOCList[i]; 1310 } 1311 1312 pRefIdxMapping = m_basicFeature->GetRefIdxMapping(); 1313 1314 MHW_ASSERT(currPic.FrameIdx != 0x7F); 1315 1316 for (uint8_t i = 0; i <= params.numRefIdxLRefpiclistnumActiveMinus1; i++) 1317 { 1318 uint8_t refFrameIDx = refPicList[params.ucList][i].FrameIdx; 1319 if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC) 1320 { 1321 MHW_ASSERT(*(pRefIdxMapping + refFrameIDx) >= 0); 1322 1323 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = *(pRefIdxMapping + refFrameIDx); 1324 int32_t pocDiff = pocCurrPic - pocList[refFrameIDx]; 1325 params.referencePictureTbValue[i] = (uint8_t)CodecHal_Clip3(-128, 127, pocDiff); 1326 CODEC_REF_LIST **refList = (CODEC_REF_LIST **)hevcRefList; 1327 params.longtermreference[i] = CodecHal_PictureIsLongTermRef(refList[currPic.FrameIdx]->RefList[refFrameIDx]); 1328 params.bottomFieldFlag[i] = 1; 1329 } 1330 else 1331 { 1332 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0; 1333 params.referencePictureTbValue[i] = 0; 1334 params.longtermreference[i] = false; 1335 params.bottomFieldFlag[i] = 0; 1336 } 1337 } 1338 1339 for (uint8_t i = (uint8_t)(params.numRefIdxLRefpiclistnumActiveMinus1 + 1); i < 16; i++) 1340 { 1341 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0; 1342 params.referencePictureTbValue[i] = 0; 1343 params.longtermreference[i] = false; 1344 params.bottomFieldFlag[i] = 0; 1345 } 1346 1347 m_hcpItf->MHW_ADDCMD_F(HCP_REF_IDX_STATE)(cmdBuffer); 1348 1349 params = {}; 1350 1351 if (m_basicFeature->m_preEncConfig.SliceType == encodeHevcBSlice) 1352 { 1353 AddHcpBSliceRefIdxStateCmds(cmdBuffer); 1354 } 1355 } 1356 1357 return MOS_STATUS_SUCCESS; 1358 } 1359 AddHcpBSliceRefIdxStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const1360 MOS_STATUS EncodePreEncPacket::AddHcpBSliceRefIdxStateCmds(PMOS_COMMAND_BUFFER cmdBuffer) const 1361 { 1362 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1363 ENCODE_FUNC_CALL(); 1364 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1365 1366 auto ¶ms = m_hcpItf->MHW_GETPAR_F(HCP_REF_IDX_STATE)(); 1367 params = {}; 1368 1369 CODEC_PICTURE currPic = {}; 1370 CODEC_PICTURE refPicList[2][CODEC_MAX_NUM_REF_FRAME_HEVC] = {}; 1371 void ** hevcRefList = nullptr; 1372 int32_t pocCurrPic = 0; 1373 int8_t * pRefIdxMapping = nullptr; 1374 int32_t pocList[CODEC_MAX_NUM_REF_FRAME_HEVC] = {}; 1375 1376 currPic = m_basicFeature->m_preEncConfig.CurrReconstructedPic; 1377 eStatus = MOS_SecureMemcpy(&refPicList, sizeof(refPicList), &m_basicFeature->m_preEncConfig.RefPicList, sizeof(m_basicFeature->m_preEncConfig.RefPicList)); 1378 if (eStatus != MOS_STATUS_SUCCESS) 1379 { 1380 ENCODE_ASSERTMESSAGE("Failed to copy memory."); 1381 return eStatus; 1382 } 1383 hevcRefList = (void **)m_basicFeature->GetRefList(); 1384 pocCurrPic = m_basicFeature->m_preEncConfig.CurrPicOrderCnt; 1385 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) 1386 { 1387 pocList[i] = m_basicFeature->m_preEncConfig.RefFramePOCList[i]; 1388 } 1389 1390 pRefIdxMapping = m_basicFeature->GetRefIdxMapping(); 1391 1392 MHW_ASSERT(currPic.FrameIdx != 0x7F); 1393 1394 params.ucList = LIST_1; 1395 params.numRefIdxLRefpiclistnumActiveMinus1 = 0; 1396 for (uint8_t i = 0; i <= params.numRefIdxLRefpiclistnumActiveMinus1; i++) 1397 { 1398 uint8_t refFrameIDx = m_basicFeature->m_preEncConfig.isPToB ? refPicList[0][i].FrameIdx : refPicList[1][i].FrameIdx; 1399 if (refFrameIDx < CODEC_MAX_NUM_REF_FRAME_HEVC) 1400 { 1401 MHW_ASSERT(*(pRefIdxMapping + refFrameIDx) >= 0); 1402 1403 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = *(pRefIdxMapping + refFrameIDx); 1404 int32_t pocDiff = pocCurrPic - pocList[refFrameIDx]; 1405 params.referencePictureTbValue[i] = (uint8_t)CodecHal_Clip3(-128, 127, pocDiff); 1406 CODEC_REF_LIST **refList = (CODEC_REF_LIST **)hevcRefList; 1407 params.longtermreference[i] = CodecHal_PictureIsLongTermRef(refList[currPic.FrameIdx]->RefList[refFrameIDx]); 1408 params.bottomFieldFlag[i] = 1; 1409 } 1410 else 1411 { 1412 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0; 1413 params.referencePictureTbValue[i] = 0; 1414 params.longtermreference[i] = false; 1415 params.bottomFieldFlag[i] = 0; 1416 } 1417 } 1418 1419 for (uint8_t i = (uint8_t)(params.numRefIdxLRefpiclistnumActiveMinus1 + 1); i < 16; i++) 1420 { 1421 params.listEntryLxReferencePictureFrameIdRefaddr07[i] = 0; 1422 params.referencePictureTbValue[i] = 0; 1423 params.longtermreference[i] = false; 1424 params.bottomFieldFlag[i] = 0; 1425 } 1426 m_hcpItf->MHW_ADDCMD_F(HCP_REF_IDX_STATE)(cmdBuffer); 1427 return eStatus; 1428 } 1429 } // namespace encode 1430