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 //! \file encode_hevc_brc.cpp 24 //! \brief Defines the common interface for hevc brc features 25 //! 26 27 #include "encode_hevc_basic_feature.h" 28 #include "encode_hevc_brc.h" 29 #include "encode_hevc_vdenc_feature_manager.h" 30 #include "encode_hevc_vdenc_const_settings.h" 31 #include "encode_huc_brc_init_packet.h" 32 #include "encode_huc_brc_update_packet.h" 33 namespace encode 34 { HEVCEncodeBRC(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)35 HEVCEncodeBRC::HEVCEncodeBRC( 36 MediaFeatureManager *featureManager, 37 EncodeAllocator *allocator, 38 CodechalHwInterfaceNext *hwInterface, 39 void *constSettings) : 40 MediaFeature(constSettings, hwInterface ? hwInterface->GetOsInterface() : nullptr), 41 m_hwInterface(hwInterface), 42 m_allocator(allocator) 43 { 44 m_featureManager = featureManager; 45 // can be optimized after move encode parameter to feature manager. 46 auto encFeatureManager = dynamic_cast<EncodeHevcVdencFeatureManager*>(featureManager); 47 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager); 48 49 m_basicFeature = dynamic_cast<HevcBasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature)); 50 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature); 51 52 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hwInterface); 53 } 54 ~HEVCEncodeBRC()55 HEVCEncodeBRC::~HEVCEncodeBRC() 56 { 57 FreeBrcResources(); 58 } 59 Init(void * setting)60 MOS_STATUS HEVCEncodeBRC::Init(void *setting) 61 { 62 ENCODE_FUNC_CALL(); 63 64 #if (_DEBUG || _RELEASE_INTERNAL) 65 MediaUserSetting::Value outValue; 66 ReadUserSettingForDebug( 67 m_userSettingPtr, 68 outValue, 69 "FAST PAK ENABLE", 70 MediaUserSetting::Group::Sequence); 71 m_fastPakEnable = outValue.Get<bool>(); 72 73 ReadUserSetting( 74 m_userSettingPtr, 75 outValue, 76 "HEVC VDEnc ACQP Enable", 77 MediaUserSetting::Group::Sequence); 78 m_hevcVDEncAcqpEnabled = outValue.Get<bool>(); 79 #endif 80 81 ENCODE_CHK_STATUS_RETURN(AllocateResources()); 82 83 return MOS_STATUS_SUCCESS; 84 } 85 Update(void * params)86 MOS_STATUS HEVCEncodeBRC::Update(void *params) 87 { 88 ENCODE_FUNC_CALL(); 89 ENCODE_CHK_NULL_RETURN(params); 90 91 EncoderParams *encodeParams = (EncoderParams *)params; 92 93 ENCODE_CHK_STATUS_RETURN(SetSequenceStructs()); 94 ENCODE_CHK_STATUS_RETURN(UpdateBrcResources(encodeParams)); 95 96 #if (_DEBUG || _RELEASE_INTERNAL) 97 ReportUserSettingForDebug( 98 m_userSettingPtr, 99 "Encode RateControl Method", 100 m_rcMode, 101 MediaUserSetting::Group::Sequence); 102 ReportUserSettingForDebug( 103 m_userSettingPtr, 104 "HEVC VDEnc ACQP Enable", 105 m_hevcVDEncAcqpEnabled, 106 MediaUserSetting::Group::Sequence); 107 #endif 108 return MOS_STATUS_SUCCESS; 109 } 110 AllocateResources()111 MOS_STATUS HEVCEncodeBRC::AllocateResources() 112 { 113 ENCODE_FUNC_CALL(); 114 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 115 116 ENCODE_CHK_NULL_RETURN(m_allocator); 117 ENCODE_CHK_NULL_RETURN(m_basicFeature); 118 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf); 119 ENCODE_CHK_NULL_RETURN(m_hwInterface); 120 ENCODE_CHK_NULL_RETURN(m_hwInterface->GetOsInterface()); 121 122 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 123 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 124 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 125 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 126 allocParamsForBufferLinear.Format = Format_Buffer; 127 128 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(CodechalVdencHevcPakInfo), CODECHAL_PAGE_SIZE); 129 allocParamsForBufferLinear.pBufName = "VDENC BRC PakInfo"; 130 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 131 m_basicFeature->m_recycleBuf->RegisterResource(PakInfo, allocParamsForBufferLinear, 6); 132 133 // Allocate Frame Statistics Streamout Data Destination Buffer. DW98-100 in HCP PipeBufAddr command 134 HevcBasicFeature *hevcBasicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 135 ENCODE_CHK_NULL_RETURN(hevcBasicFeature); 136 137 // BRC history buffer 138 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_brcHistoryBufSize, CODECHAL_PAGE_SIZE); 139 allocParamsForBufferLinear.pBufName = "VDENC BRC History Buffer"; 140 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 141 m_basicFeature->m_recycleBuf->RegisterResource(VdencBRCHistoryBuffer, allocParamsForBufferLinear, 1); 142 143 for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; j++) 144 { 145 // VDENC uses second level batch buffer 146 MOS_ZeroMemory(&m_vdenc2ndLevelBatchBuffer[j], sizeof(MHW_BATCH_BUFFER)); 147 m_vdenc2ndLevelBatchBuffer[j].bSecondLevel = true; 148 ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb( 149 m_hwInterface->GetOsInterface(), 150 &m_vdenc2ndLevelBatchBuffer[j], 151 nullptr, 152 m_hwInterface->m_vdenc2ndLevelBatchBufferSize)); 153 } 154 155 // Lcu Base Address buffer 156 // HEVC Encoder Mode: Slice size is written to this buffer when slice size conformance is enabled. 157 // 1 CL (= 16 DWs = 64 bytes) per slice * Maximum number of slices in a frame. 158 // Align to page for HUC requirement 159 const uint32_t picWidthInMinLCU = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameWidth, CODECHAL_HEVC_MIN_LCU_SIZE); //assume smallest LCU to get max width 160 const uint32_t picHeightInMinLCU = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameHeight, CODECHAL_HEVC_MIN_LCU_SIZE); //assume smallest LCU to get max height 161 uint32_t maxLcu = picWidthInMinLCU * picHeightInMinLCU; 162 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(maxLcu * CODECHAL_CACHELINE_SIZE, CODECHAL_PAGE_SIZE); 163 allocParamsForBufferLinear.pBufName = "LcuBaseAddressBuffer"; 164 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 165 m_basicFeature->m_recycleBuf->RegisterResource(LcuBaseAddressBuffer, allocParamsForBufferLinear, 1); 166 167 // VDENC BRC PAK MMIO buffer 168 allocParamsForBufferLinear.dwBytes = sizeof(VdencBrcPakMmio); 169 allocParamsForBufferLinear.pBufName = "VDENC BRC PAK MMIO Buffer"; 170 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 171 m_basicFeature->m_recycleBuf->RegisterResource(VdencBrcPakMmioBuffer, allocParamsForBufferLinear, 1); 172 173 // Debug buffer 174 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_brcDebugBufSize, CODECHAL_PAGE_SIZE); 175 allocParamsForBufferLinear.pBufName = "VDENC BRC Debug Buffer"; 176 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 177 m_basicFeature->m_recycleBuf->RegisterResource(VdencBrcDebugBuffer, allocParamsForBufferLinear, 1); 178 179 allocParamsForBufferLinear.dwBytes = HEVC_BRC_PAK_STATISTCS_SIZE; 180 allocParamsForBufferLinear.pBufName = "BRC PAK Statistics Buffer"; 181 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 182 m_basicFeature->m_recycleBuf->RegisterResource(BrcPakStatisticBuffer, allocParamsForBufferLinear, CODECHAL_ENCODE_RECYCLED_BUFFER_NUM); 183 184 for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) 185 { 186 MOS_RESOURCE *allocatedresource = m_basicFeature->m_recycleBuf->GetBuffer(BrcPakStatisticBuffer,i); 187 ENCODE_CHK_NULL_RETURN(allocatedresource); 188 m_vdencBrcBuffers.resBrcPakStatisticBuffer[i] = allocatedresource; 189 } 190 191 m_rdLambdaArray = MOS_NewArray(uint16_t, HUC_QP_RANGE); 192 ENCODE_CHK_NULL_RETURN(m_rdLambdaArray); 193 m_sadLambdaArray = MOS_NewArray(uint16_t, HUC_QP_RANGE); 194 ENCODE_CHK_NULL_RETURN(m_sadLambdaArray); 195 196 return eStatus; 197 } 198 UpdateBrcResources(void * params)199 MOS_STATUS HEVCEncodeBRC::UpdateBrcResources(void *params) 200 { 201 ENCODE_FUNC_CALL(); 202 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 203 204 ENCODE_CHK_NULL_RETURN(m_allocator); 205 ENCODE_CHK_NULL_RETURN(params); 206 207 EncoderParams *encodeParams = (EncoderParams *)params; 208 ENCODE_CHK_NULL_RETURN(encodeParams); 209 210 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams = 211 static_cast<PCODEC_HEVC_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams); 212 ENCODE_CHK_NULL_RETURN(hevcPicParams); 213 214 auto num_tile_rows = hevcPicParams->num_tile_rows_minus1 + 1; 215 auto num_tile_columns = hevcPicParams->num_tile_columns_minus1 + 1; 216 auto num_tiles = num_tile_rows * num_tile_columns; 217 218 if (Mos_ResourceIsNull(&m_resBrcDataBuffer)) 219 { 220 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 221 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 222 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 223 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 224 allocParamsForBufferLinear.Format = Format_Buffer; 225 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(num_tiles * CODECHAL_CACHELINE_SIZE, CODECHAL_PAGE_SIZE); 226 allocParamsForBufferLinear.pBufName = "BRC Data Buffer"; 227 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 228 auto resource = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 229 ENCODE_CHK_NULL_RETURN(resource); 230 m_resBrcDataBuffer = *resource; 231 } 232 // BRC Data Buffer 233 234 return eStatus; 235 } 236 GetBrcDataBuffer(MOS_RESOURCE * & buffer)237 MOS_STATUS HEVCEncodeBRC::GetBrcDataBuffer(MOS_RESOURCE *&buffer) 238 { 239 ENCODE_FUNC_CALL(); 240 buffer = &m_resBrcDataBuffer; 241 return MOS_STATUS_SUCCESS; 242 } 243 SetDmemForUpdate(void * params)244 MOS_STATUS HEVCEncodeBRC::SetDmemForUpdate(void* params) 245 { 246 ENCODE_FUNC_CALL(); 247 ENCODE_CHK_NULL_RETURN(params); 248 auto hucVdencBrcUpdateDmem = 249 (VdencHevcHucBrcUpdateDmem *)params; 250 251 auto setting = static_cast<HevcVdencFeatureSettings *>(m_constSettings); 252 ENCODE_CHK_NULL_RETURN(setting); 253 254 auto brcSettings = setting->brcSettings; 255 256 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->startGAdjFrame_U16, 4 * sizeof(uint16_t), brcSettings.startGAdjFrame.data, 4 * sizeof(uint16_t)); 257 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->gRateRatioThreshold_U8, 7 * sizeof(uint8_t), brcSettings.rateRatioThreshold.data, 7 * sizeof(uint8_t)); 258 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->startGAdjMult_U8, 5 * sizeof(uint8_t), brcSettings.startGAdjMult.data, 5 * sizeof(uint8_t)); 259 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->startGAdjDiv_U8, 5 * sizeof(uint8_t), brcSettings.startGAdjDiv.data, 5 * sizeof(uint8_t)); 260 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->gRateRatioThresholdQP_U8, 8 * sizeof(uint8_t), brcSettings.rateRatioThresholdQP.data, 8 * sizeof(uint8_t)); 261 262 if ((IsACQPEnabled() && m_basicFeature->m_hevcSeqParams->QpAdjustment) || (IsBRCEnabled() && (m_basicFeature->m_hevcSeqParams->MBBRC != 2))) 263 { 264 hucVdencBrcUpdateDmem->DeltaQPForSadZone0_S8 = brcSettings.deltaQPForSadZone0_S8; 265 hucVdencBrcUpdateDmem->DeltaQPForSadZone1_S8 = brcSettings.deltaQPForSadZone1_S8; 266 hucVdencBrcUpdateDmem->DeltaQPForSadZone2_S8 = brcSettings.deltaQPForSadZone2_S8; 267 hucVdencBrcUpdateDmem->DeltaQPForSadZone3_S8 = brcSettings.deltaQPForSadZone3_S8; 268 hucVdencBrcUpdateDmem->DeltaQPForMvZero_S8 = brcSettings.deltaQPForMvZero_S8; 269 hucVdencBrcUpdateDmem->DeltaQPForMvZone0_S8 = brcSettings.deltaQPForMvZone0_S8; 270 hucVdencBrcUpdateDmem->DeltaQPForMvZone1_S8 = brcSettings.deltaQPForMvZone1_S8; 271 hucVdencBrcUpdateDmem->DeltaQPForMvZone2_S8 = brcSettings.deltaQPForMvZone2_S8; 272 } 273 274 if (m_fastPakEnable) 275 { 276 hucVdencBrcUpdateDmem->ReEncodePositiveQPDeltaThr_S8 = brcSettings.reEncodePositiveQPDeltaThr_S8; 277 hucVdencBrcUpdateDmem->ReEncodeNegativeQPDeltaThr_S8 = brcSettings.reEncodeNegativeQPDeltaThr_S8; 278 } 279 else 280 { 281 hucVdencBrcUpdateDmem->ReEncodePositiveQPDeltaThr_S8 = 0; 282 hucVdencBrcUpdateDmem->ReEncodeNegativeQPDeltaThr_S8 = 0; 283 } 284 hucVdencBrcUpdateDmem->SceneChgPrevIntraPctThreshold_U8 = brcSettings.sceneChgPrevIntraPctThreshold_U8; 285 hucVdencBrcUpdateDmem->SceneChgCurIntraPctThreshold_U8 = brcSettings.sceneChgCurIntraPctThreshold_U8; 286 287 hucVdencBrcUpdateDmem->UPD_Randomaccess = m_basicFeature->m_hevcSeqParams->LowDelayMode == 1 ? 0 : 1; 288 289 return MOS_STATUS_SUCCESS; 290 } 291 SetHevcDepthBasedLambda(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams,PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams,uint8_t qp,uint16_t & SADQPLambda,uint16_t & RDQPLambda)292 MOS_STATUS HEVCEncodeBRC::SetHevcDepthBasedLambda( 293 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams, 294 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams, 295 uint8_t qp, 296 uint16_t& SADQPLambda, 297 uint16_t& RDQPLambda) 298 { 299 ENCODE_FUNC_CALL(); 300 301 ENCODE_CHK_NULL_RETURN(hevcSeqParams); 302 ENCODE_CHK_NULL_RETURN(hevcPicParams); 303 304 double QPScale = (hevcPicParams->CodingType == I_TYPE) ? 0.60 : 0.65; 305 uint32_t bGopSize = hevcSeqParams->GopRefDist; 306 int32_t depth = hevcPicParams->HierarchLevelPlus1 ? hevcPicParams->HierarchLevelPlus1 - 1 : 0; 307 308 std::vector<double> qpFactors; 309 uint32_t lambdaType = 1; 310 311 if (hevcSeqParams->LowDelayMode) 312 { 313 lambdaType = 1; 314 bGopSize = 4; // LDB set bGopSize as 4 315 qpFactors = {0.578, 0.3524, 0.3524}; 316 } 317 else 318 { 319 lambdaType = 2; 320 qpFactors = {0.442, 0.3536, 0.3536, 0.68}; // seems not used; 321 } 322 323 if (lambdaType != 1) 324 { 325 if (hevcPicParams->CodingType == B_TYPE && lambdaType != 0 && ((bGopSize == 4) || (bGopSize == 8))) 326 { 327 const double LambdaScaleForRA[2][4] = 328 { 329 //Base, Depth0, Depth1, Depth2 330 {1.8f, 0.9f, 1.7f, 1.0f}, // GOP 4 331 {2.0f, 0.9f, 1.4f, 0.8f} // GOP 8 332 }; 333 334 double raLambdaScale = 1.0; 335 if (bGopSize == 4) 336 { 337 if (depth == 2) 338 { 339 raLambdaScale = 1.0 * LambdaScaleForRA[0][3]; 340 } 341 else if (depth == 1) // depth is 1 //modification for LTR 342 { 343 raLambdaScale = 0.52 * LambdaScaleForRA[0][2]; 344 } 345 else if (depth == 0) // depth is 0 //modification for LTR 346 { 347 raLambdaScale = 0.65 * LambdaScaleForRA[0][1]; 348 } 349 350 QPScale *= raLambdaScale * LambdaScaleForRA[0][0]; 351 } 352 else if (bGopSize == 8) 353 { 354 if (depth == 3) 355 { 356 raLambdaScale = 1.0 * LambdaScaleForRA[1][3]; 357 } 358 else if (depth == 2 || depth == 1) 359 { 360 raLambdaScale = 0.52 * LambdaScaleForRA[1][2]; 361 } 362 else if (depth == 0) 363 { 364 raLambdaScale = 0.65 * LambdaScaleForRA[1][1]; 365 } 366 367 QPScale *= raLambdaScale * LambdaScaleForRA[1][0]; 368 } 369 } 370 } 371 else if (bGopSize > 0) 372 { 373 auto Clip3 = [&](double min, double max, double x) { 374 return ((x < min) ? min : ((x > max) ? max : x)); 375 }; 376 377 if (hevcPicParams->CodingType == I_TYPE) 378 { 379 QPScale = 0.57 * (1.0 - Clip3(0, 0.5, 0.05 * (bGopSize - 1))); 380 } 381 else 382 { 383 int size = qpFactors.size(); 384 QPScale = qpFactors[CodecHal_Clip3(0, size - 1, depth)]; 385 if (depth > 0) 386 { 387 QPScale *= Clip3(2.0, 4.0, ((qp - 12) / 6.0)); 388 } 389 } 390 } 391 392 double realLambda = QPScale * pow(2.0, MOS_MAX(0, qp - 12) / 3.0); 393 RDQPLambda = (uint16_t)(MOS_MIN(65535, realLambda * 4 + 0.5)); //U14.2 394 395 realLambda = sqrt(realLambda); 396 SADQPLambda = (uint16_t)(MOS_MIN(65535, realLambda * 4 + 0.5)); //U8.2 397 398 return MOS_STATUS_SUCCESS; 399 } 400 SetConstLambdaForUpdate(void * params,bool lambdaType)401 MOS_STATUS HEVCEncodeBRC::SetConstLambdaForUpdate(void *params, bool lambdaType) 402 { 403 ENCODE_FUNC_CALL(); 404 ENCODE_CHK_NULL_RETURN(params); 405 auto hucConstData = 406 (VdencHevcHucBrcConstantData *)params; 407 408 auto setting = static_cast<HevcVdencFeatureSettings *>(m_constSettings); 409 ENCODE_CHK_NULL_RETURN(setting); 410 411 auto brcSettings = setting->brcSettings; 412 413 if (lambdaType) 414 { 415 ENCODE_CHK_NULL_RETURN(m_basicFeature); 416 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_hevcSeqParams); 417 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_hevcPicParams); 418 419 for (uint8_t qp = 0; qp < HUC_QP_RANGE; qp++) 420 { 421 ENCODE_CHK_STATUS_RETURN(SetHevcDepthBasedLambda(m_basicFeature->m_hevcSeqParams, m_basicFeature->m_hevcPicParams, 422 qp, m_sadLambdaArray[qp], m_rdLambdaArray[qp])); 423 } 424 425 if (m_basicFeature->m_hevcPicParams->CodingType == I_TYPE) 426 { 427 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_2, brcSettings.HevcVdencBrcSettings_0.size, m_rdLambdaArray, brcSettings.HevcVdencBrcSettings_0.size); 428 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_0, brcSettings.HevcVdencBrcSettings_2.size, m_sadLambdaArray, brcSettings.HevcVdencBrcSettings_2.size); 429 } 430 else 431 { 432 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_3, brcSettings.HevcVdencBrcSettings_1.size, m_rdLambdaArray, brcSettings.HevcVdencBrcSettings_1.size); 433 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_1, brcSettings.HevcVdencBrcSettings_3.size, m_sadLambdaArray, brcSettings.HevcVdencBrcSettings_3.size); 434 } 435 } 436 else 437 { 438 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_2, brcSettings.HevcVdencBrcSettings_0.size, brcSettings.HevcVdencBrcSettings_0.data, brcSettings.HevcVdencBrcSettings_0.size); 439 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_3, brcSettings.HevcVdencBrcSettings_1.size, brcSettings.HevcVdencBrcSettings_1.data, brcSettings.HevcVdencBrcSettings_1.size); 440 441 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_0, brcSettings.HevcVdencBrcSettings_2.size, brcSettings.HevcVdencBrcSettings_2.data, brcSettings.HevcVdencBrcSettings_2.size); 442 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_1, brcSettings.HevcVdencBrcSettings_3.size, brcSettings.HevcVdencBrcSettings_3.data, brcSettings.HevcVdencBrcSettings_3.size); 443 } 444 445 return MOS_STATUS_SUCCESS; 446 } 447 SetConstForUpdate(void * params)448 MOS_STATUS HEVCEncodeBRC::SetConstForUpdate(void *params) 449 { 450 ENCODE_FUNC_CALL(); 451 ENCODE_CHK_NULL_RETURN(params); 452 auto hucConstData = 453 (VdencHevcHucBrcConstantData *)params; 454 455 auto setting = static_cast<HevcVdencFeatureSettings *>(m_constSettings); 456 ENCODE_CHK_NULL_RETURN(setting); 457 458 auto brcSettings = setting->brcSettings; 459 460 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_4, brcSettings.hucConstantData.size, brcSettings.hucConstantData.data, brcSettings.hucConstantData.size); 461 462 if (m_basicFeature->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) 463 { 464 const int numEstrateThreshlds = 7; 465 466 for (int i = 0; i < numEstrateThreshlds + 1; i++) 467 { 468 for (uint32_t j = 0; j < brcSettings.numDevThreshlds + 1; j++) 469 { 470 hucConstData->VdencHevcHucBrcConstantData_5[(numEstrateThreshlds + 1)*j + i] = *brcSettings.HevcVdencBrcSettings_4[j][i]; 471 hucConstData->VdencHevcHucBrcConstantData_6[(numEstrateThreshlds + 1)*j + i] = *brcSettings.HevcVdencBrcSettings_5[j][i]; 472 hucConstData->VdencHevcHucBrcConstantData_7[(numEstrateThreshlds + 1)*j + i] = *brcSettings.HevcVdencBrcSettings_6[j][i]; 473 } 474 } 475 } 476 477 // ModeCosts depends on frame type 478 if (m_basicFeature->m_pictureCodingType == I_TYPE) 479 { 480 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_8, brcSettings.HevcVdencBrcSettings_7.size, brcSettings.HevcVdencBrcSettings_7.data, brcSettings.HevcVdencBrcSettings_7.size); 481 } 482 else 483 { 484 MOS_SecureMemcpy(hucConstData->VdencHevcHucBrcConstantData_8, brcSettings.HevcVdencBrcSettings_8.size, brcSettings.HevcVdencBrcSettings_8.data, brcSettings.HevcVdencBrcSettings_8.size); 485 } 486 487 return MOS_STATUS_SUCCESS; 488 } 489 SetDmemForInit(void * params)490 MOS_STATUS HEVCEncodeBRC::SetDmemForInit(void *params) 491 { 492 ENCODE_FUNC_CALL(); 493 ENCODE_CHK_NULL_RETURN(params); 494 auto hucVdencBrcInitDmem = 495 (VdencHevcHucBrcInitDmem *)params; 496 497 auto setting = static_cast<HevcVdencFeatureSettings *>(m_constSettings); 498 ENCODE_CHK_NULL_RETURN(setting); 499 500 auto brcSettings = setting->brcSettings; 501 502 hucVdencBrcInitDmem->TargetBitrate_U32 = m_basicFeature->m_hevcSeqParams->TargetBitRate * m_brc_kbps; 503 hucVdencBrcInitDmem->MaxRate_U32 = m_basicFeature->m_hevcSeqParams->MaxBitRate * m_brc_kbps; 504 505 if (hucVdencBrcInitDmem->LowDelayMode_U8 = (m_basicFeature->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW)) 506 { 507 MOS_SecureMemcpy(hucVdencBrcInitDmem->DevThreshPB0_S8, 8 * sizeof(int8_t), brcSettings.lowdelayDevThreshPB.data, 8 * sizeof(int8_t)); 508 MOS_SecureMemcpy(hucVdencBrcInitDmem->DevThreshVBR0_S8, 8 * sizeof(int8_t), brcSettings.lowdelayDevThreshVBR.data, 8 * sizeof(int8_t)); 509 MOS_SecureMemcpy(hucVdencBrcInitDmem->DevThreshI0_S8, 8 * sizeof(int8_t), brcSettings.lowdelayDevThreshI.data, 8 * sizeof(int8_t)); 510 } 511 else 512 { 513 int8_t DevThreshPB0_S8[8] = {}; 514 int8_t DevThreshVBR0_S8[8] = {}; 515 int8_t DevThreshI0_S8[8] = {}; 516 517 uint64_t inputbitsperframe = uint64_t(hucVdencBrcInitDmem->MaxRate_U32*100. / (hucVdencBrcInitDmem->FrameRateM_U32 * 100.0 / hucVdencBrcInitDmem->FrameRateD_U32)); 518 if (m_brcEnabled && (m_rcMode != RATECONTROL_ICQ) && !hucVdencBrcInitDmem->BufSize_U32) 519 { 520 ENCODE_ASSERTMESSAGE("VBV BufSize should not be 0 for BRC case\n"); 521 return MOS_STATUS_INVALID_PARAMETER; 522 } 523 524 uint64_t vbvsz = hucVdencBrcInitDmem->BufSize_U32; 525 double bps_ratio = inputbitsperframe / (vbvsz / brcSettings.devStdFPS); 526 if (bps_ratio < brcSettings.bpsRatioLow) bps_ratio = brcSettings.bpsRatioLow; 527 if (bps_ratio > brcSettings.bpsRatioHigh) bps_ratio = brcSettings.bpsRatioHigh; 528 529 auto devThreshIFPNEG = (double *)brcSettings.devThreshIFPNEG.data; 530 auto devThreshPBFPNEG = (double *)brcSettings.devThreshPBFPNEG.data; 531 auto devThreshIFPPOS = (double *)brcSettings.devThreshIFPPOS.data; 532 auto devThreshPBFPPOS = (double *)brcSettings.devThreshPBFPPOS.data; 533 auto devThreshVBRPOS = (double *)brcSettings.devThreshVBRPOS.data; 534 auto devThreshVBRNEG = (double *)brcSettings.devThreshVBRNEG.data; 535 536 for (uint32_t i = 0; i < brcSettings.numDevThreshlds / 2; i++) { 537 DevThreshPB0_S8[i] = (signed char)(brcSettings.negMultPB*pow(devThreshPBFPNEG[i], bps_ratio)); 538 DevThreshPB0_S8[i + brcSettings.numDevThreshlds / 2] = (signed char)(brcSettings.postMultPB*pow(devThreshPBFPPOS[i], bps_ratio)); 539 540 DevThreshI0_S8[i] = (signed char)(brcSettings.negMultPB*pow(devThreshIFPNEG[i], bps_ratio)); 541 DevThreshI0_S8[i + brcSettings.numDevThreshlds / 2] = (signed char)(brcSettings.postMultPB*pow(devThreshIFPPOS[i], bps_ratio)); 542 543 DevThreshVBR0_S8[i] = (signed char)(brcSettings.negMultPB*pow(devThreshVBRNEG[i], bps_ratio)); 544 DevThreshVBR0_S8[i + brcSettings.numDevThreshlds / 2] = (signed char)(brcSettings.posMultVBR*pow(devThreshVBRPOS[i], bps_ratio)); 545 } 546 547 MOS_SecureMemcpy(hucVdencBrcInitDmem->DevThreshPB0_S8, 8 * sizeof(int8_t), (void*)DevThreshPB0_S8, 8 * sizeof(int8_t)); 548 MOS_SecureMemcpy(hucVdencBrcInitDmem->DevThreshVBR0_S8, 8 * sizeof(int8_t), (void*)DevThreshVBR0_S8, 8 * sizeof(int8_t)); 549 MOS_SecureMemcpy(hucVdencBrcInitDmem->DevThreshI0_S8, 8 * sizeof(int8_t), (void*)DevThreshI0_S8, 8 * sizeof(int8_t)); 550 } 551 552 MOS_SecureMemcpy(hucVdencBrcInitDmem->InstRateThreshP0_S8, 4 * sizeof(int8_t), brcSettings.instRateThreshP0.data, 4 * sizeof(int8_t)); 553 MOS_SecureMemcpy(hucVdencBrcInitDmem->InstRateThreshB0_S8, 4 * sizeof(int8_t), brcSettings.instRateThreshB0.data, 4 * sizeof(int8_t)); 554 MOS_SecureMemcpy(hucVdencBrcInitDmem->InstRateThreshI0_S8, 4 * sizeof(int8_t), brcSettings.instRateThreshI0.data, 4 * sizeof(int8_t)); 555 556 hucVdencBrcInitDmem->TopFrmSzThrForAdapt2Pass_U8 = brcSettings.topFrmSzThrForAdapt2Pass_U8; 557 hucVdencBrcInitDmem->BotFrmSzThrForAdapt2Pass_U8 = brcSettings.botFrmSzThrForAdapt2Pass_U8; 558 559 hucVdencBrcInitDmem->TopQPDeltaThrForAdapt2Pass_U8 = brcSettings.topQPDeltaThrForAdapt2Pass_U8; 560 hucVdencBrcInitDmem->BotQPDeltaThrForAdapt2Pass_U8 = brcSettings.botQPDeltaThrForAdapt2Pass_U8; 561 562 MOS_SecureMemcpy(hucVdencBrcInitDmem->EstRateThreshP0_U8, 7 * sizeof(uint8_t), brcSettings.estRateThreshP0.data, 7 * sizeof(uint8_t)); 563 MOS_SecureMemcpy(hucVdencBrcInitDmem->EstRateThreshB0_U8, 7 * sizeof(uint8_t), brcSettings.estRateThreshB0.data, 7 * sizeof(uint8_t)); 564 MOS_SecureMemcpy(hucVdencBrcInitDmem->EstRateThreshI0_U8, 7 * sizeof(uint8_t), brcSettings.estRateThreshI0.data, 7 * sizeof(uint8_t)); 565 566 if (m_brcEnabled) 567 { 568 ENCODE_CHK_STATUS_RETURN(SetBrcSettings(hucVdencBrcInitDmem)); 569 } 570 else if (m_hevcVDEncAcqpEnabled) 571 { 572 ENCODE_CHK_STATUS_RETURN(SetAcqpSettings(hucVdencBrcInitDmem)); 573 } 574 575 return MOS_STATUS_SUCCESS; 576 } 577 SetVdencBatchBufferState(const uint32_t currRecycledBufIdx,const uint32_t slcIdx,PMHW_BATCH_BUFFER & vdencBatchBuffer,bool & vdencHucUsed)578 MOS_STATUS HEVCEncodeBRC::SetVdencBatchBufferState( 579 const uint32_t currRecycledBufIdx, 580 const uint32_t slcIdx, 581 PMHW_BATCH_BUFFER &vdencBatchBuffer, 582 bool & vdencHucUsed) 583 { 584 ENCODE_FUNC_CALL(); 585 586 vdencHucUsed = m_vdencHucUsed; 587 vdencBatchBuffer = &m_vdenc2ndLevelBatchBuffer[currRecycledBufIdx]; 588 589 vdencBatchBuffer->dwOffset = 590 m_hwInterface->m_vdencBatchBuffer1stGroupSize + m_hwInterface->m_vdencBatchBuffer2ndGroupSize; 591 592 auto basicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 593 ENCODE_CHK_NULL_RETURN(basicFeature); 594 595 for (uint32_t j = 0; j < slcIdx; j++) 596 { 597 vdencBatchBuffer->dwOffset += 598 (m_hwInterface->m_vdencBatchBufferPerSliceConstSize + basicFeature->m_vdencBatchBufferPerSliceVarSize[j]); 599 } 600 601 return MOS_STATUS_SUCCESS; 602 } 603 SetSequenceStructs()604 MOS_STATUS HEVCEncodeBRC::SetSequenceStructs() 605 { 606 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 607 608 ENCODE_FUNC_CALL(); 609 610 m_brcInit = m_basicFeature->m_resolutionChanged; 611 612 m_brcEnabled = IsRateControlBrc(m_basicFeature->m_hevcSeqParams->RateControlMethod); 613 614 m_rcMode = m_brcEnabled ? m_basicFeature->m_hevcSeqParams->RateControlMethod : 0; 615 616 SetLcuBrc(); 617 618 if (m_rcMode == RATECONTROL_ICQ || m_rcMode == RATECONTROL_QVBR) 619 { 620 if (m_basicFeature->m_hevcSeqParams->ICQQualityFactor < CODECHAL_ENCODE_HEVC_MIN_ICQ_QUALITYFACTOR || 621 m_basicFeature->m_hevcSeqParams->ICQQualityFactor > CODECHAL_ENCODE_HEVC_MAX_ICQ_QUALITYFACTOR) 622 { 623 ENCODE_ASSERTMESSAGE("Invalid ICQ Quality Factor input (%d)\n", m_basicFeature->m_hevcSeqParams->ICQQualityFactor); 624 eStatus = MOS_STATUS_INVALID_PARAMETER; 625 return eStatus; 626 } 627 } 628 629 m_brcReset = m_basicFeature->m_hevcSeqParams->bResetBRC; 630 631 if (m_brcReset && 632 (!m_brcEnabled || 633 m_rcMode == RATECONTROL_ICQ)) 634 { 635 ENCODE_ASSERTMESSAGE("BRC Reset cannot be trigerred in CQP/ICQ modes - invalid BRC parameters."); 636 m_brcReset = false; 637 } 638 639 // ACQP is also considered as BRC (special version of ICQ) 640 if (m_brcEnabled) 641 { 642 m_vdencBrcEnabled = true; 643 m_hevcVDEncAcqpEnabled = false; // when BRC is enabled, ACQP has to be turned off 644 } 645 646 m_vdencHucUsed = m_hevcVDEncAcqpEnabled || m_vdencBrcEnabled; 647 648 // Check VBVBufferSize 649 if (m_brcEnabled) 650 { 651 if (m_basicFeature->m_hevcSeqParams->VBVBufferSizeInBit < m_basicFeature->m_hevcSeqParams->InitVBVBufferFullnessInBit) 652 { 653 ENCODE_NORMALMESSAGE( 654 "VBVBufferSizeInBit is less than InitVBVBufferFullnessInBit, \ 655 min(VBVBufferSizeInBit, InitVBVBufferFullnessInBit) will set to \ 656 hucVdencBrcInitDmem->InitBufFull_U32 and hucVdencBrcUpdateDmem->TARGETSIZE_U32(except Low Delay BRC).\n"); 657 } 658 } 659 660 return eStatus; 661 } 662 FreeBrcResources()663 MOS_STATUS HEVCEncodeBRC::FreeBrcResources() 664 { 665 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 666 667 ENCODE_FUNC_CALL(); 668 ENCODE_CHK_NULL_RETURN(m_hwInterface); 669 670 for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; j++) 671 { 672 eStatus = Mhw_FreeBb(m_hwInterface->GetOsInterface(), &m_vdenc2ndLevelBatchBuffer[j], nullptr); 673 ENCODE_ASSERT(eStatus == MOS_STATUS_SUCCESS); 674 } 675 676 if (m_rdLambdaArray) 677 { 678 MOS_DeleteArray(m_rdLambdaArray); 679 } 680 if (m_sadLambdaArray) 681 { 682 MOS_DeleteArray(m_sadLambdaArray); 683 } 684 685 return eStatus; 686 } 687 SetBrcSettings(void * params)688 MOS_STATUS HEVCEncodeBRC::SetBrcSettings(void *params) 689 { 690 ENCODE_FUNC_CALL(); 691 ENCODE_CHK_NULL_RETURN(params); 692 auto hucVdencBrcInitDmem = 693 (VdencHevcHucBrcInitDmem *)params; 694 695 switch (m_rcMode) 696 { 697 case RATECONTROL_ICQ: 698 hucVdencBrcInitDmem->BRCFlag = 0; 699 hucVdencBrcInitDmem->ACQP_U32 = m_basicFeature->m_hevcSeqParams->ICQQualityFactor; 700 break; 701 case RATECONTROL_CBR: 702 hucVdencBrcInitDmem->BRCFlag = 1; 703 break; 704 case RATECONTROL_VBR: 705 hucVdencBrcInitDmem->BRCFlag = 2; 706 hucVdencBrcInitDmem->ACQP_U32 = 0; 707 break; 708 case RATECONTROL_VCM: 709 hucVdencBrcInitDmem->BRCFlag = 3; 710 break; 711 case RATECONTROL_QVBR: 712 hucVdencBrcInitDmem->BRCFlag = 2; 713 hucVdencBrcInitDmem->ACQP_U32 = m_basicFeature->m_hevcSeqParams->ICQQualityFactor; 714 break; 715 default: 716 break; 717 } 718 719 // Low Delay BRC 720 if (m_basicFeature->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) 721 { 722 hucVdencBrcInitDmem->BRCFlag = 4; 723 } 724 725 switch (m_basicFeature->m_hevcSeqParams->MBBRC) 726 { 727 case mbBrcInternal: 728 case mbBrcEnabled: 729 hucVdencBrcInitDmem->CuQpCtrl_U8 = 3; 730 break; 731 case mbBrcDisabled: 732 hucVdencBrcInitDmem->CuQpCtrl_U8 = 0; 733 break; 734 default: 735 break; 736 } 737 738 // initQPIP, initQPB values will be used for BRC in the future 739 int32_t initQPIP = 0, initQPB = 0; 740 ComputeVDEncInitQP(initQPIP, initQPB); 741 hucVdencBrcInitDmem->InitQPIP_U8 = (uint8_t)initQPIP; 742 hucVdencBrcInitDmem->InitQPB_U8 = (uint8_t)initQPB; 743 744 return MOS_STATUS_SUCCESS; 745 } 746 SetAcqpSettings(void * params)747 MOS_STATUS HEVCEncodeBRC::SetAcqpSettings(void *params) 748 { 749 ENCODE_FUNC_CALL(); 750 ENCODE_CHK_NULL_RETURN(params); 751 auto hucVdencBrcInitDmem = 752 (VdencHevcHucBrcInitDmem *)params; 753 754 hucVdencBrcInitDmem->BRCFlag = 0; 755 756 // 0=No CUQP; 1=CUQP for I-frame; 2=CUQP for P/B-frame 757 // bit operation, bit 1 for I-frame, bit 2 for P/B frame 758 // In VDENC mode, the field "Cu_Qp_Delta_Enabled_Flag" should always be set to 1. 759 if (m_basicFeature->m_hevcSeqParams->QpAdjustment) 760 { 761 hucVdencBrcInitDmem->CuQpCtrl_U8 = 3; // wPictureCodingType I:0, P:1, B:2 762 } 763 else 764 { 765 hucVdencBrcInitDmem->CuQpCtrl_U8 = 0; // wPictureCodingType I:0, P:1, B:2 766 } 767 768 hucVdencBrcInitDmem->InitQPIP_U8 = m_basicFeature->m_hevcPicParams->QpY + m_basicFeature->m_hevcSliceParams->slice_qp_delta; 769 hucVdencBrcInitDmem->InitQPB_U8 = m_basicFeature->m_hevcPicParams->QpY + m_basicFeature->m_hevcSliceParams->slice_qp_delta; 770 771 return MOS_STATUS_SUCCESS; 772 } 773 ComputeVDEncInitQP(int32_t & initQPIP,int32_t & initQPB)774 void HEVCEncodeBRC::ComputeVDEncInitQP(int32_t& initQPIP, int32_t& initQPB) 775 { 776 ENCODE_FUNC_CALL(); 777 778 const float x0 = 0, y0 = 1.19f, x1 = 1.75f, y1 = 1.75f; 779 uint32_t frameSize = ((m_basicFeature->m_frameWidth * m_basicFeature->m_frameHeight * 3) >> 1); 780 781 initQPIP = (int)(1. / 1.2 * pow(10.0, (log10(frameSize * 2. / 3. * ((float)m_basicFeature->m_hevcSeqParams->FrameRate.Numerator / ((float)m_basicFeature->m_hevcSeqParams->FrameRate.Denominator * (float)m_basicFeature->m_hevcSeqParams->TargetBitRate * m_brc_kbps))) - x0) * (y1 - y0) / (x1 - x0) + y0) + 0.5); 782 783 initQPIP += 2; 784 785 int32_t gopP = (m_basicFeature->m_hevcSeqParams->GopRefDist) ? ((m_basicFeature->m_hevcSeqParams->GopPicSize - 1) / m_basicFeature->m_hevcSeqParams->GopRefDist) : 0; 786 int32_t gopB = m_basicFeature->m_hevcSeqParams->GopPicSize - 1 - gopP; 787 int32_t gopB1 = 0; 788 int32_t gopB2 = 0; 789 int32_t gopSize = 1 + gopP + gopB + gopB1 + gopB2; 790 791 if (gopSize == 1) 792 { 793 initQPIP += 12; 794 } 795 else if (gopSize < 15) 796 { 797 initQPIP += ((14 - gopSize) >> 1); 798 } 799 800 initQPIP = CodecHal_Clip3((int32_t)m_basicFeature->m_hevcPicParams->BRCMinQp, (int32_t)m_basicFeature->m_hevcPicParams->BRCMaxQp, initQPIP); 801 initQPIP--; 802 803 if (initQPIP < 0) 804 { 805 initQPIP = 1; 806 } 807 808 initQPB = ((initQPIP + initQPIP) * 563 >> 10) + 1; 809 initQPB = CodecHal_Clip3((int32_t)m_basicFeature->m_hevcPicParams->BRCMinQp, (int32_t)m_basicFeature->m_hevcPicParams->BRCMaxQp, initQPB); 810 811 if (gopSize > 300) //if intra frame is not inserted frequently 812 { 813 initQPIP -= 8; 814 initQPB -= 8; 815 } 816 else 817 { 818 initQPIP -= 2; 819 initQPB -= 2; 820 } 821 822 initQPIP = CodecHal_Clip3((int32_t)m_basicFeature->m_hevcPicParams->BRCMinQp, (int32_t)m_basicFeature->m_hevcPicParams->BRCMaxQp, initQPIP); 823 initQPB = CodecHal_Clip3((int32_t)m_basicFeature->m_hevcPicParams->BRCMinQp, (int32_t)m_basicFeature->m_hevcPicParams->BRCMaxQp, initQPB); 824 } 825 SetLcuBrc()826 void HEVCEncodeBRC::SetLcuBrc() 827 { 828 ENCODE_FUNC_CALL(); 829 830 if (m_brcEnabled) 831 { 832 switch (m_basicFeature->m_hevcSeqParams->MBBRC) 833 { 834 case mbBrcInternal: 835 m_lcuBrcEnabled = (m_basicFeature->m_hevcSeqParams->TargetUsage == 1); 836 break; 837 case mbBrcDisabled: 838 m_lcuBrcEnabled = false; 839 break; 840 case mbBrcEnabled: 841 m_lcuBrcEnabled = true; 842 break; 843 } 844 845 if (m_rcMode == RATECONTROL_ICQ || 846 m_rcMode == RATECONTROL_QVBR || 847 m_basicFeature->m_hevcPicParams->NumROI) 848 { 849 // ICQ or ROI must result in LCU-based BRC to be enabled. 850 m_lcuBrcEnabled = true; 851 } 852 } 853 854 if (m_rcMode == RATECONTROL_VCM && m_lcuBrcEnabled) 855 { 856 m_lcuBrcEnabled = false; // when VCM is enabled, only frame-based BRC 857 } 858 } 859 SetReadBrcPakStatsParams(uint8_t ucPass,uint32_t offset,PMOS_RESOURCE osResource,EncodeReadBrcPakStatsParams & readBrcPakStatsParams)860 MOS_STATUS HEVCEncodeBRC::SetReadBrcPakStatsParams( 861 uint8_t ucPass, 862 uint32_t offset, 863 PMOS_RESOURCE osResource, 864 EncodeReadBrcPakStatsParams &readBrcPakStatsParams) 865 { 866 ENCODE_FUNC_CALL(); 867 868 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 869 870 readBrcPakStatsParams.pHwInterface = m_hwInterface; 871 readBrcPakStatsParams.presBrcPakStatisticBuffer = m_vdencBrcBuffers.resBrcPakStatisticBuffer[m_vdencBrcBuffers.currBrcPakStasIdxForWrite]; 872 readBrcPakStatsParams.presStatusBuffer = osResource; 873 readBrcPakStatsParams.dwStatusBufNumPassesOffset = offset; 874 readBrcPakStatsParams.ucPass = ucPass; 875 876 return eStatus; 877 } 878 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,HEVCEncodeBRC)879 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, HEVCEncodeBRC) 880 { 881 params.frameStatisticsStreamOut |= m_hevcVDEncAcqpEnabled || m_vdencBrcEnabled; 882 883 return MOS_STATUS_SUCCESS; 884 } 885 MHW_SETPAR_DECL_SRC(VDENC_CMD2,HEVCEncodeBRC)886 MHW_SETPAR_DECL_SRC(VDENC_CMD2, HEVCEncodeBRC) 887 { 888 auto basicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 889 ENCODE_CHK_NULL_RETURN(basicFeature); 890 891 bool useDefaultQpDeltas = (m_hevcVDEncAcqpEnabled && basicFeature->m_hevcSeqParams->QpAdjustment) || 892 (m_brcEnabled && basicFeature->m_hevcSeqParams->MBBRC != 2 /*mbBrcDisabled*/); 893 894 if (useDefaultQpDeltas) 895 { 896 #if !(_MEDIA_RESERVED) 897 params.extSettings.emplace_back( 898 [this, basicFeature](uint32_t *data) { 899 data[13] |= 0xf0120000; 900 if (basicFeature->m_hevcPicParams->CodingType == I_TYPE) 901 { 902 data[14] |= 0x000021db; 903 data[16] |= 0x00010000; 904 } 905 else 906 { 907 data[14] |= 0x000021ed; 908 data[16] |= 0xd0010000; 909 data[18] |= 0x0060010f; 910 data[19] |= 0x000000c0; 911 } 912 return MOS_STATUS_SUCCESS; 913 }); 914 #else 915 params.vdencCmd2Par44[0] = 2; 916 params.vdencCmd2Par44[1] = 1; 917 params.vdencCmd2Par44[2] = 0; 918 params.vdencCmd2Par44[3] = -1; 919 if (basicFeature->m_hevcPicParams->CodingType == I_TYPE) 920 { 921 params.vdencCmd2Par45[0] = -5; 922 params.vdencCmd2Par45[1] = -3; 923 params.vdencCmd2Par45[2] = 1; 924 params.vdencCmd2Par45[3] = 2; 925 params.vdencCmd2Par47 = 1; 926 params.vdencCmd2Par48 = 0; 927 params.vdencCmd2Par50 = 0; 928 params.vdencCmd2Par52[0] = 0; 929 params.vdencCmd2Par52[1] = 0; 930 params.vdencCmd2Par52[2] = 0; 931 params.vdencCmd2Par53[0] = 0; 932 params.vdencCmd2Par53[1] = 0; 933 } 934 else 935 { 936 params.vdencCmd2Par45[0] = -3; 937 params.vdencCmd2Par45[1] = -2; 938 params.vdencCmd2Par45[2] = 1; 939 params.vdencCmd2Par45[3] = 2; 940 params.vdencCmd2Par47 = 1; 941 params.vdencCmd2Par48 = 0; 942 params.vdencCmd2Par50 = -3; 943 params.vdencCmd2Par52[0] = -1; 944 params.vdencCmd2Par52[1] = 0; 945 params.vdencCmd2Par52[2] = 1; 946 params.vdencCmd2Par53[0] = 96; 947 params.vdencCmd2Par53[1] = 192; 948 } 949 #endif // !(_MEDIA_RESERVED) 950 } 951 952 return MOS_STATUS_SUCCESS; 953 } 954 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT,HEVCEncodeBRC)955 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT, HEVCEncodeBRC) 956 { 957 ENCODE_FUNC_CALL(); 958 959 params.bAdvancedRateControlEnable = m_brcEnabled; 960 params.bBRCEnabled = m_hevcVDEncAcqpEnabled || m_vdencBrcEnabled; 961 962 return MOS_STATUS_SUCCESS; 963 } 964 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,HEVCEncodeBRC)965 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, HEVCEncodeBRC) 966 { 967 ENCODE_FUNC_CALL(); 968 969 if (params.function == BRC_UPDATE) 970 { 971 params.regionParams[0].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencBRCHistoryBuffer, 0); // Region 0 - History Buffer (Input/Output) 972 params.regionParams[0].isWritable = true; 973 974 params.regionParams[5].presRegion = const_cast<MOS_RESOURCE*>(&m_vdenc2ndLevelBatchBuffer[m_currRecycledBufIdx].OsResource); // Region 5 - Output SLB Buffer (Output) 975 params.regionParams[5].isWritable = true; 976 977 // region 15 always in clear 978 params.regionParams[15].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcDebugBuffer, 0); // Region 15 - Debug Buffer (Output) 979 params.regionParams[15].isWritable = true; 980 } 981 982 return MOS_STATUS_SUCCESS; 983 } 984 SetCurrRecycledBufIdx(const uint8_t index)985 MOS_STATUS HEVCEncodeBRC::SetCurrRecycledBufIdx(const uint8_t index) 986 { 987 ENCODE_FUNC_CALL(); 988 989 m_currRecycledBufIdx = index; 990 return MOS_STATUS_SUCCESS; 991 } 992 993 } // namespace encode 994