1 /* 2 * Copyright (c) 2018-2021, 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 //! 24 //! \file encode_huc_brc_update_packet.cpp 25 //! \brief Defines the implementation of huc update packet 26 //! 27 28 #include "encode_huc_brc_update_packet.h" 29 #include "codechal_debug.h" 30 #include "encode_hevc_vdenc_weighted_prediction.h" 31 #include "encode_hevc_brc.h" 32 #include "encode_hevc_vdenc_scc.h" 33 #include "encode_vdenc_lpla_analysis.h" 34 #include "encode_hevc_vdenc_lpla_enc.h" 35 #include "encode_hevc_header_packer.h" 36 37 namespace encode 38 { Init()39 MOS_STATUS HucBrcUpdatePkt::Init() 40 { 41 ENCODE_FUNC_CALL(); 42 m_hwInterface->m_vdencBatchBuffer1stGroupSize = MOS_ALIGN_CEIL(m_hwInterface->m_vdencBatchBuffer1stGroupSize, CODECHAL_CACHELINE_SIZE); 43 m_hwInterface->m_vdencBatchBuffer2ndGroupSize = MOS_ALIGN_CEIL(m_hwInterface->m_vdencBatchBuffer2ndGroupSize, CODECHAL_CACHELINE_SIZE); 44 m_hwInterface->m_vdencReadBatchBufferSize = 45 m_hwInterface->m_vdenc2ndLevelBatchBufferSize = m_hwInterface->m_vdencBatchBuffer1stGroupSize 46 + m_hwInterface->m_vdencBatchBuffer2ndGroupSize 47 + ENCODE_HEVC_VDENC_NUM_MAX_SLICES * MOS_ALIGN_CEIL((2 * m_hcpItf->MHW_GETSIZE_F(HCP_WEIGHTOFFSET_STATE)() 48 + m_hcpItf->MHW_GETSIZE_F(HCP_SLICE_STATE)() 49 + 2 * m_hcpItf->MHW_GETSIZE_F(HCP_PAK_INSERT_OBJECT)() 50 + sizeof (HevcSlice) 51 + m_vdencItf->MHW_GETSIZE_F(VDENC_WEIGHTSOFFSETS_STATE)() 52 + 2 * m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)()), CODECHAL_CACHELINE_SIZE); 53 m_hwInterface->m_vdencBatchBufferPerSliceConstSize = m_hcpItf->MHW_GETSIZE_F(HCP_SLICE_STATE)() 54 + m_vdencItf->MHW_GETSIZE_F(VDENC_WEIGHTSOFFSETS_STATE)() 55 + m_hcpItf->MHW_GETSIZE_F(HCP_PAK_INSERT_OBJECT)() 56 + m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)() * 2; 57 58 HUC_CHK_STATUS_RETURN(EncodeHucPkt::Init()); 59 60 ENCODE_CHK_NULL_RETURN(m_pipeline); 61 m_allocator = m_pipeline->GetEncodeAllocator(); 62 ENCODE_CHK_NULL_RETURN(m_allocator); 63 64 ENCODE_CHK_NULL_RETURN(m_featureManager); 65 m_basicFeature = dynamic_cast<HevcBasicFeature *>(m_featureManager->GetFeature(HevcFeatureIDs::basicFeature)); 66 ENCODE_CHK_NULL_RETURN(m_basicFeature); 67 68 return MOS_STATUS_SUCCESS; 69 } 70 CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)71 MOS_STATUS HucBrcUpdatePkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize) 72 { 73 ENCODE_FUNC_CALL(); 74 75 auto osInterface = m_hwInterface->GetOsInterface(); 76 ENCODE_CHK_NULL_RETURN(osInterface); 77 78 uint32_t hucCommandsSize = 0; 79 uint32_t hucPatchListSize = 0; 80 MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams; 81 82 stateCmdSizeParams.uNumStoreDataImm = 2; 83 stateCmdSizeParams.uNumStoreReg = 4; 84 stateCmdSizeParams.uNumMfxWait = 3; 85 stateCmdSizeParams.uNumAddConBBEnd = 1; 86 ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize( 87 m_basicFeature->m_mode, (uint32_t*)&hucCommandsSize, (uint32_t*)&hucPatchListSize, &stateCmdSizeParams)); 88 89 commandBufferSize = hucCommandsSize; 90 requestedPatchListSize = osInterface->bUsesPatchList ? hucPatchListSize : 0; 91 92 if (m_pipeline->IsSingleTaskPhaseSupported()) 93 { 94 commandBufferSize *= m_pipeline->GetPassNum(); 95 } 96 97 // 4K align since allocation is in chunks of 4K bytes. 98 commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE); 99 100 return MOS_STATUS_SUCCESS; 101 } 102 DumpOutput()103 MOS_STATUS HucBrcUpdatePkt::DumpOutput() 104 { 105 ENCODE_FUNC_CALL(); 106 107 #if USE_CODECHAL_DEBUG_TOOL 108 DumpHucBrcUpdate(false); 109 #endif 110 return MOS_STATUS_SUCCESS; 111 } 112 AllocateResources()113 MOS_STATUS HucBrcUpdatePkt::AllocateResources() 114 { 115 ENCODE_FUNC_CALL(); 116 ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::AllocateResources()); 117 118 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 119 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 120 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 121 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 122 allocParamsForBufferLinear.Format = Format_Buffer; 123 124 // HuC FW Region 6: Data Buffer of Current Picture 125 // Data (1024 bytes) for current 126 // Data (1024 bytes) for ref0 127 // Data (1024 bytes) for ref1 128 // Data (1024 bytes) for ref2 129 allocParamsForBufferLinear.dwBytes = CODECHAL_PAGE_SIZE * 4; 130 allocParamsForBufferLinear.pBufName = "Data from Pictures Buffer for Weighted Prediction"; 131 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE; 132 MOS_RESOURCE *allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 133 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 134 m_dataFromPicsBuffer = *allocatedbuffer; 135 136 for (auto k = 0; k < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; k++) 137 { 138 // Const Data buffer 139 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcConstDataBufferSize, CODECHAL_PAGE_SIZE); 140 allocParamsForBufferLinear.pBufName = "VDENC BRC Const Data Buffer"; 141 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE; 142 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 143 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 144 m_vdencBrcConstDataBuffer[k] = *allocatedbuffer; 145 146 for (auto i = 0; i < VDENC_BRC_NUM_OF_PASSES; i++) 147 { 148 // VDEnc read batch buffer (input for HuC FW) 149 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 150 allocParamsForBufferLinear.pBufName = "VDENC Read Batch Buffer"; 151 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 152 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 153 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 154 m_vdencReadBatchBuffer[k][i] = *allocatedbuffer; 155 156 // BRC update DMEM 157 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcUpdateDmemBufferSize, CODECHAL_CACHELINE_SIZE); 158 allocParamsForBufferLinear.pBufName = "VDENC BrcUpdate DmemBuffer"; 159 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE; 160 allocatedbuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true, MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ); 161 ENCODE_CHK_NULL_RETURN(allocatedbuffer); 162 m_vdencBrcUpdateDmemBuffer[k][i] = *allocatedbuffer; 163 } 164 } 165 166 return MOS_STATUS_SUCCESS; 167 } 168 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE,HucBrcUpdatePkt)169 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE, HucBrcUpdatePkt) 170 { 171 if (m_basicFeature->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) // Low Delay BRC 172 { 173 params.kernelDescriptor = m_vdboxHucHevcBrcLowdelayKernelDescriptor; 174 } 175 else 176 { 177 params.kernelDescriptor = m_vdboxHucHevcBrcUpdateKernelDescriptor; 178 } 179 180 return MOS_STATUS_SUCCESS; 181 } 182 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,HucBrcUpdatePkt)183 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, HucBrcUpdatePkt) 184 { 185 ENCODE_CHK_STATUS_RETURN(SetDmemBuffer()); 186 187 params.function = BRC_UPDATE; 188 params.passNum = static_cast<uint8_t>(m_pipeline->GetPassNum()); 189 params.currentPass = static_cast<uint8_t> (m_pipeline->GetCurrentPass()); 190 params.hucDataSource = const_cast<PMOS_RESOURCE> (&m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()]); 191 params.dataLength = MOS_ALIGN_CEIL(m_vdencBrcUpdateDmemBufferSize, CODECHAL_CACHELINE_SIZE); 192 params.dmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS; 193 194 return MOS_STATUS_SUCCESS; 195 } 196 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,HucBrcUpdatePkt)197 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, HucBrcUpdatePkt) 198 { 199 ENCODE_FUNC_CALL(); 200 201 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 202 203 int32_t currentPass = m_pipeline->GetCurrentPass(); 204 if (currentPass < 0) 205 { 206 eStatus = MOS_STATUS_INVALID_PARAMETER; 207 return eStatus; 208 } 209 210 ENCODE_CHK_NULL_RETURN(m_basicFeature); 211 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf); 212 213 params.function = BRC_UPDATE; 214 215 ENCODE_CHK_STATUS_RETURN(SetConstDataHuCBrcUpdate()); 216 217 // Add Virtual addr 218 RUN_FEATURE_INTERFACE_RETURN(HEVCEncodeBRC, HevcFeatureIDs::hevcBrcFeature, 219 SetCurrRecycledBufIdx, m_pipeline->m_currRecycledBufIdx); 220 221 params.regionParams[2].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(FrameStatStreamOutBuffer, 0); // Region 2 PAK Statistics Buffer (Input) - MFX_PAK_FRAME_STATISTICS 222 params.regionParams[3].presRegion = const_cast<PMOS_RESOURCE>(&m_vdencReadBatchBuffer[m_pipeline->m_currRecycledBufIdx][currentPass]); // Region 3 - Input SLB Buffer (Input) 223 params.regionParams[4].presRegion = const_cast<PMOS_RESOURCE>(&m_vdencBrcConstDataBuffer[m_pipeline->m_currRecycledBufIdx]); // Region 4 - Constant Data (Input) 224 params.regionParams[6].presRegion = const_cast<PMOS_RESOURCE>(&m_dataFromPicsBuffer); // Region 6 - Data Buffer of Current and Reference Pictures for Weighted Prediction (Input/Output) 225 params.regionParams[6].isWritable = true; 226 params.regionParams[8].presRegion = 227 m_basicFeature->m_recycleBuf->GetBuffer(PakInfo, 0); // Region 8 - PAK Information (Input) 228 229 params.regionParams[7].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(LcuBaseAddressBuffer, 0); // Region 7 Slice Stat Streamout (Input) 230 231 bool tileEnabled = false; 232 RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, IsEnabled, tileEnabled); 233 if (tileEnabled) 234 { 235 MOS_RESOURCE *resHuCPakAggregatedFrameStatsBuffer = nullptr; 236 RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, GetHucPakAggregatedFrameStatsBuffer, resHuCPakAggregatedFrameStatsBuffer); 237 HevcTileStatusInfo tileStatsOffset = {}; 238 HevcTileStatusInfo frameStatsOffset = {}; 239 HevcTileStatusInfo statsSize = {}; 240 RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, GetTileStatusInfo, tileStatsOffset, frameStatsOffset, statsSize); 241 params.regionParams[1].presRegion = resHuCPakAggregatedFrameStatsBuffer; 242 params.regionParams[1].dwOffset = frameStatsOffset.vdencStatistics; 243 244 if (m_pipeline->GetPipeNum() > 1) 245 { 246 params.regionParams[2].presRegion = resHuCPakAggregatedFrameStatsBuffer; // Region 2 PAK Statistics Buffer (Input) - MFX_PAK_FRAME_STATISTICS 247 params.regionParams[2].dwOffset = frameStatsOffset.hevcPakStatistics; 248 params.regionParams[7].presRegion = resHuCPakAggregatedFrameStatsBuffer; // Region 7 Slice Stat Streamout (Input) 249 params.regionParams[7].dwOffset = frameStatsOffset.hevcSliceStreamout; 250 // In scalable-mode, use PAK Integration kernel output to get bistream size 251 MOS_RESOURCE *resBrcDataBuffer = nullptr; 252 RUN_FEATURE_INTERFACE_RETURN(HEVCEncodeBRC, HevcFeatureIDs::hevcBrcFeature, GetBrcDataBuffer, resBrcDataBuffer); 253 params.regionParams[8].presRegion = resBrcDataBuffer; 254 } 255 } 256 else 257 { 258 params.regionParams[1].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencStatsBuffer, 0); // Region 1 VDEnc Statistics Buffer (Input) - VDENC_HEVC_VP9_FRAME_BASED_STATISTICS_STREAMOUT 259 } 260 261 return MOS_STATUS_SUCCESS; 262 } 263 SetCommonDmemBuffer(VdencHevcHucBrcUpdateDmem * hucVdencBrcUpdateDmem)264 MOS_STATUS HucBrcUpdatePkt::SetCommonDmemBuffer(VdencHevcHucBrcUpdateDmem *hucVdencBrcUpdateDmem) 265 { 266 RUN_FEATURE_INTERFACE_RETURN(HEVCEncodeBRC, HevcFeatureIDs::hevcBrcFeature, SetDmemForUpdate, hucVdencBrcUpdateDmem); 267 268 hucVdencBrcUpdateDmem->TARGETSIZE_U32 = 269 (m_basicFeature->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) ? m_basicFeature->m_hevcSeqParams->InitVBVBufferFullnessInBit : MOS_MIN(m_basicFeature->m_hevcSeqParams->InitVBVBufferFullnessInBit, m_basicFeature->m_hevcSeqParams->VBVBufferSizeInBit); 270 hucVdencBrcUpdateDmem->FrameID_U32 = m_basicFeature->m_frameNum; // frame number 271 hucVdencBrcUpdateDmem->TargetSliceSize_U16 = (uint16_t)m_basicFeature->m_hevcPicParams->MaxSliceSizeInBytes; 272 hucVdencBrcUpdateDmem->SLB_Data_SizeInBytes = (uint16_t)m_slbDataSizeInBytes; 273 hucVdencBrcUpdateDmem->PIPE_MODE_SELECT_StartInBytes = 0xFFFF; // HuC need not modify the pipe mode select command in Gen11+ 274 hucVdencBrcUpdateDmem->CMD1_StartInBytes = (uint16_t)m_hwInterface->m_vdencBatchBuffer1stGroupSize; 275 hucVdencBrcUpdateDmem->PIC_STATE_StartInBytes = (uint16_t)m_basicFeature->m_picStateCmdStartInBytes; 276 hucVdencBrcUpdateDmem->CMD2_StartInBytes = (uint16_t)m_cmd2StartInBytes; 277 278 if (m_basicFeature->m_prevStoreData != m_basicFeature->m_frameNum) 279 { 280 m_basicFeature->m_prevStoreData = m_basicFeature->m_frameNum; 281 282 int32_t oldestIdx = -1; 283 int32_t selectedSlot = -1; 284 uint32_t oldestAge = 0; 285 for (int i = 0; i < CODECHAL_ENCODE_HEVC_VDENC_WP_DATA_BLOCK_NUMBER; i++) 286 { 287 if (slotInfo[i].isUsed == true && slotInfo[i].isRef) 288 { 289 slotInfo[i].age++; 290 if (slotInfo[i].age >= oldestAge) 291 { 292 oldestAge = slotInfo[i].age; 293 oldestIdx = i; 294 } 295 } 296 if ((selectedSlot == -1) && (slotInfo[i].isUsed == false || !slotInfo[i].isRef)) 297 { 298 selectedSlot = i; 299 } 300 } 301 302 if (selectedSlot == -1) 303 { 304 selectedSlot = oldestIdx; 305 } 306 307 if (selectedSlot == -1) 308 { 309 ENCODE_ASSERTMESSAGE("No valid ref slot index"); 310 return MOS_STATUS_INVALID_PARAMETER; 311 } 312 313 slotInfo[selectedSlot].age = 0; 314 slotInfo[selectedSlot].poc = m_basicFeature->m_hevcPicParams->CurrPicOrderCnt; 315 slotInfo[selectedSlot].isUsed = true; 316 slotInfo[selectedSlot].isRef = m_basicFeature->m_hevcPicParams->bUsedAsRef; 317 318 m_curPicSlot = selectedSlot; 319 } 320 321 hucVdencBrcUpdateDmem->Current_Data_Offset = m_curPicSlot * m_weightHistSize; 322 323 for (uint8_t refIdx = 0; refIdx <= m_basicFeature->m_hevcSliceParams->num_ref_idx_l0_active_minus1; refIdx++) 324 { 325 CODEC_PICTURE refPic = m_basicFeature->m_hevcSliceParams->RefPicList[LIST_0][refIdx]; 326 auto refPOC = m_basicFeature->m_hevcPicParams->RefFramePOCList[refPic.FrameIdx]; 327 for (int i = 0; i < CODECHAL_ENCODE_HEVC_VDENC_WP_DATA_BLOCK_NUMBER; i++) 328 { 329 if (slotInfo[i].poc == refPOC) 330 { 331 hucVdencBrcUpdateDmem->Ref_Data_Offset[refIdx] = i * m_weightHistSize; 332 break; 333 } 334 } 335 } 336 337 for (uint8_t refIdx = 0; refIdx <= m_basicFeature->m_hevcSliceParams->num_ref_idx_l1_active_minus1; refIdx++) 338 { 339 CODEC_PICTURE refPic = m_basicFeature->m_hevcSliceParams->RefPicList[LIST_1][refIdx]; 340 auto refPOC = m_basicFeature->m_hevcPicParams->RefFramePOCList[refPic.FrameIdx]; 341 for (int i = 0; i < CODECHAL_ENCODE_HEVC_VDENC_WP_DATA_BLOCK_NUMBER; i++) 342 { 343 if (slotInfo[i].poc == refPOC) 344 { 345 hucVdencBrcUpdateDmem->Ref_Data_Offset[refIdx + m_basicFeature->m_hevcSliceParams->num_ref_idx_l0_active_minus1 + 1] = i * m_weightHistSize; 346 break; 347 } 348 } 349 } 350 351 hucVdencBrcUpdateDmem->MaxNumSliceAllowed_U16 = (uint16_t)GetMaxAllowedSlices(m_basicFeature->m_hevcSeqParams->Level); 352 353 hucVdencBrcUpdateDmem->OpMode_U8 = 0x4; 354 355 bool enableTileReplay = false; 356 RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, IsTileReplayEnabled, enableTileReplay); 357 if (enableTileReplay) 358 { 359 hucVdencBrcUpdateDmem->OpMode_U8 = 0x8; 360 } 361 else 362 { 363 RUN_FEATURE_INTERFACE_RETURN( 364 HevcVdencWeightedPred, 365 HevcFeatureIDs::hevcVdencWpFeature, 366 SetHucBrcUpdateDmemBuffer, 367 m_pipeline->IsFirstPass(), 368 *hucVdencBrcUpdateDmem); 369 } 370 371 bool bAllowedPyramid = m_basicFeature->m_hevcSeqParams->GopRefDist != 3; 372 373 if (m_basicFeature->m_pictureCodingType == I_TYPE) 374 { 375 hucVdencBrcUpdateDmem->CurrentFrameType_U8 = HEVC_BRC_FRAME_TYPE_I; 376 } 377 else if (m_basicFeature->m_hevcSeqParams->HierarchicalFlag && bAllowedPyramid) 378 { 379 if (m_basicFeature->m_hevcPicParams->HierarchLevelPlus1 > 0) 380 { 381 std::map<int, HEVC_BRC_FRAME_TYPE> hierchLevelPlus1_to_brclevel{ 382 {1, HEVC_BRC_FRAME_TYPE_P_OR_LB}, 383 {2, HEVC_BRC_FRAME_TYPE_B}, 384 {3, HEVC_BRC_FRAME_TYPE_B1}, 385 {4, HEVC_BRC_FRAME_TYPE_B2}}; 386 hucVdencBrcUpdateDmem->CurrentFrameType_U8 = hierchLevelPlus1_to_brclevel.count(m_basicFeature->m_hevcPicParams->HierarchLevelPlus1) ? hierchLevelPlus1_to_brclevel[m_basicFeature->m_hevcPicParams->HierarchLevelPlus1] : HEVC_BRC_FRAME_TYPE_INVALID; 387 //Invalid HierarchLevelPlus1 or LBD frames at level 3 eror check. 388 if ((hucVdencBrcUpdateDmem->CurrentFrameType_U8 == HEVC_BRC_FRAME_TYPE_INVALID) || 389 (m_basicFeature->m_hevcSeqParams->LowDelayMode && hucVdencBrcUpdateDmem->CurrentFrameType_U8 == HEVC_BRC_FRAME_TYPE_B2)) 390 { 391 ENCODE_ASSERTMESSAGE("HEVC_BRC_FRAME_TYPE_INVALID or LBD picture doesn't support Level 4\n"); 392 return MOS_STATUS_INVALID_PARAMETER; 393 } 394 } 395 else if (!m_basicFeature->m_hevcSeqParams->LowDelayMode) //RA 396 { 397 //if L0/L1 both points to previous frame, then its LBD otherwise its is level 1 RA B. 398 auto B_or_LDB_brclevel = m_basicFeature->m_ref.IsLowDelay() ? HEVC_BRC_FRAME_TYPE_P_OR_LB : HEVC_BRC_FRAME_TYPE_B; 399 std::map<int, HEVC_BRC_FRAME_TYPE> codingtype_to_brclevel{ 400 {P_TYPE, HEVC_BRC_FRAME_TYPE_P_OR_LB}, 401 {B_TYPE, B_or_LDB_brclevel}, 402 {B1_TYPE, HEVC_BRC_FRAME_TYPE_B1}, 403 {B2_TYPE, HEVC_BRC_FRAME_TYPE_B2}}; 404 hucVdencBrcUpdateDmem->CurrentFrameType_U8 = codingtype_to_brclevel.count(m_basicFeature->m_pictureCodingType) ? codingtype_to_brclevel[m_basicFeature->m_pictureCodingType] : HEVC_BRC_FRAME_TYPE_INVALID; 405 //Invalid CodingType. 406 if (hucVdencBrcUpdateDmem->CurrentFrameType_U8 == HEVC_BRC_FRAME_TYPE_INVALID) 407 { 408 ENCODE_ASSERTMESSAGE("Invalid CodingType\n"); 409 return MOS_STATUS_INVALID_PARAMETER; 410 } 411 } 412 else //LDB 413 { 414 hucVdencBrcUpdateDmem->CurrentFrameType_U8 = HEVC_BRC_FRAME_TYPE_P_OR_LB; //No Hierarchical info for LDB, treated as flat case 415 } 416 } 417 else 418 { 419 hucVdencBrcUpdateDmem->CurrentFrameType_U8 = m_basicFeature->m_ref.IsLowDelay() ? HEVC_BRC_FRAME_TYPE_P_OR_LB : HEVC_BRC_FRAME_TYPE_B; 420 } 421 422 // Num_Ref_L1 should be always same as Num_Ref_L0 423 hucVdencBrcUpdateDmem->Num_Ref_L0_U8 = m_basicFeature->m_hevcSliceParams->num_ref_idx_l0_active_minus1 + 1; 424 hucVdencBrcUpdateDmem->Num_Ref_L1_U8 = m_basicFeature->m_hevcSliceParams->num_ref_idx_l1_active_minus1 + 1; 425 hucVdencBrcUpdateDmem->Num_Slices = (uint8_t)m_basicFeature->m_hevcPicParams->NumSlices; 426 427 // CQP_QPValue_U8 setting is needed since ACQP is also part of ICQ 428 hucVdencBrcUpdateDmem->CQP_QPValue_U8 = m_basicFeature->m_hevcPicParams->QpY + m_basicFeature->m_hevcSliceParams->slice_qp_delta; 429 hucVdencBrcUpdateDmem->CQP_FracQP_U8 = 0; 430 if (m_basicFeature->m_hevcPicParams->BRCPrecision == 1) 431 { 432 hucVdencBrcUpdateDmem->MaxNumPass_U8 = 1; 433 } 434 else 435 { 436 hucVdencBrcUpdateDmem->MaxNumPass_U8 = VDENC_BRC_NUM_OF_PASSES; 437 } 438 439 hucVdencBrcUpdateDmem->IPAverageCoeff_U8 = (m_basicFeature->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) ? 0 : 64; 440 hucVdencBrcUpdateDmem->CurrentPass_U8 = (uint8_t)m_pipeline->GetCurrentPass(); 441 442 // chroma weights are not confirmed to be supported from HW team yet 443 hucVdencBrcUpdateDmem->DisabledFeature_U8 = 0; // bit mask, 1 (bit0): disable chroma weight setting 444 445 hucVdencBrcUpdateDmem->SlidingWindow_Enable_U8 = (m_basicFeature->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_LOW); 446 hucVdencBrcUpdateDmem->LOG_LCU_Size_U8 = 6; 447 448 RUN_FEATURE_INTERFACE_RETURN( 449 HevcVdencScc, 450 HevcFeatureIDs::hevcVdencSccFeature, 451 SetHucBrcUpdateDmem, 452 hucVdencBrcUpdateDmem); 453 454 // reset skip frame statistics 455 //m_numSkipFrames = 0; 456 //m_sizeSkipFrames = 0; 457 458 // For tile row based BRC 459 //if (m_basicFeature->m_TileRowLevelBRC) 460 //{ 461 // hucVdencBrcUpdateDmem->MaxNumTileHuCCallMinus1 = m_basicFeature->m_hevcPicParams->num_tile_rows_minus1 + 1; 462 // hucVdencBrcUpdateDmem->TileHucCallIndex = (uint8_t)m_CurrentTileRow; 463 // hucVdencBrcUpdateDmem->TileHuCCallPassIndex = m_CurrentPassForTileReplay + 1; 464 // hucVdencBrcUpdateDmem->TileHuCCallPassMax = m_NumPassesForTileReplay; 465 466 // hucVdencBrcUpdateDmem->TxSizeInBitsPerFrame = 0; //threshold for the min frame size 467 468 // uint32_t numTileColumns = m_basicFeature->m_hevcPicParams->num_tile_columns_minus1 + 1; 469 // uint32_t startIdx = m_CurrentTileRow * numTileColumns; 470 // uint32_t endIdx = startIdx + numTileColumns - 1; 471 // uint32_t LCUsInTile = 0; 472 473 // for (uint32_t idx = 0; idx < numTileColumns; idx ++) 474 // { 475 // LCUsInTile += m_basicFeature->m_hevcPicParams->tile_row_height[m_CurrentTileRow] * m_hevcPicParams->tile_column_width[idx]; 476 // } 477 478 // hucVdencBrcUpdateDmem->StartTileIdx = (uint8_t)startIdx; 479 // hucVdencBrcUpdateDmem->EndTileIdx = (uint8_t)endIdx; 480 // hucVdencBrcUpdateDmem->TileSizeInLCU = (uint16_t)LCUsInTile; 481 //} 482 483 // Long term reference 484 hucVdencBrcUpdateDmem->IsLongTermRef = CodecHal_PictureIsLongTermRef(m_basicFeature->m_currReconstructedPic); 485 486 return MOS_STATUS_SUCCESS; 487 } 488 SetExtDmemBuffer(VdencHevcHucBrcUpdateDmem * hucVdencBrcUpdateDmem) const489 MOS_STATUS HucBrcUpdatePkt::SetExtDmemBuffer(VdencHevcHucBrcUpdateDmem *hucVdencBrcUpdateDmem) const 490 { 491 ENCODE_FUNC_CALL(); 492 493 // TCBRC 494 hucVdencBrcUpdateDmem->FrameSizeBoostForSceneChange = m_tcbrcQualityBoost; 495 hucVdencBrcUpdateDmem->TargetFrameSize = m_basicFeature->m_hevcPicParams->TargetFrameSize << 3; 496 497 auto CalculatedMaxFrame = m_basicFeature->GetProfileLevelMaxFrameSize(); 498 hucVdencBrcUpdateDmem->UPD_UserMaxFrame = m_basicFeature->m_hevcSeqParams->UserMaxIFrameSize > 0 ? MOS_MIN(m_basicFeature->m_hevcSeqParams->UserMaxIFrameSize, CalculatedMaxFrame) : CalculatedMaxFrame; 499 hucVdencBrcUpdateDmem->UPD_UserMaxFramePB = m_basicFeature->m_hevcSeqParams->UserMaxPBFrameSize > 0 ? MOS_MIN(m_basicFeature->m_hevcSeqParams->UserMaxPBFrameSize, CalculatedMaxFrame) : CalculatedMaxFrame; 500 501 auto UserMaxFrame = m_basicFeature->m_hevcPicParams->CodingType == I_TYPE ? hucVdencBrcUpdateDmem->UPD_UserMaxFrame : hucVdencBrcUpdateDmem->UPD_UserMaxFramePB; 502 if (!(UserMaxFrame < hucVdencBrcUpdateDmem->TargetFrameSize / 4) 503 && !(hucVdencBrcUpdateDmem->FrameSizeBoostForSceneChange == 2) 504 && (m_basicFeature->m_hevcSeqParams->LookaheadDepth == 0)) 505 { 506 hucVdencBrcUpdateDmem->TargetFrameSize = 0; 507 } 508 else if (m_basicFeature->m_hevcPicParams->CodingType == I_TYPE && (m_basicFeature->m_hevcSeqParams->LookaheadDepth == 0)) 509 { 510 hucVdencBrcUpdateDmem->TargetFrameSize += m_basicFeature->m_hevcPicParams->TargetFrameSize; 511 } 512 513 hucVdencBrcUpdateDmem->ROMCurrent = 8; 514 hucVdencBrcUpdateDmem->ROMZero = 0; 515 516 // LPLA 517 RUN_FEATURE_INTERFACE_RETURN( 518 HEVCVdencLplaEnc, 519 HevcFeatureIDs::hevcVdencLplaEncFeature, 520 SetHucBrcUpdateExtBuffer, 521 hucVdencBrcUpdateDmem, 522 m_pipeline->IsLastPass()); 523 524 // CQM 525 hucVdencBrcUpdateDmem->CqmEnable = m_basicFeature->m_hevcSeqParams->scaling_list_enable_flag || m_basicFeature->m_hevcPicParams->scaling_list_data_present_flag; 526 527 return MOS_STATUS_SUCCESS; 528 } 529 SetDmemBuffer() const530 MOS_STATUS HucBrcUpdatePkt::SetDmemBuffer() const 531 { 532 ENCODE_FUNC_CALL(); 533 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 534 535 // Program update DMEM 536 auto hucVdencBrcUpdateDmem = 537 (VdencHevcHucBrcUpdateDmem *)m_allocator->LockResourceForWrite(const_cast<MOS_RESOURCE*>(&m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()])); 538 ENCODE_CHK_NULL_RETURN(hucVdencBrcUpdateDmem); 539 MOS_ZeroMemory(hucVdencBrcUpdateDmem, sizeof(VdencHevcHucBrcUpdateDmem)); 540 541 const_cast<HucBrcUpdatePkt* const>(this)->SetCommonDmemBuffer(hucVdencBrcUpdateDmem); 542 SetExtDmemBuffer(hucVdencBrcUpdateDmem); 543 544 m_allocator->UnLock(const_cast<MOS_RESOURCE*>(&m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()])); 545 546 return MOS_STATUS_SUCCESS; 547 } 548 SetConstLambdaHucBrcUpdate(void * params) const549 MOS_STATUS HucBrcUpdatePkt::SetConstLambdaHucBrcUpdate(void *params) const 550 { 551 ENCODE_FUNC_CALL(); 552 ENCODE_CHK_NULL_RETURN(params); 553 auto hucConstData = (VdencHevcHucBrcConstantData *)params; 554 555 RUN_FEATURE_INTERFACE_RETURN(HEVCEncodeBRC, HevcFeatureIDs::hevcBrcFeature, 556 SetConstLambdaForUpdate, hucConstData, true); 557 558 return MOS_STATUS_SUCCESS; 559 } 560 SetConstDataHuCBrcUpdate() const561 MOS_STATUS HucBrcUpdatePkt::SetConstDataHuCBrcUpdate() const 562 { 563 ENCODE_FUNC_CALL(); 564 565 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 566 567 auto hucConstData = (VdencHevcHucBrcConstantData *)m_allocator->LockResourceForWrite(const_cast<MOS_RESOURCE*>(&m_vdencBrcConstDataBuffer[m_pipeline->m_currRecycledBufIdx])); 568 ENCODE_CHK_NULL_RETURN(hucConstData); 569 570 ENCODE_CHK_STATUS_RETURN(SetConstLambdaHucBrcUpdate(hucConstData)); 571 RUN_FEATURE_INTERFACE_RETURN(HEVCEncodeBRC, HevcFeatureIDs::hevcBrcFeature, 572 SetConstForUpdate, hucConstData); 573 574 // starting location in batch buffer for each slice 575 uint32_t baseLocation = m_hwInterface->m_vdencBatchBuffer1stGroupSize + m_hwInterface->m_vdencBatchBuffer2ndGroupSize; 576 uint32_t currentLocation = baseLocation; 577 578 auto slcData = m_basicFeature->m_slcData; 579 // HCP_WEIGHTSOFFSETS_STATE + HCP_SLICE_STATE + HCP_PAK_INSERT_OBJECT + VDENC_WEIGHT_OFFSETS_STATE 580 for (uint32_t slcCount = 0; slcCount < m_basicFeature->m_numSlices; slcCount++) 581 { 582 m_basicFeature->m_curNumSlices = slcCount; 583 auto hevcSlcParams = &m_basicFeature->m_hevcSliceParams[slcCount]; 584 // HuC FW require unit in Bytes 585 hucConstData->Slice[slcCount].SizeOfCMDs 586 = (uint16_t)(m_hwInterface->m_vdencBatchBufferPerSliceConstSize + m_basicFeature->m_vdencBatchBufferPerSliceVarSize[slcCount]); 587 588 // HCP_WEIGHTOFFSET_STATE cmd 589 RUN_FEATURE_INTERFACE_RETURN( 590 HevcVdencWeightedPred, 591 HevcFeatureIDs::hevcVdencWpFeature, 592 SetHucBrcUpdateConstData, 593 *hevcSlcParams, 594 slcCount, 595 m_hcpWeightOffsetStateCmdSize, 596 currentLocation, 597 *hucConstData); 598 599 // HCP_SLICE_STATE cmd 600 hucConstData->Slice[slcCount].SliceState_StartInBytes = (uint16_t)currentLocation; // HCP_WEIGHTOFFSET is not needed 601 currentLocation += m_hcpSliceStateCmdSize; 602 603 // VDENC_WEIGHT_OFFSETS_STATE cmd 604 hucConstData->Slice[slcCount].VdencWeightOffset_StartInBytes // VdencWeightOffset cmd is the last one expect BatchBufferEnd cmd 605 = (uint16_t)(baseLocation + hucConstData->Slice[slcCount].SizeOfCMDs - m_vdencWeightOffsetStateCmdSize - m_miBatchBufferEndCmdSize - m_alignSize[slcCount]); 606 607 currentLocation += m_miBatchBufferEndCmdSize; 608 609 // logic from PakInsertObject cmd 610 uint32_t bitSize = (m_basicFeature->m_hevcSeqParams->SliceSizeControl) ? (hevcSlcParams->BitLengthSliceHeaderStartingPortion) : slcData[slcCount].BitSize; // 40 for HEVC VDEnc Dynamic Slice 611 uint32_t byteSize = (bitSize + 7) >> 3; 612 uint32_t sliceHeaderSizeInBytes = (bitSize + 7) >> 3; 613 // 1st PakInsertObject cmd with AU, SPS, PPS headers only exists for the first slice 614 if (slcCount == 0) 615 { 616 // assumes that there is no 3rd PakInsertObject cmd for SSC 617 currentLocation += m_1stPakInsertObjectCmdSize; 618 } 619 620 hucConstData->Slice[slcCount].SliceHeaderPIO_StartInBytes = (uint16_t)currentLocation; 621 622 // HuC FW requires true slice header size in bits without byte alignment 623 hucConstData->Slice[slcCount].SliceHeader_SizeInBits = (uint16_t)(sliceHeaderSizeInBytes * 8); 624 if (!m_pipeline->IsFirstPass()) 625 { 626 PBSBuffer bsBuffer = &(m_basicFeature->m_bsBuffer); 627 ENCODE_CHK_NULL_RETURN(bsBuffer); 628 ENCODE_CHK_NULL_RETURN(bsBuffer->pBase); 629 uint8_t *sliceHeaderLastByte = (uint8_t*)(bsBuffer->pBase + slcData[slcCount].SliceOffset + sliceHeaderSizeInBytes - 1); 630 for (auto i = 0; i < 8; i++) 631 { 632 uint8_t mask = 1 << i; 633 if (*sliceHeaderLastByte & mask) 634 { 635 hucConstData->Slice[slcCount].SliceHeader_SizeInBits -= (i + 1); 636 break; 637 } 638 } 639 } 640 641 baseLocation += hucConstData->Slice[slcCount].SizeOfCMDs; 642 currentLocation = baseLocation; 643 } 644 645 m_allocator->UnLock(const_cast<MOS_RESOURCE*>(&m_vdencBrcConstDataBuffer[m_pipeline->m_currRecycledBufIdx])); 646 647 return eStatus; 648 } 649 Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)650 MOS_STATUS HucBrcUpdatePkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase) 651 { 652 ENCODE_FUNC_CALL(); 653 654 ENCODE_CHK_NULL_RETURN(m_basicFeature); 655 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf); 656 657 ENCODE_CHK_STATUS_RETURN(SetTcbrcMode()); 658 ENCODE_CHK_STATUS_RETURN(ConstructBatchBufferHuCBRC(&m_vdencReadBatchBuffer[m_pipeline->m_currRecycledBufIdx][m_pipeline->GetCurrentPass()])); 659 660 bool firstTaskInPhase = packetPhase & firstPacket; 661 bool requestProlog = false; 662 663 auto brcFeature = dynamic_cast<HEVCEncodeBRC *>(m_featureManager->GetFeature(HevcFeatureIDs::hevcBrcFeature)); 664 ENCODE_CHK_NULL_RETURN(brcFeature); 665 666 uint16_t perfTag = m_pipeline->IsFirstPass() ? CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE : CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE_SECOND_PASS; 667 uint16_t pictureType = m_basicFeature->m_pictureCodingType; 668 if (m_basicFeature->m_pictureCodingType == B_TYPE && m_basicFeature->m_ref.IsLowDelay()) 669 { 670 pictureType = 0; 671 } 672 SetPerfTag(perfTag, (uint16_t)m_basicFeature->m_mode, pictureType); 673 674 if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase) 675 { 676 // Send command buffer header at the beginning (OS dependent) 677 requestProlog = true; 678 } 679 680 ENCODE_CHK_STATUS_RETURN(Execute(commandBuffer, true, requestProlog, BRC_UPDATE)); 681 682 #if _SW_BRC 683 if (!m_swBrc || !m_swBrc->SwBrcEnabled()) 684 { 685 #endif 686 // Write HUC_STATUS mask: DW1 (mask value) 687 auto &storeDataParams = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)(); 688 storeDataParams = {}; 689 storeDataParams.pOsResource = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0); 690 storeDataParams.dwResourceOffset = sizeof(uint32_t); 691 storeDataParams.dwValue = CODECHAL_VDENC_HEVC_BRC_HUC_STATUS_REENCODE_MASK; 692 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(commandBuffer)); 693 694 // store HUC_STATUS register: DW0 (actual value) 695 ENCODE_CHK_COND_RETURN((m_vdboxIndex > MHW_VDBOX_NODE_1), "ERROR - vdbox index exceed the maximum"); 696 auto mmioRegisters = m_hucItf->GetMmioRegisters(m_vdboxIndex); 697 auto &storeRegParams = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)(); 698 storeDataParams = {}; 699 storeRegParams.presStoreBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0); 700 storeRegParams.dwOffset = 0; 701 storeRegParams.dwRegister = mmioRegisters->hucStatusRegOffset; 702 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(commandBuffer)); 703 #if _SW_BRC 704 } 705 #endif 706 707 return MOS_STATUS_SUCCESS; 708 } 709 ConstructBatchBufferHuCBRC(PMOS_RESOURCE batchBuffer)710 MOS_STATUS HucBrcUpdatePkt::ConstructBatchBufferHuCBRC(PMOS_RESOURCE batchBuffer) 711 { 712 ENCODE_FUNC_CALL(); 713 714 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 715 716 ENCODE_CHK_NULL_RETURN(batchBuffer); 717 718 m_batchbufferAddr = (uint8_t *)m_allocator->LockResourceForWrite(batchBuffer); 719 ENCODE_CHK_NULL_RETURN(m_batchbufferAddr); 720 721 ENCODE_CHK_STATUS_RETURN(ConstructGroup1Cmds()); 722 ENCODE_CHK_STATUS_RETURN(ConstructGroup2Cmds()); 723 ENCODE_CHK_STATUS_RETURN(ConstructGroup3Cmds()); 724 725 m_allocator->UnLock(batchBuffer); 726 727 return eStatus; 728 } 729 ConstructGroup1Cmds()730 MOS_STATUS HucBrcUpdatePkt::ConstructGroup1Cmds() 731 { 732 ENCODE_FUNC_CALL(); 733 734 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 735 736 MOS_COMMAND_BUFFER constructedCmdBuf; 737 MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf)); 738 constructedCmdBuf.pCmdBase = constructedCmdBuf.pCmdPtr = (uint32_t *)m_batchbufferAddr; 739 constructedCmdBuf.iRemaining = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 740 741 // 1st Group : PIPE_MODE_SELECT 742 // set PIPE_MODE_SELECT command 743 // This is not needed for GEN11/GEN12 as single pass SAO is supported 744 // for Gen11+, we need to add MFX wait for both KIN and VRT before and after HCP Pipemode select... 745 auto &mfxWaitParams = m_miItf->MHW_GETPAR_F(MFX_WAIT)(); 746 mfxWaitParams = {}; 747 mfxWaitParams.iStallVdboxPipeline = true; 748 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&constructedCmdBuf)); 749 750 SETPAR_AND_ADDCMD(HCP_PIPE_MODE_SELECT, m_hcpItf, &constructedCmdBuf); 751 752 mfxWaitParams = {}; 753 mfxWaitParams.iStallVdboxPipeline = true; 754 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&constructedCmdBuf)); 755 756 MHW_BATCH_BUFFER TempBatchBuffer = {}; 757 TempBatchBuffer.iSize = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 758 TempBatchBuffer.pData = m_batchbufferAddr; 759 760 // set MI_BATCH_BUFFER_END command 761 int32_t cmdBufOffset = constructedCmdBuf.iOffset; 762 763 TempBatchBuffer.iCurrent = constructedCmdBuf.iOffset; 764 TempBatchBuffer.iRemaining = constructedCmdBuf.iRemaining; 765 ENCODE_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(nullptr, &TempBatchBuffer)); 766 constructedCmdBuf.pCmdPtr += (TempBatchBuffer.iCurrent - constructedCmdBuf.iOffset) / 4; 767 constructedCmdBuf.iOffset = TempBatchBuffer.iCurrent; 768 constructedCmdBuf.iRemaining = TempBatchBuffer.iRemaining; 769 770 m_miBatchBufferEndCmdSize = constructedCmdBuf.iOffset - cmdBufOffset; 771 772 uint32_t alignSize = m_hwInterface->m_vdencBatchBuffer1stGroupSize - constructedCmdBuf.iOffset; 773 if (alignSize) 774 { 775 for (uint32_t i = 0; i < (alignSize / 4); i++) 776 { 777 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_NOOP)(&constructedCmdBuf)); 778 } 779 } 780 ENCODE_CHK_COND_RETURN( 781 (m_hwInterface->m_vdencBatchBuffer1stGroupSize != constructedCmdBuf.iOffset), 782 "ERROR - constructed cmd size is mismatch with calculated"); 783 784 return eStatus; 785 } 786 MHW_SETPAR_DECL_SRC(HCP_PIC_STATE,HucBrcUpdatePkt)787 MHW_SETPAR_DECL_SRC(HCP_PIC_STATE, HucBrcUpdatePkt) 788 { 789 params.bNotFirstPass = !m_pipeline->IsFirstPass(); 790 791 return MOS_STATUS_SUCCESS; 792 } 793 ConstructGroup2Cmds()794 MOS_STATUS HucBrcUpdatePkt::ConstructGroup2Cmds() 795 { 796 ENCODE_FUNC_CALL(); 797 798 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 799 800 MOS_COMMAND_BUFFER constructedCmdBuf; 801 MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf)); 802 constructedCmdBuf.pCmdBase = (uint32_t *)m_batchbufferAddr; 803 constructedCmdBuf.iOffset = m_hwInterface->m_vdencBatchBuffer1stGroupSize; 804 constructedCmdBuf.pCmdPtr = constructedCmdBuf.pCmdBase + constructedCmdBuf.iOffset / 4; 805 constructedCmdBuf.iRemaining = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE) - constructedCmdBuf.iOffset; 806 807 SETPAR_AND_ADDCMD(VDENC_CMD1, m_vdencItf, &constructedCmdBuf); 808 m_basicFeature->m_picStateCmdStartInBytes = constructedCmdBuf.iOffset; 809 810 // set HCP_PIC_STATE command 811 SETPAR_AND_ADDCMD(HCP_PIC_STATE, m_hcpItf, &constructedCmdBuf); 812 m_cmd2StartInBytes = constructedCmdBuf.iOffset; 813 814 SETPAR_AND_ADDCMD(VDENC_CMD2, m_vdencItf, &constructedCmdBuf); 815 816 // set MI_BATCH_BUFFER_END command 817 MHW_BATCH_BUFFER TempBatchBuffer = {}; 818 TempBatchBuffer.iSize = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 819 TempBatchBuffer.pData = m_batchbufferAddr; 820 821 TempBatchBuffer.iCurrent = constructedCmdBuf.iOffset; 822 TempBatchBuffer.iRemaining = constructedCmdBuf.iRemaining; 823 ENCODE_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(nullptr, &TempBatchBuffer)); 824 constructedCmdBuf.pCmdPtr += (TempBatchBuffer.iCurrent - constructedCmdBuf.iOffset) / 4; 825 constructedCmdBuf.iOffset = TempBatchBuffer.iCurrent; 826 constructedCmdBuf.iRemaining = TempBatchBuffer.iRemaining; 827 828 uint32_t alignSize = m_hwInterface->m_vdencBatchBuffer2ndGroupSize + m_hwInterface->m_vdencBatchBuffer1stGroupSize - constructedCmdBuf.iOffset; 829 if (alignSize) 830 { 831 for (uint32_t i = 0; i < (alignSize / 4); i++) 832 { 833 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_NOOP)(&constructedCmdBuf)); 834 } 835 } 836 ENCODE_CHK_COND_RETURN( 837 (m_hwInterface->m_vdencBatchBuffer2ndGroupSize + m_hwInterface->m_vdencBatchBuffer1stGroupSize != constructedCmdBuf.iOffset), 838 "ERROR - constructed cmd size is mismatch with calculated"); 839 840 return eStatus; 841 } 842 ConstructGroup3Cmds()843 MOS_STATUS HucBrcUpdatePkt::ConstructGroup3Cmds() 844 { 845 ENCODE_FUNC_CALL(); 846 847 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 848 uint32_t cmdBufOffset = 0; 849 850 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_slcData); 851 852 MOS_COMMAND_BUFFER constructedCmdBuf; 853 MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf)); 854 constructedCmdBuf.pCmdBase = (uint32_t *)m_batchbufferAddr; 855 constructedCmdBuf.iOffset = m_hwInterface->m_vdencBatchBuffer1stGroupSize + m_hwInterface->m_vdencBatchBuffer2ndGroupSize; 856 constructedCmdBuf.pCmdPtr = constructedCmdBuf.pCmdBase + constructedCmdBuf.iOffset / 4; 857 constructedCmdBuf.iRemaining = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE) - constructedCmdBuf.iOffset; 858 859 // slice level cmds for each slice 860 PCODEC_ENCODER_SLCDATA slcData = m_basicFeature->m_slcData; 861 for (uint32_t startLCU = 0, slcCount = 0; slcCount < m_basicFeature->m_numSlices; slcCount++) 862 { 863 m_basicFeature->m_curNumSlices = slcCount; 864 m_basicFeature->m_lastSliceInTile = true; 865 866 if (m_pipeline->IsFirstPass()) 867 { 868 slcData[slcCount].CmdOffset = startLCU * (m_hcpItf->GetHcpPakObjSize()) * sizeof(uint32_t); 869 } 870 871 RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, SetCurrentTileFromSliceIndex, slcCount, m_pipeline); 872 873 m_basicFeature->m_vdencBatchBufferPerSliceVarSize[slcCount] = 0; 874 m_basicFeature->m_vdencBatchBufferPerSlicePart2Size[slcCount] = 0; 875 876 // set HCP_WEIGHTOFFSET_STATE command 877 // This slice level command is issued, if the weighted_pred_flag or weighted_bipred_flag equals one. 878 // If zero, then this command is not issued. 879 AddAllCmds_HCP_WEIGHTOFFSET_STATE(&constructedCmdBuf); 880 881 // set HCP_SLICE_STATE command 882 cmdBufOffset = constructedCmdBuf.iOffset; 883 SETPAR_AND_ADDCMD(HCP_SLICE_STATE, m_hcpItf, &constructedCmdBuf); 884 m_hcpSliceStateCmdSize = constructedCmdBuf.iOffset - cmdBufOffset; 885 886 // set MI_BATCH_BUFFER_END command 887 MHW_BATCH_BUFFER TempBatchBuffer = {}; 888 TempBatchBuffer.iSize = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 889 TempBatchBuffer.pData = m_batchbufferAddr; 890 891 TempBatchBuffer.iCurrent = constructedCmdBuf.iOffset; 892 TempBatchBuffer.iRemaining = constructedCmdBuf.iRemaining; 893 ENCODE_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(nullptr, &TempBatchBuffer)); 894 constructedCmdBuf.pCmdPtr += (TempBatchBuffer.iCurrent - constructedCmdBuf.iOffset) / 4; 895 constructedCmdBuf.iOffset = TempBatchBuffer.iCurrent; 896 constructedCmdBuf.iRemaining = TempBatchBuffer.iRemaining; 897 898 m_basicFeature->m_vdencBatchBufferPerSlicePart2Start[slcCount] = constructedCmdBuf.iOffset; 899 900 AddAllCmds_HCP_PAK_INSERT_OBJECT_SLICE(&constructedCmdBuf); 901 902 cmdBufOffset = constructedCmdBuf.iOffset; 903 SETPAR_AND_ADDCMD(VDENC_WEIGHTSOFFSETS_STATE, m_vdencItf, &constructedCmdBuf); 904 m_vdencWeightOffsetStateCmdSize = constructedCmdBuf.iOffset - cmdBufOffset; 905 906 // set MI_BATCH_BUFFER_END command 907 TempBatchBuffer = {}; 908 TempBatchBuffer.iSize = MOS_ALIGN_CEIL(m_hwInterface->m_vdencReadBatchBufferSize, CODECHAL_PAGE_SIZE); 909 TempBatchBuffer.pData = m_batchbufferAddr; 910 911 TempBatchBuffer.iCurrent = constructedCmdBuf.iOffset; 912 TempBatchBuffer.iRemaining = constructedCmdBuf.iRemaining; 913 ENCODE_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(nullptr, &TempBatchBuffer)); 914 constructedCmdBuf.pCmdPtr += (TempBatchBuffer.iCurrent - constructedCmdBuf.iOffset) / 4; 915 constructedCmdBuf.iOffset = TempBatchBuffer.iCurrent; 916 constructedCmdBuf.iRemaining = TempBatchBuffer.iRemaining; 917 918 m_alignSize[slcCount] = MOS_ALIGN_CEIL(constructedCmdBuf.iOffset, 64) - constructedCmdBuf.iOffset; 919 if (m_alignSize[slcCount] > 0) 920 { 921 for (uint32_t i = 0; i < (m_alignSize[slcCount] / 4); i++) 922 { 923 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_NOOP)(&constructedCmdBuf)); 924 } 925 } 926 m_basicFeature->m_vdencBatchBufferPerSliceVarSize[slcCount] += m_alignSize[slcCount]; 927 m_basicFeature->m_vdencBatchBufferPerSlicePart2Size[slcCount] = constructedCmdBuf.iOffset - m_basicFeature->m_vdencBatchBufferPerSlicePart2Start[slcCount]; 928 startLCU += m_basicFeature->m_hevcSliceParams[slcCount].NumLCUsInSlice; 929 } 930 931 m_slbDataSizeInBytes = constructedCmdBuf.iOffset; 932 933 return eStatus; 934 } 935 GetMaxAllowedSlices(uint8_t levelIdc) const936 uint32_t HucBrcUpdatePkt::GetMaxAllowedSlices(uint8_t levelIdc) const 937 { 938 uint32_t maxAllowedNumSlices = 0; 939 940 switch (levelIdc) 941 { 942 case 10: 943 case 20: 944 maxAllowedNumSlices = 16; 945 break; 946 case 21: 947 maxAllowedNumSlices = 20; 948 break; 949 case 30: 950 maxAllowedNumSlices = 30; 951 break; 952 case 31: 953 maxAllowedNumSlices = 40; 954 break; 955 case 40: 956 case 41: 957 maxAllowedNumSlices = 75; 958 break; 959 case 50: 960 case 51: 961 case 52: 962 maxAllowedNumSlices = 200; 963 break; 964 case 60: 965 case 61: 966 case 62: 967 maxAllowedNumSlices = 600; 968 break; 969 default: 970 maxAllowedNumSlices = 0; 971 break; 972 } 973 974 return maxAllowedNumSlices; 975 } 976 977 #if USE_CODECHAL_DEBUG_TOOL DumpHucBrcUpdate(bool isInput)978 MOS_STATUS HucBrcUpdatePkt::DumpHucBrcUpdate(bool isInput) 979 { 980 ENCODE_FUNC_CALL(); 981 982 CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface(); 983 ENCODE_CHK_NULL_RETURN(debugInterface); 984 985 auto virtualAddrParams = m_hucItf->MHW_GETPAR_F(HUC_VIRTUAL_ADDR_STATE)(); 986 int32_t currentPass = m_pipeline->GetCurrentPass(); 987 988 if (isInput) 989 { 990 //Dump HucBrcUpdate input buffers 991 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpHucDmem( 992 &m_vdencBrcUpdateDmemBuffer[m_pipeline->m_currRecycledBufIdx][currentPass], 993 m_vdencBrcUpdateDmemBufferSize, 994 currentPass, 995 hucRegionDumpUpdate)); 996 997 // Region 1 - VDENC Statistics Buffer dump 998 HevcBasicFeature *hevcBasicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 999 ENCODE_CHK_NULL_RETURN(hevcBasicFeature); 1000 uint32_t vdencBRCStatsBufferSize = 1216; 1001 uint32_t size = MOS_ALIGN_CEIL(vdencBRCStatsBufferSize * hevcBasicFeature->m_maxTileNumber, CODECHAL_PAGE_SIZE); 1002 ENCODE_CHK_STATUS_RETURN(DumpRegion(1, "_VdencStats", true, hucRegionDumpUpdate, size)); 1003 1004 // Region 2 - PAK Statistics Buffer dump 1005 size = MOS_ALIGN_CEIL(HevcBasicFeature::m_sizeOfHcpPakFrameStats * hevcBasicFeature->m_maxTileNumber, CODECHAL_PAGE_SIZE); 1006 ENCODE_CHK_STATUS_RETURN(DumpRegion(2, "_PakStats", true, hucRegionDumpUpdate, size)); 1007 1008 // Region 3 - Input SLB Buffer 1009 ENCODE_CHK_STATUS_RETURN(DumpRegion(3, "_Slb", true, hucRegionDumpUpdate, m_hwInterface->m_vdencReadBatchBufferSize)); 1010 1011 // Region 4 - Constant Data Buffer dump 1012 ENCODE_CHK_STATUS_RETURN(DumpRegion(4, "_ConstData", true, hucRegionDumpUpdate, m_vdencBrcConstDataBufferSize)); 1013 1014 // Region 7 - Slice Stat Streamout (Input) 1015 ENCODE_CHK_STATUS_RETURN(DumpRegion(7, "_SliceStat", true, hucRegionDumpUpdate, CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6 * CODECHAL_CACHELINE_SIZE)); 1016 1017 // Region 8 - PAK MMIO Buffer dump 1018 ENCODE_CHK_STATUS_RETURN(DumpRegion(8, "_PakMmio", true, hucRegionDumpUpdate, sizeof(CodechalVdencHevcPakInfo))); 1019 1020 // Region 9 - Streamin Buffer for ROI (Input) 1021 auto streamInBufferSize = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32) * (MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 64) / 32) * CODECHAL_CACHELINE_SIZE; 1022 ENCODE_CHK_STATUS_RETURN(DumpRegion(9, "_RoiStreamin", true, hucRegionDumpUpdate, streamInBufferSize)); 1023 1024 // Region 10 - Delta QP for ROI Buffer 1025 auto vdencDeltaQpBuffer = virtualAddrParams.regionParams[10].presRegion; 1026 if (vdencDeltaQpBuffer) 1027 { 1028 ENCODE_CHK_STATUS_RETURN(DumpRegion(10, "_DeltaQp", true, hucRegionDumpUpdate, vdencDeltaQpBuffer->iSize)); 1029 } 1030 } 1031 else 1032 { 1033 // Region 5 - Output SLB Buffer 1034 ENCODE_CHK_STATUS_RETURN(DumpRegion(5, "_Slb", false, hucRegionDumpUpdate, m_hwInterface->m_vdenc2ndLevelBatchBufferSize)); 1035 1036 // Region 11 - Output ROI Streamin Buffer 1037 auto vdencOutputROIStreaminBuffer = virtualAddrParams.regionParams[11].presRegion; 1038 if (vdencOutputROIStreaminBuffer) 1039 { 1040 ENCODE_CHK_STATUS_RETURN(DumpRegion(11, "_RoiStreamin", false, hucRegionDumpUpdate, vdencOutputROIStreaminBuffer->iSize)); 1041 } 1042 } 1043 1044 // Region 0 - History Buffer dump (Input/Output) 1045 ENCODE_CHK_STATUS_RETURN(DumpRegion(0, "_History", isInput, hucRegionDumpUpdate)); 1046 1047 // Region 6 - Data from Pictures for Weighted Prediction (Input/Output) 1048 ENCODE_CHK_STATUS_RETURN(DumpRegion(6, "_PicsData", isInput, hucRegionDumpUpdate, CODECHAL_PAGE_SIZE * 4)); 1049 1050 // Region 15 - Debug Output 1051 auto debugBuffer = virtualAddrParams.regionParams[15].presRegion; 1052 if (debugBuffer) 1053 { 1054 ENCODE_CHK_STATUS_RETURN(DumpRegion(15, "_Debug", isInput, hucRegionDumpUpdate, debugBuffer->iSize)); 1055 } 1056 1057 return MOS_STATUS_SUCCESS; 1058 } 1059 DumpInput()1060 MOS_STATUS HucBrcUpdatePkt::DumpInput() 1061 { 1062 ENCODE_FUNC_CALL(); 1063 DumpHucBrcUpdate(true); 1064 return MOS_STATUS_SUCCESS; 1065 } 1066 #endif 1067 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT,HucBrcUpdatePkt)1068 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT, HucBrcUpdatePkt) 1069 { 1070 params.codecStandardSelect = CodecHal_GetStandardFromMode(m_basicFeature->m_mode) - CODECHAL_HCP_BASE; 1071 params.bStreamOutEnabled = true; 1072 params.bVdencEnabled = true; 1073 params.multiEngineMode = MHW_VDBOX_HCP_MULTI_ENGINE_MODE_FE_LEGACY; 1074 params.pipeWorkMode = MHW_VDBOX_HCP_PIPE_WORK_MODE_LEGACY; 1075 1076 MhwCpInterface *cpInterface = m_hwInterface->GetCpInterface(); 1077 bool twoPassScalable = params.multiEngineMode != MHW_VDBOX_HCP_MULTI_ENGINE_MODE_FE_LEGACY && !params.bTileBasedReplayMode; 1078 1079 ENCODE_CHK_NULL_RETURN(cpInterface); 1080 params.setProtectionSettings = [=](uint32_t *data) { return cpInterface->SetProtectionSettingsForHcpPipeModeSelect(data, twoPassScalable); }; 1081 1082 return MOS_STATUS_SUCCESS; 1083 } 1084 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE,HucBrcUpdatePkt)1085 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE, HucBrcUpdatePkt) 1086 { 1087 ENCODE_FUNC_CALL(); 1088 1089 params.intrareffetchdisable = m_basicFeature->m_pakOnlyPass; 1090 1091 return MOS_STATUS_SUCCESS; 1092 } 1093 AddAllCmds_HCP_PAK_INSERT_OBJECT_SLICE(PMOS_COMMAND_BUFFER cmdBuffer) const1094 MOS_STATUS HucBrcUpdatePkt::AddAllCmds_HCP_PAK_INSERT_OBJECT_SLICE(PMOS_COMMAND_BUFFER cmdBuffer) const 1095 { 1096 ENCODE_FUNC_CALL(); 1097 1098 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1099 1100 auto ¶ms = m_hcpItf->MHW_GETPAR_F(HCP_PAK_INSERT_OBJECT)(); 1101 1102 uint32_t cmdBufOffset = 0; 1103 uint32_t bitSize = 0; 1104 uint32_t offSet = 0; 1105 PCODECHAL_NAL_UNIT_PARAMS *ppNalUnitParams = (CODECHAL_NAL_UNIT_PARAMS **)m_basicFeature->m_nalUnitParams; 1106 PBSBuffer pBsBuffer = &(m_basicFeature->m_bsBuffer); 1107 1108 params = {}; 1109 // Insert slice header 1110 params.bLastHeader = true; 1111 params.bEmulationByteBitsInsert = true; 1112 1113 // App does the slice header packing, set the skip count passed by the app 1114 PCODEC_ENCODER_SLCDATA slcData = m_basicFeature->m_slcData; 1115 uint32_t currSlcIdx = m_basicFeature->m_curNumSlices; 1116 1117 params.uiSkipEmulationCheckCount = slcData[currSlcIdx].SkipEmulationByteCount; 1118 bitSize = slcData[currSlcIdx].BitSize; 1119 offSet = slcData[currSlcIdx].SliceOffset; 1120 1121 if (m_basicFeature->m_hevcSeqParams->SliceSizeControl) 1122 { 1123 params.bLastHeader = false; 1124 params.bEmulationByteBitsInsert = false; 1125 bitSize = m_basicFeature->m_hevcSliceParams->BitLengthSliceHeaderStartingPortion; 1126 params.bResetBitstreamStartingPos = true; 1127 params.dwPadding = (MOS_ALIGN_CEIL((bitSize + 7) >> 3, sizeof(uint32_t))) / sizeof(uint32_t); 1128 params.dataBitsInLastDw = bitSize % 32; 1129 if (params.dataBitsInLastDw == 0) 1130 { 1131 params.dataBitsInLastDw = 32; 1132 } 1133 1134 m_hcpItf->MHW_ADDCMD_F(HCP_PAK_INSERT_OBJECT)(cmdBuffer); 1135 uint32_t byteSize = (bitSize + 7) >> 3; 1136 m_basicFeature->m_vdencBatchBufferPerSliceVarSize[m_basicFeature->m_curNumSlices] += (MOS_ALIGN_CEIL(byteSize, sizeof(uint32_t))) / sizeof(uint32_t) * 4; 1137 if (byteSize) 1138 { 1139 MHW_MI_CHK_NULL(pBsBuffer); 1140 MHW_MI_CHK_NULL(pBsBuffer->pBase); 1141 uint8_t *data = (uint8_t *)(pBsBuffer->pBase + offSet); 1142 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize)); 1143 } 1144 1145 // Send HCP_PAK_INSERT_OBJ command. For dynamic slice, we are skipping the beginning part of slice header. 1146 params.bLastHeader = true; 1147 bitSize = slcData[currSlcIdx].BitSize - m_basicFeature->m_hevcSliceParams->BitLengthSliceHeaderStartingPortion; 1148 offSet += ((m_basicFeature->m_hevcSliceParams->BitLengthSliceHeaderStartingPortion + 7) / 8); // Skips the first 5 bytes which is Start Code + Nal Unit Header 1149 params.dwPadding = (MOS_ALIGN_CEIL((bitSize + 7) >> 3, sizeof(uint32_t))) / sizeof(uint32_t); 1150 params.dataBitsInLastDw = bitSize % 32; 1151 if (params.dataBitsInLastDw == 0) 1152 { 1153 params.dataBitsInLastDw = 32; 1154 } 1155 params.bResetBitstreamStartingPos = true; 1156 cmdBufOffset = cmdBuffer->iOffset; 1157 m_hcpItf->MHW_ADDCMD_F(HCP_PAK_INSERT_OBJECT)(cmdBuffer); 1158 byteSize = (bitSize + 7) >> 3; 1159 if (byteSize) 1160 { 1161 MHW_MI_CHK_NULL(pBsBuffer); 1162 MHW_MI_CHK_NULL(pBsBuffer->pBase); 1163 uint8_t *data = (uint8_t *)(pBsBuffer->pBase + offSet); 1164 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize)); 1165 } 1166 m_basicFeature->m_vdencBatchBufferPerSliceVarSize[m_basicFeature->m_curNumSlices] += (cmdBuffer->iOffset - cmdBufOffset); 1167 } 1168 else 1169 { 1170 params.dwPadding = (MOS_ALIGN_CEIL((bitSize + 7) >> 3, sizeof(uint32_t))) / sizeof(uint32_t); 1171 params.dataBitsInLastDw = bitSize % 32; 1172 if (params.dataBitsInLastDw == 0) 1173 { 1174 params.dataBitsInLastDw = 32; 1175 } 1176 m_hcpItf->MHW_ADDCMD_F(HCP_PAK_INSERT_OBJECT)(cmdBuffer); 1177 uint32_t byteSize = (bitSize + 7) >> 3; 1178 m_basicFeature->m_vdencBatchBufferPerSliceVarSize[m_basicFeature->m_curNumSlices] += (MOS_ALIGN_CEIL(byteSize, sizeof(uint32_t))) / sizeof(uint32_t) * 4; 1179 if (byteSize) 1180 { 1181 MHW_MI_CHK_NULL(pBsBuffer); 1182 MHW_MI_CHK_NULL(pBsBuffer->pBase); 1183 uint8_t *data = (uint8_t *)(pBsBuffer->pBase + offSet); 1184 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize)); 1185 } 1186 } 1187 1188 return MOS_STATUS_SUCCESS; 1189 } 1190 AddAllCmds_HCP_WEIGHTOFFSET_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const1191 MOS_STATUS HucBrcUpdatePkt::AddAllCmds_HCP_WEIGHTOFFSET_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const 1192 { 1193 ENCODE_FUNC_CALL(); 1194 1195 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1196 1197 auto ¶ms = m_hcpItf->MHW_GETPAR_F(HCP_WEIGHTOFFSET_STATE)(); 1198 params = {}; 1199 auto wpFeature = dynamic_cast<HevcVdencWeightedPred *>(m_featureManager->GetFeature(HevcFeatureIDs::hevcVdencWpFeature)); 1200 ENCODE_CHK_NULL_RETURN(wpFeature); 1201 1202 if (wpFeature->IsEnabled() && m_basicFeature->m_hevcPicParams->bEnableGPUWeightedPrediction) 1203 { 1204 MHW_CHK_STATUS_RETURN(wpFeature->MHW_SETPAR_F(HCP_WEIGHTOFFSET_STATE)(params)); 1205 1206 uint32_t cmdBufOffset = 0; 1207 // 1st HCP_WEIGHTOFFSET_STATE cmd - P & B 1208 if (m_basicFeature->m_hevcSliceParams->slice_type == encodeHevcPSlice || m_basicFeature->m_hevcSliceParams->slice_type == encodeHevcBSlice) 1209 { 1210 params.ucList = LIST_0; 1211 cmdBufOffset = cmdBuffer->iOffset; 1212 m_hcpItf->MHW_ADDCMD_F(HCP_WEIGHTOFFSET_STATE)(cmdBuffer); 1213 m_hcpWeightOffsetStateCmdSize = cmdBuffer->iOffset - cmdBufOffset; 1214 // 1st HcpWeightOffset cmd is not always inserted (except weighted prediction + P, B slices) 1215 m_basicFeature->m_vdencBatchBufferPerSliceVarSize[m_basicFeature->m_curNumSlices] += m_hcpWeightOffsetStateCmdSize; 1216 } 1217 1218 // 2nd HCP_WEIGHTOFFSET_STATE cmd - B only 1219 if (m_basicFeature->m_hevcSliceParams->slice_type == encodeHevcBSlice) 1220 { 1221 params.ucList = LIST_1; 1222 cmdBufOffset = cmdBuffer->iOffset; 1223 m_hcpItf->MHW_ADDCMD_F(HCP_WEIGHTOFFSET_STATE)(cmdBuffer); 1224 m_hcpWeightOffsetStateCmdSize = cmdBuffer->iOffset - cmdBufOffset; 1225 // 1st HcpWeightOffset cmd is not always inserted (except weighted prediction + P, B slices) 1226 m_basicFeature->m_vdencBatchBufferPerSliceVarSize[m_basicFeature->m_curNumSlices] += m_hcpWeightOffsetStateCmdSize; 1227 } 1228 } 1229 1230 return MOS_STATUS_SUCCESS; 1231 } 1232 SetTcbrcMode()1233 MOS_STATUS HucBrcUpdatePkt::SetTcbrcMode() 1234 { 1235 ENCODE_FUNC_CALL(); 1236 ENCODE_CHK_NULL_RETURN(m_basicFeature); 1237 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_hevcSeqParams); 1238 ENCODE_CHK_NULL_RETURN(m_hwInterface); 1239 1240 if (m_basicFeature->m_newSeq) 1241 { 1242 //tcbrc mode set by scenarioInfo 1243 uint8_t tcbrcQualityBoostFromScenario = 0; 1244 switch (m_basicFeature->m_hevcSeqParams->ScenarioInfo) 1245 { 1246 case ESCENARIO_REMOTEGAMING: 1247 tcbrcQualityBoostFromScenario = 0; 1248 break; 1249 case ESCENARIO_VIDEOCONFERENCE: 1250 tcbrcQualityBoostFromScenario = 1; 1251 break; 1252 default: 1253 tcbrcQualityBoostFromScenario = 0; 1254 } 1255 1256 #if (_DEBUG || _RELEASE_INTERNAL) 1257 //tcbrc mode override by reg key 1258 uint8_t tcbrcQualityBoostFromRegkey = 3; 1259 1260 MediaUserSetting::Value outValue; 1261 ReadUserSetting(m_userSettingPtr, 1262 outValue, 1263 "TCBRC Quality Boost Mode", 1264 MediaUserSetting::Group::Sequence); 1265 tcbrcQualityBoostFromRegkey = static_cast<uint8_t>(outValue.Get<int32_t>()); 1266 //if FrameSizeBoostForSceneChange is set by regkey, then override it 1267 if (tcbrcQualityBoostFromRegkey == 0 || tcbrcQualityBoostFromRegkey == 1 || tcbrcQualityBoostFromRegkey == 2) 1268 { 1269 m_tcbrcQualityBoost = tcbrcQualityBoostFromRegkey; 1270 ENCODE_VERBOSEMESSAGE("TCBRC FrameSizeBoostForSceneChange is override by regkey!"); 1271 } 1272 else 1273 #endif 1274 { 1275 m_tcbrcQualityBoost = tcbrcQualityBoostFromScenario; 1276 } 1277 #if (_DEBUG || _RELEASE_INTERNAL) 1278 ReportUserSettingForDebug(m_userSettingPtr, 1279 "TCBRC Quality Boost Mode", 1280 m_tcbrcQualityBoost, 1281 MediaUserSetting::Group::Sequence); 1282 #endif 1283 } 1284 return MOS_STATUS_SUCCESS; 1285 } 1286 1287 } 1288