1 /* 2 * Copyright (c) 2020-2023, 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_av1_brc.cpp 24 //! \brief Defines the common interface for av1 brc features 25 //! 26 #include "encode_av1_basic_feature.h" 27 #include "encode_av1_brc.h" 28 #include "encode_av1_vdenc_feature_manager.h" 29 #include "encode_av1_vdenc_const_settings.h" 30 #include "encode_av1_brc_init_packet.h" 31 #include "encode_av1_brc_update_packet.h" 32 namespace encode 33 { Av1Brc(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)34 Av1Brc::Av1Brc( 35 MediaFeatureManager *featureManager, 36 EncodeAllocator *allocator, 37 CodechalHwInterfaceNext *hwInterface, 38 void *constSettings) : 39 MediaFeature(constSettings, hwInterface ? hwInterface->GetOsInterface() : nullptr), 40 m_hwInterface(hwInterface), 41 m_allocator(allocator) 42 { 43 m_featureManager = featureManager; 44 45 ENCODE_CHK_NULL_NO_STATUS_RETURN(featureManager); 46 m_basicFeature = dynamic_cast<Av1BasicFeature*>(featureManager->GetFeature(Av1FeatureIDs::basicFeature)); 47 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature); 48 49 ENCODE_CHK_NULL_NO_STATUS_RETURN(hwInterface); 50 } 51 ~Av1Brc()52 Av1Brc::~Av1Brc() 53 { 54 FreeBrcResources(); 55 } 56 Init(void * setting)57 MOS_STATUS Av1Brc::Init(void *setting) 58 { 59 ENCODE_FUNC_CALL(); 60 61 ENCODE_CHK_STATUS_RETURN(AllocateResources()); 62 63 return MOS_STATUS_SUCCESS; 64 } 65 Update(void * params)66 MOS_STATUS Av1Brc::Update(void *params) 67 { 68 ENCODE_FUNC_CALL(); 69 ENCODE_CHK_NULL_RETURN(params); 70 71 EncoderParams *encodeParams = (EncoderParams *)params; 72 73 ENCODE_CHK_STATUS_RETURN(SetSequenceStructs()); 74 75 const auto& seqParams = *m_basicFeature->m_av1SeqParams; 76 77 #if (_DEBUG || _RELEASE_INTERNAL) 78 ReportUserSetting( 79 m_userSettingPtr, 80 "Encode RateControl Method", 81 m_rcMode, 82 MediaUserSetting::Group::Sequence); 83 #endif 84 return MOS_STATUS_SUCCESS; 85 } 86 AllocateResources()87 MOS_STATUS Av1Brc::AllocateResources() 88 { 89 ENCODE_FUNC_CALL(); 90 91 ENCODE_CHK_NULL_RETURN(m_allocator); 92 ENCODE_CHK_NULL_RETURN(m_basicFeature); 93 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf); 94 95 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 96 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 97 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 98 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 99 allocParamsForBufferLinear.Format = Format_Buffer; 100 101 // BRC history buffer 102 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_brcHistoryBufSize, CODECHAL_PAGE_SIZE); 103 allocParamsForBufferLinear.pBufName = "VDENC BRC History Buffer"; 104 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 105 m_basicFeature->m_recycleBuf->RegisterResource(VdencBRCHistoryBuffer, allocParamsForBufferLinear, 1); 106 107 // VDENC BRC PAK MMIO buffer 108 allocParamsForBufferLinear.dwBytes = sizeof(Av1BrcPakMmio); 109 allocParamsForBufferLinear.pBufName = "VDENC BRC PAK MMIO Buffer"; 110 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 111 m_basicFeature->m_recycleBuf->RegisterResource(VdencBrcPakMmioBuffer, allocParamsForBufferLinear, 1); 112 113 // BRC HuC Data Buffer 114 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(BRC_DATA_SIZE, CODECHAL_PAGE_SIZE); 115 allocParamsForBufferLinear.pBufName = "BRC HuC Data Buffer"; 116 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ; 117 MOS_RESOURCE* brcDataBuffer = m_allocator->AllocateResource( 118 allocParamsForBufferLinear, 119 true); 120 ENCODE_CHK_NULL_RETURN(brcDataBuffer); 121 m_resBrcDataBuffer = *brcDataBuffer; 122 123 for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; j++) 124 { 125 // VDENC uses second level batch buffer 126 MOS_ZeroMemory(&m_vdenc2ndLevelBatchBuffer[j], sizeof(MHW_BATCH_BUFFER)); 127 m_vdenc2ndLevelBatchBuffer[j].bSecondLevel = true; 128 ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb( 129 m_hwInterface->GetOsInterface(), 130 &m_vdenc2ndLevelBatchBuffer[j], 131 nullptr, 132 m_hwInterface->m_vdenc2ndLevelBatchBufferSize)); 133 134 // VDENC uses second level batch buffer 135 MOS_ZeroMemory(&m_pakInsertOutputBatchBuffer[j], sizeof(MHW_BATCH_BUFFER)); 136 m_pakInsertOutputBatchBuffer[j].bSecondLevel = true; 137 ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb( 138 m_hwInterface->GetOsInterface(), 139 &m_pakInsertOutputBatchBuffer[j], 140 nullptr, 141 CODECHAL_PAGE_SIZE)); 142 } 143 144 return MOS_STATUS_SUCCESS; 145 } 146 GetBrcDataBuffer(MOS_RESOURCE * & buffer)147 MOS_STATUS Av1Brc::GetBrcDataBuffer(MOS_RESOURCE *&buffer) 148 { 149 ENCODE_FUNC_CALL(); 150 buffer = &m_resBrcDataBuffer; 151 return MOS_STATUS_SUCCESS; 152 } 153 MapTCBRCScenarioInfo(ENCODE_SCENARIO & scenarioInfo)154 inline uint8_t MapTCBRCScenarioInfo(ENCODE_SCENARIO& scenarioInfo) 155 { 156 uint8_t TCBRCScenarioInfo = 0; 157 switch (scenarioInfo) 158 { 159 case ESCENARIO_REMOTEGAMING: 160 TCBRCScenarioInfo = 0; 161 break; 162 case ESCENARIO_VIDEOCONFERENCE: 163 TCBRCScenarioInfo = 1; 164 break; 165 default: 166 ENCODE_ASSERTMESSAGE("TCBRC mode not supported!"); 167 break; 168 } 169 return TCBRCScenarioInfo; 170 } 171 SetDmemForUpdate(VdencAv1HucBrcUpdateDmem * dmem) const172 MOS_STATUS Av1Brc::SetDmemForUpdate(VdencAv1HucBrcUpdateDmem *dmem) const 173 { 174 ENCODE_FUNC_CALL(); 175 ENCODE_CHK_NULL_RETURN(dmem); 176 177 ENCODE_CHK_NULL_RETURN(m_basicFeature); 178 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_av1SeqParams); 179 auto seqParams = m_basicFeature->m_av1SeqParams; 180 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_av1PicParams); 181 auto picParams = m_basicFeature->m_av1PicParams; 182 auto setting = static_cast<Av1VdencFeatureSettings*>(m_constSettings); 183 ENCODE_CHK_NULL_RETURN(setting); 184 185 auto brcSettings = setting->brcSettings; 186 187 // BRC update setting 188 if (m_curTargetFullness > seqParams->VBVBufferSizeInBit && dmem->UPD_PAKPassNum == 0) 189 { 190 dmem->UPD_OverflowFlag = 0x1; 191 m_curTargetFullness -= seqParams->VBVBufferSizeInBit; 192 } 193 194 dmem->UPD_TARGET_BUF_FULLNESS = (uint32_t)m_curTargetFullness; 195 dmem->UPD_CDF_BufferSize = MOS_ALIGN_CEIL(m_basicFeature->m_cdfMaxNumBytes, CODECHAL_CACHELINE_SIZE); 196 dmem->UPD_FRAMENUM = m_basicFeature->m_frameNum; // frame number 197 dmem->UPD_HRD_BUFF_FULLNESS = m_delay; 198 dmem->UPD_HRD_BUFF_FULLNESS_LOWER = seqParams->LowerVBVBufferLevelThresholdInBit; 199 dmem->UPD_HRD_BUFF_FULLNESS_UPPER = seqParams->UpperVBVBufferLevelThresholdInBit; 200 201 auto CalculatedMaxFrame = m_basicFeature->m_frameHeight * m_basicFeature->m_frameWidth; 202 dmem->UPD_UserMaxFrame = seqParams->UserMaxIFrameSize > 0 ? MOS_MIN(seqParams->UserMaxIFrameSize, CalculatedMaxFrame) : CalculatedMaxFrame; 203 dmem->UPD_UserMaxFramePB = seqParams->UserMaxPBFrameSize > 0 ? MOS_MIN(seqParams->UserMaxPBFrameSize, CalculatedMaxFrame) : CalculatedMaxFrame; 204 205 dmem->UPD_CurWidth = (uint16_t)m_basicFeature->m_oriFrameWidth; 206 dmem->UPD_CurHeight = (uint16_t)m_basicFeature->m_oriFrameHeight; 207 dmem->UPD_Asyn = 0; 208 dmem->UPD_EnableAdaptiveRounding = (m_basicFeature->m_roundingMethod == RoundingMethod::adaptiveRounding); 209 210 if (seqParams->GopRefDist == 16 && m_rcMode == RATECONTROL_CQL) 211 dmem->UPD_MaxBRCLevel = 4; 212 else if (seqParams->GopRefDist == 8) 213 dmem->UPD_MaxBRCLevel = 3; 214 else if (seqParams->GopRefDist == 4) 215 dmem->UPD_MaxBRCLevel = 2; 216 else if (seqParams->GopRefDist == 2) 217 dmem->UPD_MaxBRCLevel = 1; 218 else 219 dmem->UPD_MaxBRCLevel = 0; 220 221 bool bAllowedPyramid = seqParams->GopRefDist != 3; 222 223 if (m_basicFeature->m_pictureCodingType == I_TYPE) 224 { 225 dmem->UPD_CurrFrameType = AV1_BRC_FRAME_TYPE_I; 226 } 227 else if (seqParams->SeqFlags.fields.HierarchicalFlag && bAllowedPyramid) 228 { 229 if (picParams->HierarchLevelPlus1 > 0) 230 { 231 std::map<int, AV1_BRC_FRAME_TYPE> hierchLevelPlus1_to_brclevel{ 232 {1, AV1_BRC_FRAME_TYPE_P_OR_LB}, 233 {2, AV1_BRC_FRAME_TYPE_B}, 234 {3, AV1_BRC_FRAME_TYPE_B1}, 235 {4, AV1_BRC_FRAME_TYPE_B2}, 236 {5, AV1_BRC_FRAME_TYPE_B3}}; 237 dmem->UPD_CurrFrameType = hierchLevelPlus1_to_brclevel.count(picParams->HierarchLevelPlus1) ? hierchLevelPlus1_to_brclevel[picParams->HierarchLevelPlus1] : AV1_BRC_FRAME_TYPE_INVALID; 238 //Invalid HierarchLevelPlus1 or LBD frames at level 3 eror check. 239 if ((dmem->UPD_CurrFrameType == AV1_BRC_FRAME_TYPE_INVALID) || 240 (m_basicFeature->m_ref.IsLowDelay() && dmem->UPD_CurrFrameType == AV1_BRC_FRAME_TYPE_B2)) 241 { 242 ENCODE_VERBOSEMESSAGE("AV1_BRC_FRAME_TYPE_INVALID or LBD picture doesn't support Level 4\n"); 243 dmem->UPD_CurrFrameType = AV1_BRC_FRAME_TYPE_B2; 244 } 245 } 246 else 247 { 248 dmem->UPD_CurrFrameType = AV1_BRC_FRAME_TYPE_P_OR_LB; //No Hierarchical info, treated as flat case 249 } 250 } 251 else 252 { 253 dmem->UPD_CurrFrameType = m_basicFeature->m_ref.IsLowDelay() ? AV1_BRC_FRAME_TYPE_P_OR_LB : AV1_BRC_FRAME_TYPE_B; 254 } 255 256 #define MEMCPY_CONST(D, S) MOS_SecureMemcpy(dmem->D, sizeof(dmem->D), brcSettings.S.data, brcSettings.S.size); 257 MEMCPY_CONST(UPD_startGAdjFrame, startGlobalAdjustFrame); 258 MEMCPY_CONST(UPD_QPThreshold, QPThresholds); 259 MEMCPY_CONST(UPD_gRateRatioThreshold, globalRateRatioThreshold); 260 MEMCPY_CONST(UPD_gRateRatioThresholdQP, globalRateRatioThresholdQP); 261 MEMCPY_CONST(UPD_startGAdjMult, startGlobalAdjustMult); 262 MEMCPY_CONST(UPD_startGAdjDiv, startGlobalAdjustDiv); 263 MEMCPY_CONST(UPD_DistThreshldI, distortionThresh); 264 MEMCPY_CONST(UPD_DistThreshldP, distortionThresh); 265 MEMCPY_CONST(UPD_DistThreshldB, distortionThreshB); 266 MEMCPY_CONST(UPD_MaxFrameThreshI, maxFrameMultI); 267 MEMCPY_CONST(UPD_MaxFrameThreshP, maxFrameMultP); 268 MEMCPY_CONST(UPD_MaxFrameThreshB, maxFrameMultP); 269 #undef MEMCPY_CONST 270 271 dmem->UPD_Temporal_Level = m_basicFeature->m_av1PicParams->temporal_id; 272 dmem->UPD_Lowdelay = seqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW ? 1 : 0; 273 // To handle ultra-low-delay situation inside driver 274 dmem->UPD_Lowdelay = (dmem->UPD_Lowdelay || seqParams->InitVBVBufferFullnessInBit <= m_inputbitsperframe * 2) ? 1 : 0; 275 276 dmem->UPD_TR_TargetSize = picParams->TargetFrameSize << 3; 277 278 if (picParams->TargetFrameSize > 0) 279 { 280 dmem->UPD_TCBRC_SCENARIO = MapTCBRCScenarioInfo(seqParams->ScenarioInfo); 281 } 282 283 dmem->UPD_LA_TargetFULNESS = 0; 284 dmem->UPD_Delta = 0; 285 dmem->UPD_LALength = 0; 286 287 //SLBB related fields. 288 dmem->UPD_SLBBSize = m_slbData.slbSize; 289 dmem->UPD_AVPPiCStateCmdNum = m_slbData.avpPicStateCmdNum; 290 dmem->UPD_AVPSegmentStateOffset = m_slbData.avpSegmentStateOffset; 291 dmem->UPD_AVPInloopFilterStateOffset = m_slbData.avpInloopFilterStateOffset; 292 dmem->UPD_VDEncCmd1Offset = m_slbData.vdencCmd1Offset; 293 dmem->UPD_VDEncCmd2Offset = m_slbData.vdencCmd2Offset; 294 dmem->UPD_AVPPicStateOffset = m_slbData.avpPicStateOffset; 295 dmem->UPD_VDEncTileSliceStateOffset = m_slbData.vdencTileSliceStateOffset; 296 dmem->UPD_TileNum = m_slbData.tileNum; 297 298 // BA start 299 dmem->UPD_LoopFilterParamsBitOffset = (uint16_t)m_basicFeature->m_av1PicParams->LoopFilterParamsBitOffset; 300 dmem->UPD_QIndexBitOffset = (uint16_t)m_basicFeature->m_av1PicParams->QIndexBitOffset; 301 dmem->UPD_SegmentationBitOffset = (uint16_t)m_basicFeature->m_av1PicParams->SegmentationBitOffset; // after SegOn flag bit. 302 dmem->UPD_FrameHdrOBUSizeInBits = (uint16_t)m_basicFeature->m_av1PicParams->FrameHdrOBUSizeInBits; // excluding frame_header_obu's trailing_bits() and frame_obu's byte_alignment() 303 dmem->UPD_FrameHdrOBUSizeInBytes = (uint16_t)((m_basicFeature->m_av1PicParams->FrameHdrOBUSizeInBits + 7) >> 3); 304 dmem->UPD_FrameHdrOBUSizeByteOffset = (uint16_t)(m_basicFeature->m_av1PicParams->FrameHdrOBUSizeByteOffset - m_basicFeature->GetAppHdrSizeInBytes(true)); 305 dmem->UPD_FrameType = 0; 306 dmem->UPD_ErrorResilientMode = m_basicFeature->m_av1PicParams->PicFlags.fields.error_resilient_mode; 307 dmem->UPD_IntraOnly = 0; 308 dmem->UPD_PrimaryRefFrame = 0; 309 dmem->UPD_SegOn = m_basicFeature->m_av1PicParams->stAV1Segments.SegmentFlags.fields.segmentation_enabled; 310 dmem->UPD_SegMapUpdate = 0; 311 dmem->UPD_SegTemporalUpdate = 0; 312 dmem->UPD_SegUpdateData = 0; 313 dmem->UPD_IsFrameOBU = m_basicFeature->m_av1PicParams->PicFlags.fields.EnableFrameOBU; 314 dmem->UPD_EnableCDEFUpdate = m_basicFeature->m_av1SeqParams->CodingToolFlags.fields.enable_cdef; 315 dmem->UPD_CDEFParamsBitOffset = (uint16_t)m_basicFeature->m_av1PicParams->CDEFParamsBitOffset; 316 dmem->UPD_CDEFParamsSizeInBits = (uint16_t)m_basicFeature->m_av1PicParams->CDEFParamsSizeInBits; 317 dmem->UPD_EnableLFUpdate = 1; 318 dmem->UPD_DisableCdfUpdate = (m_basicFeature->m_av1PicParams->primary_ref_frame != av1PrimaryRefNone); 319 dmem->UPD_EnableDMAForCdf = 1; 320 dmem->UPD_AdditionalHrdSizeByteCount = 0 - m_basicFeature->m_av1PicParams->FrameSizeReducedInBytes; 321 dmem->UPD_PaletteOn = m_basicFeature->m_av1PicParams->PicFlags.fields.PaletteModeEnable; 322 323 if (dmem->UPD_PAKPassNum == 1) 324 m_curTargetFullness += m_inputbitsperframe; 325 326 if (picParams->PicFlags.fields.allow_intrabc && AV1_KEY_OR_INRA_FRAME(picParams->PicFlags.fields.frame_type)) 327 { 328 dmem->UPD_EnableCDEFUpdate = 0; 329 dmem->UPD_EnableLFUpdate = 0; 330 } 331 332 return MOS_STATUS_SUCCESS; 333 } 334 SetConstForUpdate(VdencAv1HucBrcConstantData * params) const335 MOS_STATUS Av1Brc::SetConstForUpdate(VdencAv1HucBrcConstantData *params) const 336 { 337 ENCODE_FUNC_CALL(); 338 ENCODE_CHK_NULL_RETURN(params); 339 auto constData = (VdencAv1HucBrcConstantData *)params; 340 341 auto setting = static_cast<Av1VdencFeatureSettings *>(m_constSettings); 342 ENCODE_CHK_NULL_RETURN(setting); 343 344 auto brcSettings = setting->brcSettings; 345 346 #define MEMCPY_CONST(D, S) MOS_SecureMemcpy(constData->D, sizeof(constData->D), brcSettings.S.data, brcSettings.S.size); 347 MEMCPY_CONST(CONST_QPAdjTabI, av1DeltaQpI); 348 MEMCPY_CONST(CONST_QPAdjTabP, av1DeltaQpP); 349 MEMCPY_CONST(CONST_QPAdjTabB, av1DeltaQpP); 350 MEMCPY_CONST(CONST_DistQPAdjTabI, av1DistortionsDeltaQpI); 351 MEMCPY_CONST(CONST_DistQPAdjTabP, av1DistortionsDeltaQpP); 352 MEMCPY_CONST(CONST_DistQPAdjTabB, av1DistortionsDeltaQpP); 353 MEMCPY_CONST(CONST_LoopFilterLevelTabLuma, loopFilterLevelTabLuma); 354 MEMCPY_CONST(CONST_LoopFilterLevelTabChroma, loopFilterLevelTabChroma); 355 356 // ModeCosts depends on frame type 357 if (m_basicFeature->m_pictureCodingType == I_TYPE) 358 { 359 MEMCPY_CONST(CONST_ModeCosts, hucModeCostsIFrame); 360 } 361 else 362 { 363 MEMCPY_CONST(CONST_ModeCosts, hucModeCostsPFrame); 364 } 365 #undef MEMCPY_CONST 366 return MOS_STATUS_SUCCESS; 367 } 368 SwitchFlag(uint8_t rc)369 inline uint16_t SwitchFlag(uint8_t rc) 370 { 371 uint16_t brcFlag = 0; 372 switch (rc) 373 { 374 case RATECONTROL_CBR: 375 brcFlag = 0x10; // BRC flag 0: ACQP, 0x10: CBR, 0x20: VBR, 0x40: AVBR, 0x80: CQL 376 break; 377 case RATECONTROL_VBR: 378 brcFlag = 0x20; 379 break; 380 case RATECONTROL_CQP: 381 brcFlag = 0; 382 break; 383 case RATECONTROL_CQL: 384 brcFlag = 0x80; 385 break; 386 default: 387 ENCODE_ASSERTMESSAGE("BRC mode not supported!"); 388 break; 389 } 390 return brcFlag; 391 } 392 CalculateNormalizedDenominator(FRAMERATE * frameRates,uint16_t numberOfLayers,uint32_t normalizedDenominator)393 static uint32_t CalculateNormalizedDenominator(FRAMERATE* frameRates, uint16_t numberOfLayers, uint32_t normalizedDenominator) 394 { 395 ENCODE_FUNC_CALL(); 396 397 // If pointer to the list of FrameRates is null, return the current Normalized Denominator. 398 if (!frameRates) 399 { 400 return normalizedDenominator; 401 } 402 403 if (numberOfLayers == 0) 404 { 405 return normalizedDenominator; 406 } 407 408 normalizedDenominator = normalizedDenominator * frameRates[numberOfLayers - 1].Denominator / MosUtilities::MosGCD(normalizedDenominator, frameRates[numberOfLayers - 1].Denominator); 409 410 return CalculateNormalizedDenominator(frameRates, numberOfLayers - 1, normalizedDenominator); 411 } 412 GetProfileLevelMaxFrameSize(uint32_t width,uint32_t height,uint32_t userMaxFrameSize)413 inline uint32_t GetProfileLevelMaxFrameSize(uint32_t width, uint32_t height, uint32_t userMaxFrameSize) 414 { 415 ENCODE_FUNC_CALL(); 416 uint32_t profileLevelMaxFrame = 0; 417 418 // Might need calculate max frame size base on profile and level, confirm with arch. 419 420 profileLevelMaxFrame = width * height; 421 if (userMaxFrameSize > 0) 422 { 423 profileLevelMaxFrame = (uint32_t)MOS_MIN(userMaxFrameSize, profileLevelMaxFrame); 424 } 425 426 return profileLevelMaxFrame; 427 } 428 ComputeVDEncInitQPI(uint32_t width,uint32_t height,FRAMERATE frameRate,uint32_t targetBitRate,uint16_t gopPicSize,bool is10Bit,uint16_t n_p)429 inline int32_t ComputeVDEncInitQPI(uint32_t width, uint32_t height, FRAMERATE frameRate, uint32_t targetBitRate, uint16_t gopPicSize, bool is10Bit, uint16_t n_p) 430 { 431 ENCODE_FUNC_CALL(); 432 433 uint32_t frameSize = ((width * height * 3) >> 1); 434 if (is10Bit) 435 { 436 frameSize = (frameSize * 10) >> 3; 437 } 438 439 const float x0 = 0, y0 = 1.19f, x1 = 1.75f, y1 = 1.75f; 440 441 int32_t qpP = (int32_t)(1. / 1.2 * pow(10.0, (log10(frameSize * 2. / 3. * ((float)frameRate.Numerator) / ((float)targetBitRate * BRC_KBPS * frameRate.Denominator)) - x0) * (y1 - y0) / (x1 - x0) + y0) + 0.5); 442 qpP = (int32_t)((float)qpP * (5.0)); 443 qpP -= 20; 444 qpP = MOS_CLAMP_MIN_MAX(qpP, 1, 200); 445 446 int32_t qpI = (qpP > 4) ? (qpP - 4) : qpP; 447 int16_t qiboost = n_p / 30 - 1; 448 qiboost = MOS_CLAMP_MIN_MAX(qiboost, 10, 20); 449 450 qpI -= qiboost; 451 qpI = MOS_CLAMP_MIN_MAX(qpI, 1, 200); 452 453 return qpI; 454 } 455 GetFrameRate(CODEC_AV1_ENCODE_SEQUENCE_PARAMS const & seqParams)456 static std::tuple<uint32_t, uint32_t> GetFrameRate(CODEC_AV1_ENCODE_SEQUENCE_PARAMS const &seqParams) 457 { 458 if ((seqParams.FrameRate->Numerator != 0) && (seqParams.FrameRate->Denominator != 0)) 459 { 460 return std::make_tuple(seqParams.FrameRate->Numerator, seqParams.FrameRate->Denominator); 461 } 462 else 463 { 464 return std::make_tuple(30, 1); 465 } 466 } 467 SetDmemForInit(VdencAv1HucBrcInitDmem * dmem) const468 MOS_STATUS Av1Brc::SetDmemForInit(VdencAv1HucBrcInitDmem *dmem) const 469 { 470 ENCODE_FUNC_CALL(); 471 ENCODE_CHK_NULL_RETURN(dmem); 472 ENCODE_CHK_NULL_RETURN(m_basicFeature); 473 474 auto setting = static_cast<Av1VdencFeatureSettings*>(m_constSettings); 475 ENCODE_CHK_NULL_RETURN(setting); 476 477 auto brcSettings = setting->brcSettings; 478 479 auto seqParams = m_basicFeature->m_av1SeqParams; 480 ENCODE_CHK_NULL_RETURN(seqParams); 481 482 dmem->BRCFunc = IsBRCResetRequired() ? 2 : 0; 483 dmem->INIT_ProfileLevelMaxFrame = GetProfileLevelMaxFrameSize(m_basicFeature->m_frameWidth, m_basicFeature->m_frameHeight, seqParams->UserMaxIFrameSize); 484 dmem->INIT_TargetBitrate = seqParams->TargetBitRate[seqParams->NumTemporalLayersMinus1] * BRC_KBPS; 485 dmem->INIT_MaxRate = seqParams->MaxBitRate * BRC_KBPS; 486 dmem->INIT_MinRate = seqParams->MinBitRate * BRC_KBPS; 487 488 std::tie(dmem->INIT_FrameRateM, dmem->INIT_FrameRateD) = GetFrameRate(*seqParams); 489 490 dmem->INIT_InitBufFullness = MOS_MIN(seqParams->InitVBVBufferFullnessInBit, seqParams->VBVBufferSizeInBit); 491 dmem->INIT_BufSize = m_vbvSize; 492 dmem->INIT_BRCFlag = SwitchFlag(seqParams->RateControlMethod); 493 m_curTargetFullness = seqParams->InitVBVBufferFullnessInBit; 494 495 auto BGOPSize = seqParams->GopRefDist; 496 int32_t intraPeriod = seqParams->GopPicSize - 1; 497 498 if (BGOPSize > 1) 499 { 500 if (intraPeriod > 0) 501 { 502 intraPeriod = ((intraPeriod + (BGOPSize - 1)) / BGOPSize) * BGOPSize; 503 } 504 if (intraPeriod != -1) 505 { 506 dmem->INIT_GopP = intraPeriod / BGOPSize; 507 dmem->INIT_GopB = intraPeriod / BGOPSize; 508 dmem->INIT_GopB1 = (dmem->INIT_GopP + dmem->INIT_GopB == intraPeriod)? 0 : dmem->INIT_GopP * 2; 509 dmem->INIT_GopB2 = intraPeriod - dmem->INIT_GopP - dmem->INIT_GopB - dmem->INIT_GopB1; 510 if (m_rcMode == RATECONTROL_CQL && seqParams->GopRefDist == 16) 511 { 512 dmem->INIT_GopB2 = (dmem->INIT_GopP + dmem->INIT_GopB + dmem->INIT_GopB1 == intraPeriod) ? 0 : dmem->INIT_GopB1 * 2; 513 dmem->INIT_GopB3 = intraPeriod - dmem->INIT_GopP - dmem->INIT_GopB - dmem->INIT_GopB1 - dmem->INIT_GopB2; 514 } 515 } 516 else 517 { 518 dmem->INIT_GopP = 9999; 519 dmem->INIT_GopB = 9999; 520 } 521 } 522 else 523 { 524 dmem->INIT_GopP = seqParams->GopPicSize - 1; 525 dmem->INIT_GopB = 0; 526 } 527 528 dmem->INIT_FrameWidth = (uint16_t)m_basicFeature->m_oriFrameWidth; 529 dmem->INIT_FrameHeight = (uint16_t)m_basicFeature->m_oriFrameHeight; 530 dmem->INIT_MinQP = m_basicFeature->m_av1PicParams->MinBaseQIndex; 531 dmem->INIT_MaxQP = m_basicFeature->m_av1PicParams->MaxBaseQIndex == 0 ? 255 : m_basicFeature->m_av1PicParams->MaxBaseQIndex; 532 dmem->INIT_LevelQP = seqParams->ICQQualityFactor; 533 dmem->INIT_GoldenFrameInterval = 14; 534 dmem->INIT_EnableScaling = false; 535 dmem->INIT_OvershootCBR_pct = 0; //sliding window related. 536 537 #define MEMCPY_CONST(D, S) MOS_SecureMemcpy(dmem->D, sizeof(dmem->D), brcSettings.S.data, brcSettings.S.size); 538 MEMCPY_CONST(INIT_InstRateThreshI0, instRateThresholdI); 539 MEMCPY_CONST(INIT_InstRateThreshP0, instRateThresholdP); 540 #undef MEMCPY_CONST 541 542 if (dmem->INIT_FrameRateM == 0) 543 { 544 return MOS_STATUS_INVALID_PARAMETER; 545 } 546 double inputBitsPerFrame = ((double)dmem->INIT_MaxRate * (double)dmem->INIT_FrameRateD) / (double)dmem->INIT_FrameRateM; 547 double bpsRatio = inputBitsPerFrame / ((double)dmem->INIT_BufSize / brcSettings.devStdFPS); 548 bpsRatio = MOS_CLAMP_MIN_MAX(bpsRatio, brcSettings.bpsRatioLow, brcSettings.bpsRatioHigh); 549 for (uint32_t i = 0; i < brcSettings.numDevThreshlds / 2; i++) 550 { 551 dmem->INIT_DevThreshPB0[i] = (int8_t)(brcSettings.negMultPB * pow(((double *)(brcSettings.devThresholdFpNegPB.data))[i], bpsRatio)); 552 dmem->INIT_DevThreshPB0[i + brcSettings.numDevThreshlds / 2] = (int8_t)(brcSettings.postMultPB * pow(((double *)(brcSettings.devThresholdFpPosPB.data))[i], bpsRatio)); 553 554 dmem->INIT_DevThreshI0[i] = (int8_t)(brcSettings.negMultPB * pow(((double *)(brcSettings.devThresholdFpNegI.data))[i], bpsRatio)); 555 dmem->INIT_DevThreshI0[i + brcSettings.numDevThreshlds / 2] = (int8_t)(brcSettings.postMultPB * pow(((double *)(brcSettings.devThresholdFpPosI.data))[i], bpsRatio)); 556 557 dmem->INIT_DevThreshVBR0[i] = (int8_t)(brcSettings.negMultVBR * pow(((double *)(brcSettings.devThresholdVbrNeg.data))[i], bpsRatio)); 558 dmem->INIT_DevThreshVBR0[i + brcSettings.numDevThreshlds / 2] = (int8_t)(brcSettings.posMultVBR * pow(((double *)(brcSettings.devThresholdVbrPos.data))[i], bpsRatio)); 559 } 560 561 int32_t qpI = 0, qpP = 0; 562 qpI = ComputeVDEncInitQPI( 563 m_basicFeature->m_oriFrameWidth, 564 m_basicFeature->m_oriFrameHeight, 565 m_basicFeature->m_av1SeqParams->FrameRate[0], 566 m_basicFeature->m_av1SeqParams->TargetBitRate[0], 567 m_basicFeature->m_av1SeqParams->GopPicSize, 568 m_basicFeature->m_is10Bit, 569 dmem->INIT_GopP); 570 571 qpP = qpI + 20; 572 573 dmem->INIT_InitQPI = (uint8_t)qpI; 574 dmem->INIT_InitQPP = (uint8_t)qpP; 575 576 dmem->INIT_SegMapGenerating = false; 577 dmem->INIT_Total_Level = seqParams->NumTemporalLayersMinus1 + 1; 578 if (dmem->INIT_Total_Level > 1) 579 { 580 return MOS_STATUS_INVALID_PARAMETER; 581 } 582 583 dmem->INIT_SLIDINGWINDOW_ENABLE = seqParams->SlidingWindowSize != 0; 584 dmem->INIT_SLIDINGWINDOW_SIZE = (uint8_t)seqParams->SlidingWindowSize; 585 if (dmem->INIT_SLIDINGWINDOW_ENABLE && seqParams->TargetBitRate[0] > 0) 586 { 587 dmem->INIT_OvershootCBR_pct = (uint16_t)(seqParams->MaxBitRatePerSlidingWindow * 100 / seqParams->TargetBitRate[0]); 588 } 589 return MOS_STATUS_SUCCESS; 590 } 591 SetSequenceStructs()592 MOS_STATUS Av1Brc::SetSequenceStructs() 593 { 594 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 595 596 ENCODE_FUNC_CALL(); 597 598 if (m_basicFeature->m_av1SeqParams->RateControlMethod == RATECONTROL_CQL) 599 { 600 const uint8_t ICQFactorLookup[52] = { 601 0, 1, 1, 1, 1, 2, 3, 4, 6, 7, 9, 11, 13, 16, 18, 23, 602 26, 30, 34, 39, 46, 52, 59, 68, 77, 87, 98, 104,112,120,127,134, 603 142,149,157,164,171,178,186,193,200,207,213,219,225,230,235,240, 604 245,249,252,255 605 }; 606 607 uint32_t TargetBitRate = m_basicFeature->m_frameWidth * m_basicFeature->m_frameHeight * 8 / 1000; 608 m_basicFeature->m_av1SeqParams->ICQQualityFactor = ICQFactorLookup[m_basicFeature->m_av1SeqParams->ICQQualityFactor]; 609 m_basicFeature->m_av1SeqParams->TargetBitRate[0] = TargetBitRate; 610 m_basicFeature->m_av1SeqParams->MaxBitRate = (TargetBitRate << 4) / 10; 611 m_basicFeature->m_av1SeqParams->MinBitRate = 0; 612 m_basicFeature->m_av1SeqParams->InitVBVBufferFullnessInBit = 8000 * (TargetBitRate << 3) / 10; 613 m_basicFeature->m_av1SeqParams->VBVBufferSizeInBit = 8000 * (TargetBitRate << 1); 614 } 615 616 m_brcEnabled = IsRateControlBrc(m_basicFeature->m_av1SeqParams->RateControlMethod); 617 618 m_brcInit = m_brcEnabled && m_basicFeature->m_resolutionChanged; 619 620 m_rcMode = m_brcEnabled? m_basicFeature->m_av1SeqParams->RateControlMethod : 0; 621 622 if (m_rcMode == RATECONTROL_CQL || m_rcMode == RATECONTROL_QVBR) 623 { 624 if (m_basicFeature->m_av1SeqParams->ICQQualityFactor > ENCODE_AV1_MAX_ICQ_QUALITYFACTOR) 625 { 626 ENCODE_ASSERTMESSAGE("Invalid ICQ Quality Factor input (%d)\n", m_basicFeature->m_av1SeqParams->ICQQualityFactor); 627 eStatus = MOS_STATUS_INVALID_PARAMETER; 628 return eStatus; 629 } 630 } 631 632 m_brcReset = m_basicFeature->m_av1SeqParams->SeqFlags.fields.ResetBRC; 633 634 if (m_brcReset && 635 (!m_brcEnabled || 636 m_rcMode == RATECONTROL_CQL)) 637 { 638 ENCODE_ASSERTMESSAGE("BRC Reset cannot be trigerred in CQP/ICQ modes - invalid BRC parameters."); 639 m_brcReset = false; 640 } 641 642 if (IsBRCInitRequired()) 643 { 644 auto seqParams = m_basicFeature->m_av1SeqParams; 645 ENCODE_CHK_NULL_RETURN(seqParams); 646 647 m_delay = seqParams->InitVBVBufferFullnessInBit; 648 m_vbvSize = seqParams->VBVBufferSizeInBit; 649 650 uint32_t nom = 0; 651 uint32_t denom = 1; 652 std::tie(nom, denom) = GetFrameRate(*seqParams); 653 654 if (denom == 0) 655 { 656 denom = 1; 657 } 658 659 m_frameRate = (int32_t)((double)nom * 100. / (double)denom); 660 661 //average frame size in bits based on bit rate and frame rate. 662 const uint32_t maxBitrate = seqParams->MaxBitRate * BRC_KBPS; 663 m_inputbitsperframe = maxBitrate * 100. / m_frameRate; 664 665 //make sure the buffer size can contain at least 4 frames in average 666 if (m_vbvSize < (int32_t)(m_inputbitsperframe * 4)) 667 { 668 m_vbvSize = (int32_t)(m_inputbitsperframe * 4); 669 } 670 //make sure the initial buffer size is larger than 2 average frames and smaller than the max buffer size. 671 if (m_delay == 0) 672 m_delay = 7 * m_vbvSize / 8; 673 if (m_delay < (int32_t)(m_inputbitsperframe * 2)) 674 m_delay = (int32_t)(m_inputbitsperframe * 2); 675 if (m_delay > m_vbvSize) 676 m_delay = m_vbvSize; 677 } 678 679 return eStatus; 680 } 681 FreeBrcResources()682 MOS_STATUS Av1Brc::FreeBrcResources() 683 { 684 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 685 686 ENCODE_FUNC_CALL(); 687 ENCODE_CHK_NULL_RETURN(m_hwInterface); 688 689 for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; j++) 690 { 691 eStatus = Mhw_FreeBb(m_hwInterface->GetOsInterface(), &m_vdenc2ndLevelBatchBuffer[j], nullptr); 692 ENCODE_ASSERT(eStatus == MOS_STATUS_SUCCESS); 693 eStatus = Mhw_FreeBb(m_hwInterface->GetOsInterface(), &m_pakInsertOutputBatchBuffer[j], nullptr); 694 ENCODE_ASSERT(eStatus == MOS_STATUS_SUCCESS); 695 } 696 697 return eStatus; 698 } 699 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,Av1Brc)700 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, Av1Brc) 701 { 702 ENCODE_CHK_NULL_RETURN(params.hucDataSource); 703 704 switch (params.function) 705 { 706 case BRC_INIT: { 707 auto dmem = (VdencAv1HucBrcInitDmem *)m_allocator->LockResourceForWrite(params.hucDataSource); 708 709 ENCODE_CHK_NULL_RETURN(dmem); 710 MOS_ZeroMemory(dmem, sizeof(VdencAv1HucBrcInitDmem)); 711 712 SetDmemForInit(dmem); 713 714 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(params.hucDataSource)); 715 break; 716 } 717 case BRC_UPDATE: { 718 auto dmem = (VdencAv1HucBrcUpdateDmem *)m_allocator->LockResourceForWrite(params.hucDataSource); 719 720 ENCODE_CHK_NULL_RETURN(dmem); 721 MOS_ZeroMemory(dmem, sizeof(VdencAv1HucBrcUpdateDmem)); 722 723 dmem->UPD_MaxNumPAKs = params.passNum; 724 dmem->UPD_PAKPassNum = params.currentPass; 725 dmem->UPD_SegMapGenerating = 0; 726 727 SetDmemForUpdate(dmem); 728 729 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(params.hucDataSource)); 730 731 break; 732 } 733 case PAK_INTEGRATE: { 734 // nothing need to be done within brc feature for pak int 735 break; 736 } 737 default: 738 ENCODE_ASSERTMESSAGE("AV1 BRC feature supports only PAK_INTEGRATE, BRC_INIT and BRC_UPDATE HUC functions"); 739 return MOS_STATUS_INVALID_PARAMETER; 740 } 741 742 return MOS_STATUS_SUCCESS; 743 } 744 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,Av1Brc)745 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, Av1Brc) 746 { 747 if (params.function == BRC_UPDATE) 748 { 749 const PMOS_RESOURCE brcConstDataBuffer = params.regionParams[5].presRegion; 750 751 auto hucConstData = (VdencAv1HucBrcConstantData *)m_allocator->LockResourceForWrite(brcConstDataBuffer); 752 ENCODE_CHK_NULL_RETURN(hucConstData); 753 754 SetConstForUpdate(hucConstData); 755 756 m_allocator->UnLock(brcConstDataBuffer); 757 } 758 759 return MOS_STATUS_SUCCESS; 760 } 761 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,Av1Brc)762 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, Av1Brc) 763 { 764 if (m_brcEnabled) 765 { 766 params.frameStatisticsStreamOut = true; 767 } 768 769 return MOS_STATUS_SUCCESS; 770 } 771 772 } // namespace encode 773