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_avc_brc.cpp
24 //! \brief Defines the common interface for avc brc features
25 //!
26
27 #include "encode_avc_brc.h"
28 #include "encode_avc_vdenc_feature_manager.h"
29 #include "encode_avc_vdenc_const_settings.h"
30 #include "encode_avc_huc_brc_init_packet.h"
31 #include "encode_avc_huc_brc_update_packet.h"
32 #include "encode_avc_basic_feature.h"
33
34 namespace encode
35 {
36
37 #define ENCODE_AVC_BRC_MIN_QP 1
38 #define VDENC_AVC_BRC_MIN_QP 10
39 #define VDENC_AVC_BPS_RATIO_LOW 0.1
40 #define VDENC_AVC_BPS_RATIO_HIGH 3.5
41 #define ENCODE_AVC_VDENC_MIN_ICQ_QUALITYFACTOR 11
42
43 //dynamic deviation thresholds calculation
44 #define VDENC_AVC_POS_MULT_I 50
45 #define VDENC_AVC_NEG_MULT_I -50
46 #define VDENC_AVC_POS_MULT_PB 50
47 #define VDENC_AVC_NEG_MULT_PB -50
48 #define VDENC_AVC_POS_MULT_VBR 100
49 #define VDENC_AVC_NEG_MULT_VBR -50
50
51 #define VDENC_AVC_BRC_TOPQPDELTATHRFORADAPT2PASS 2
52 #define VDENC_AVC_BRC_BOTQPDELTATHRFORADAPT2PASS 1
53 #define VDENC_AVC_BRC_TOPFRMSZTHRFORADAPT2PASS 32
54 #define VDENC_AVC_BRC_BOTFRMSZTHRFORADAPT2PASS 24
55
56 #define VDENC_AVC_AVBR_TOPQPDELTATHRFORADAPT2PASS 2
57 #define VDENC_AVC_AVBR_BOTQPDELTATHRFORADAPT2PASS 2
58 #define VDENC_AVC_AVBR_TOPFRMSZTHRFORADAPT2PASS 48
59 #define VDENC_AVC_AVBR_BOTFRMSZTHRFORADAPT2PASS 32
60
61 #define VDENC_AVC_BRC_TOPQPDELTATHRFORADAPT2PASS_4K 5
62 #define VDENC_AVC_BRC_BOTQPDELTATHRFORADAPT2PASS_4K 5
63 #define VDENC_AVC_BRC_TOPFRMSZTHRFORADAPT2PASS_4K 80
64 #define VDENC_AVC_BRC_BOTFRMSZTHRFORADAPT2PASS_4K 80
65
66 // VDEnc BRC Flag in BRC Init Kernel
67 typedef enum _BRCFLAG
68 {
69 BRCFLAG_ISICQ = 0x0000,
70 BRCFLAG_ISCBR = 0x0010,
71 BRCFLAG_ISVBR = 0x0020,
72 BRCFLAG_ISVCM = 0x0040,
73 BRCFLAG_ISLOWDELAY = 0x0080
74 } BRCFLAG;
75
AvcEncodeBRC(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)76 AvcEncodeBRC::AvcEncodeBRC(
77 MediaFeatureManager *featureManager,
78 EncodeAllocator *allocator,
79 CodechalHwInterfaceNext *hwInterface,
80 void *constSettings) :
81 MediaFeature(constSettings, hwInterface ? hwInterface->GetOsInterface() : nullptr),
82 m_hwInterface(hwInterface),
83 m_allocator(allocator)
84 {
85 m_featureManager = featureManager;
86 //TODO: can be optimized after move encode parameter to feature manager.
87 auto encFeatureManager = dynamic_cast<EncodeAvcVdencFeatureManager*>(featureManager);
88 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
89
90 m_basicFeature = dynamic_cast<AvcBasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature));
91 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
92
93 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hwInterface);
94 m_vdencItf = std::static_pointer_cast<mhw::vdbox::vdenc::Itf>(m_hwInterface->GetVdencInterfaceNext());
95 m_mfxItf = std::static_pointer_cast<mhw::vdbox::mfx::Itf>(m_hwInterface->GetMfxInterfaceNext());
96 m_miItf = std::static_pointer_cast<mhw::mi::Itf>(m_hwInterface->GetMiInterfaceNext());
97 }
98
~AvcEncodeBRC()99 AvcEncodeBRC::~AvcEncodeBRC()
100 {
101 FreeBrcResources();
102 }
103
Init(void * setting)104 MOS_STATUS AvcEncodeBRC::Init(void *setting)
105 {
106 ENCODE_FUNC_CALL();
107
108 MediaUserSetting::Value outValue;
109 ReadUserSetting(
110 m_userSettingPtr,
111 outValue,
112 "AVC Encode MB BRC",
113 MediaUserSetting::Group::Sequence);
114
115 int32_t val = outValue.Get<int32_t>();
116 if ((val == 0) || (val == 1))
117 {
118 m_mbBrcUserFeatureKeyControl = true;
119 m_mbBrcEnabled = val ? true : false;
120 }
121
122 outValue = 0;
123
124 ReadUserSetting(
125 m_userSettingPtr,
126 outValue,
127 "VDEnc Single Pass Enable",
128 MediaUserSetting::Group::Sequence);
129
130 m_vdencSinglePassEnable = outValue.Get<int32_t>() == 1;
131
132 #if (_DEBUG || _RELEASE_INTERNAL)
133 auto statusKey = ReadUserSettingForDebug(
134 m_userSettingPtr,
135 outValue,
136 "Lpla TargetBufferFulness Data Address",
137 MediaUserSetting::Group::Sequence);
138 const char *path_buffer = outValue.ConstString().c_str();
139
140 if (statusKey == MOS_STATUS_SUCCESS && strcmp(path_buffer, "") != 0)
141 m_useBufferFulnessData = true;
142
143 if (m_useBufferFulnessData)
144 {
145 std::ifstream fp(path_buffer);
146 if (!fp.is_open())
147 {
148 m_useBufferFulnessData = false;
149 ENCODE_ASSERTMESSAGE("lpla targetBufferFulness data load failed!");
150 }
151 int cnt = 0;
152 std::string line = "";
153 while (getline(fp, line))
154 {
155 m_bufferFulnessData_csv[cnt++] = atoi(line.c_str());
156 }
157 }
158 #endif
159
160 ENCODE_CHK_STATUS_RETURN(AllocateResources());
161
162 return MOS_STATUS_SUCCESS;
163 }
164
Update(void * params)165 MOS_STATUS AvcEncodeBRC::Update(void *params)
166 {
167 ENCODE_FUNC_CALL();
168 ENCODE_CHK_NULL_RETURN(params);
169
170 EncoderParams *encodeParams = (EncoderParams *)params;
171
172 ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
173
174 if (m_basicFeature->m_seqParam->RateControlMethod == RATECONTROL_VCM && m_basicFeature->m_pictureCodingType == B_TYPE)
175 {
176 ENCODE_ASSERTMESSAGE("VCM BRC mode does not support B-frames\n");
177 return MOS_STATUS_INVALID_PARAMETER;
178 }
179
180 if (m_basicFeature->m_seqParam->RateControlMethod == RATECONTROL_VCM &&
181 (m_basicFeature->m_picParam->FieldCodingFlag || m_basicFeature->m_picParam->FieldFrameCodingFlag))
182 {
183 ENCODE_ASSERTMESSAGE("VCM BRC mode does not support interlaced\n");
184 return MOS_STATUS_INVALID_PARAMETER;
185 }
186
187 #if (_DEBUG || _RELEASE_INTERNAL)
188 ReportUserSettingForDebug(
189 m_userSettingPtr,
190 "Encode RateControl Method",
191 m_rcMode,
192 MediaUserSetting::Group::Sequence);
193 #endif
194 return MOS_STATUS_SUCCESS;
195 }
196
AllocateResources()197 MOS_STATUS AvcEncodeBRC::AllocateResources()
198 {
199 ENCODE_FUNC_CALL();
200
201 ENCODE_CHK_NULL_RETURN(m_allocator);
202 ENCODE_CHK_NULL_RETURN(m_basicFeature);
203 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf);
204 ENCODE_CHK_NULL_RETURN(m_hwInterface);
205 ENCODE_CHK_NULL_RETURN(m_hwInterface->GetOsInterface());
206
207 auto setting = static_cast<AvcVdencFeatureSettings *>(m_constSettings);
208 ENCODE_CHK_NULL_RETURN(setting);
209
210 auto brcSettings = setting->brcSettings;
211
212 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
213 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
214 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
215 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
216 allocParamsForBufferLinear.Format = Format_Buffer;
217
218 // VDENC Statistics buffer
219 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(brcSettings.vdencBrcStatsBufferSize, CODECHAL_PAGE_SIZE);
220 allocParamsForBufferLinear.pBufName = "VDENC BRC Statistics Buffer";
221 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
222 ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_recycleBuf->RegisterResource(VdencStatsBuffer, allocParamsForBufferLinear, 1));
223
224 // VDENC BRC PAK MMIO buffer
225 allocParamsForBufferLinear.dwBytes = sizeof(VdencBrcPakMmio);
226 allocParamsForBufferLinear.pBufName = "VDENC BRC PAK MMIO Buffer";
227 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
228 ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_recycleBuf->RegisterResource(VdencBrcPakMmioBuffer, allocParamsForBufferLinear, 1));
229
230 // Debug buffer
231 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(brcSettings.vdencBrcDbgBufferSize, CODECHAL_PAGE_SIZE);
232 allocParamsForBufferLinear.pBufName = "VDENC BRC Debug Buffer";
233 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
234 ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_recycleBuf->RegisterResource(VdencBrcDebugBuffer, allocParamsForBufferLinear, 1));
235
236 // BRC history buffer
237 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(brcSettings.vdencBrcHistoryBufferSize, CODECHAL_PAGE_SIZE);
238 allocParamsForBufferLinear.pBufName = "VDENC BRC History Buffer";
239 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
240 ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_recycleBuf->RegisterResource(VdencBRCHistoryBuffer, allocParamsForBufferLinear, 1));
241
242 // VDENC uses second level batch buffer for image state cmds
243 MOS_ZeroMemory(&m_batchBufferForVdencImgStat, sizeof(MHW_BATCH_BUFFER));
244 m_batchBufferForVdencImgStat.bSecondLevel = true;
245 ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
246 m_hwInterface->GetOsInterface(),
247 &m_batchBufferForVdencImgStat,
248 nullptr,
249 GetVdencBRCImgStateBufferSize()));
250
251 return MOS_STATUS_SUCCESS;
252 }
253
SetDmemForInit(void * params)254 MOS_STATUS AvcEncodeBRC::SetDmemForInit(void *params)
255 {
256 ENCODE_FUNC_CALL();
257
258 ENCODE_CHK_NULL_RETURN(params);
259 auto hucVdencBrcInitDmem =(VdencAvcHucBrcInitDmem*)params;
260 static_assert(sizeof(VdencAvcHucBrcInitDmem) == 192, "VdencAvcHucBrcInitDmem size MUST be equal to 192");
261
262 auto setting = static_cast<AvcVdencFeatureSettings *>(m_constSettings);
263 ENCODE_CHK_NULL_RETURN(setting);
264
265 auto brcSettings = setting->brcSettings;
266 auto avcSeqParams = m_basicFeature->m_seqParam;
267 auto avcPicParams = m_basicFeature->m_picParam;
268
269 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) // Low Delay Mode
270 {
271 avcSeqParams->MaxBitRate = avcSeqParams->TargetBitRate;
272 }
273
274 m_dBrcInitResetInputBitsPerFrame = avcSeqParams->MaxBitRate * 100.0 / avcSeqParams->FramesPer100Sec;
275 m_dBrcInitCurrentTargetBufFullInBits = m_dBrcInitResetInputBitsPerFrame;
276 m_dBrcTargetSize = avcSeqParams->InitVBVBufferFullnessInBit;
277
278 hucVdencBrcInitDmem->BRCFunc_U8 = m_brcInit ? 0 : 2; // 0 for init, 2 for reset
279
280 hucVdencBrcInitDmem->INIT_FrameWidth_U16 = (uint16_t)m_basicFeature->m_frameWidth;
281 hucVdencBrcInitDmem->INIT_FrameHeight_U16 = (uint16_t)m_basicFeature->m_frameHeight;
282
283 hucVdencBrcInitDmem->INIT_TargetBitrate_U32 = avcSeqParams->TargetBitRate;
284 hucVdencBrcInitDmem->INIT_MinRate_U32 = avcSeqParams->MinBitRate;
285 hucVdencBrcInitDmem->INIT_MaxRate_U32 = avcSeqParams->MaxBitRate;
286 hucVdencBrcInitDmem->INIT_BufSize_U32 = avcSeqParams->VBVBufferSizeInBit;
287 hucVdencBrcInitDmem->INIT_InitBufFull_U32 = avcSeqParams->InitVBVBufferFullnessInBit;
288
289 if (hucVdencBrcInitDmem->INIT_InitBufFull_U32 > avcSeqParams->VBVBufferSizeInBit)
290 hucVdencBrcInitDmem->INIT_InitBufFull_U32 = avcSeqParams->VBVBufferSizeInBit;
291
292 switch (avcSeqParams->RateControlMethod)
293 {
294 case RATECONTROL_CBR:
295 hucVdencBrcInitDmem->INIT_BRCFlag_U16 |= BRCFLAG_ISCBR;
296 break;
297 case RATECONTROL_VBR:
298 hucVdencBrcInitDmem->INIT_BRCFlag_U16 |= BRCFLAG_ISVBR;
299 break;
300 case RATECONTROL_QVBR:
301 // QVBR will use VBR BRCFlag, triggered when ICQQualityFactor > 10
302 hucVdencBrcInitDmem->INIT_BRCFlag_U16 |= BRCFLAG_ISVBR;
303 break;
304 // Temp solution using AVBR for low delay case, before the BRC flag is added to DDI
305 case RATECONTROL_AVBR:
306 hucVdencBrcInitDmem->INIT_BRCFlag_U16 |= BRCFLAG_ISLOWDELAY;
307 break;
308 case RATECONTROL_ICQ:
309 hucVdencBrcInitDmem->INIT_BRCFlag_U16 |= BRCFLAG_ISICQ;
310 break;
311 case RATECONTROL_VCM:
312 hucVdencBrcInitDmem->INIT_BRCFlag_U16 |= BRCFLAG_ISVCM;
313 break;
314 default:
315 break;
316 }
317
318 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) // Low Delay Mode
319 {
320 hucVdencBrcInitDmem->INIT_BRCFlag_U16 = BRCFLAG_ISLOWDELAY;
321 hucVdencBrcInitDmem->INIT_LowDelayGoldenFrameBoost_U8 = 0; //get from ?
322 }
323
324 hucVdencBrcInitDmem->INIT_FrameRateM_U32 = avcSeqParams->FramesPer100Sec;
325 hucVdencBrcInitDmem->INIT_FrameRateD_U32 = 100;
326
327 hucVdencBrcInitDmem->INIT_ProfileLevelMaxFrame_U32 = m_basicFeature->GetProfileLevelMaxFrameSize();
328
329 if (avcSeqParams->GopRefDist && (avcSeqParams->GopPicSize > 0))
330 {
331 uint16_t intraPeriod = avcSeqParams->GopPicSize - 1;
332 if (intraPeriod % avcSeqParams->GopRefDist != 0)
333 {
334 // Implement original cmodel behavior: use only complete Gop (for intraPeriod=6, GopRefDist=4 => intraPeriod must be 4)
335 intraPeriod -= intraPeriod % avcSeqParams->GopRefDist;
336 }
337
338 hucVdencBrcInitDmem->INIT_GopP_U16 = intraPeriod / avcSeqParams->GopRefDist;
339 hucVdencBrcInitDmem->INIT_GopB_U16 = (avcSeqParams->GopRefDist - 1) * hucVdencBrcInitDmem->INIT_GopP_U16;
340
341 if (avcSeqParams->GopRefDist >= avcSeqParams->GopPicSize && avcSeqParams->GopPicSize > 1)
342 {
343 hucVdencBrcInitDmem->INIT_ExtGopP_U16 = 1;
344 hucVdencBrcInitDmem->INIT_ExtGopB_U16 = avcSeqParams->GopPicSize - 2;
345 }
346 else if (IsBPyramidWithGoldenBGOP()) // For now AVC support only GOP4 and GOP8 golden gops
347 {
348 auto dmem = hucVdencBrcInitDmem;
349 uint8_t BGopSize = (uint8_t)avcSeqParams->GopRefDist;
350
351 dmem->INIT_ExtGopP_U16 = (uint16_t)(intraPeriod / BGopSize);
352 dmem->INIT_ExtGopB_U16 = BGopSize > 1 ? (uint16_t)dmem->INIT_ExtGopP_U16 : 0;
353
354 uint16_t gopB1Multiplicator = (BGopSize > 2 ? 1 : 0) +
355 (BGopSize == 4 || BGopSize > 5 ? 1 : 0);
356 uint16_t gopB2Multiplicator = (BGopSize > 3 ? 1 : 0);
357
358 dmem->INIT_ExtGopB1_U16 = dmem->INIT_ExtGopP_U16 * gopB1Multiplicator;
359 dmem->INIT_ExtGopB2_U16 = (intraPeriod - dmem->INIT_ExtGopP_U16 - dmem->INIT_ExtGopB_U16 - dmem->INIT_ExtGopB1_U16) * gopB2Multiplicator;
360 dmem->INIT_ExtMaxBrcLevel_U8 = dmem->INIT_ExtGopB1_U16 == 0 ? 2 :
361 (dmem->INIT_ExtGopB2_U16 == 0 ? AvcBrcFrameType::B1_FRAME : AvcBrcFrameType::B2_FRAME);
362 ENCODE_CHK_COND_RETURN(BGopSize != (1 << (dmem->INIT_ExtMaxBrcLevel_U8 - 1)),
363 "'BGopSize' (GopRefDist) must be equal '1 << (dmem->INIT_MaxBrcLevel_U16 - 1)'");
364 }
365 else
366 {
367 hucVdencBrcInitDmem->INIT_ExtGopP_U16 = hucVdencBrcInitDmem->INIT_GopP_U16;
368 hucVdencBrcInitDmem->INIT_ExtGopB_U16 = hucVdencBrcInitDmem->INIT_GopB_U16;
369
370 hucVdencBrcInitDmem->INIT_ExtGopB1_U16 = hucVdencBrcInitDmem->INIT_ExtGopB2_U16 = hucVdencBrcInitDmem->INIT_ExtMaxBrcLevel_U8 = 0;
371 }
372 }
373
374 if (m_basicFeature->m_minMaxQpControlEnabled)
375 {
376 hucVdencBrcInitDmem->INIT_MinQP_U16 = m_basicFeature->m_iMinQp;
377 hucVdencBrcInitDmem->INIT_MaxQP_U16 = m_basicFeature->m_iMaxQp;
378 }
379 else
380 {
381 hucVdencBrcInitDmem->INIT_MinQP_U16 = VDENC_AVC_BRC_MIN_QP; // Setting values from arch spec
382 hucVdencBrcInitDmem->INIT_MaxQP_U16 = CODECHAL_ENCODE_AVC_MAX_SLICE_QP; // Setting values from arch spec
383 }
384
385 //dynamic deviation thresholds
386 double inputBitsPerFrame = avcSeqParams->MaxBitRate * 100.0 / avcSeqParams->FramesPer100Sec;
387 double bps_ratio = inputBitsPerFrame / (avcSeqParams->VBVBufferSizeInBit * 100.0 / avcSeqParams->FramesPer100Sec/*DEV_STD_FPS*/);
388 if (bps_ratio < VDENC_AVC_BPS_RATIO_LOW) bps_ratio = VDENC_AVC_BPS_RATIO_LOW;
389 if (bps_ratio > VDENC_AVC_BPS_RATIO_HIGH) bps_ratio = VDENC_AVC_BPS_RATIO_HIGH;
390
391 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) // Low Delay Mode
392 {
393 MOS_SecureMemcpy(hucVdencBrcInitDmem->INIT_DevThreshPB0_S8, 8 * sizeof(int8_t),
394 brcSettings.BRC_LowDelay_DevThreshPB0_S8, 8 * sizeof(int8_t));
395 MOS_SecureMemcpy(hucVdencBrcInitDmem->INIT_DevThreshI0_S8, 8 * sizeof(int8_t),
396 brcSettings.BRC_LowDelay_DevThreshI0_S8, 8 * sizeof(int8_t));
397 MOS_SecureMemcpy(hucVdencBrcInitDmem->INIT_DevThreshVBR0_S8, 8 * sizeof(int8_t),
398 brcSettings.BRC_LowDelay_DevThreshVBR0_S8, 8 * sizeof(int8_t));
399 }
400 else
401 {
402 //dynamic deviation thresholds
403 for (int i = 0; i < AvcVdencBrcConstSettings::m_numDevThreshlds / 2; i++)
404 {
405 hucVdencBrcInitDmem->INIT_DevThreshPB0_S8[i] =
406 (int8_t)(VDENC_AVC_NEG_MULT_PB * pow(brcSettings.BRC_DevThreshPB0_FP_NEG[i], bps_ratio));
407 hucVdencBrcInitDmem->INIT_DevThreshPB0_S8[i + AvcVdencBrcConstSettings::m_numDevThreshlds / 2] =
408 (int8_t)(VDENC_AVC_POS_MULT_PB * pow(brcSettings.BRC_DevThreshPB0_FP_POS[i], bps_ratio));
409
410 hucVdencBrcInitDmem->INIT_DevThreshI0_S8[i] =
411 (int8_t)(VDENC_AVC_NEG_MULT_I * pow(brcSettings.BRC_DevThreshI0_FP_NEG[i], bps_ratio));
412 hucVdencBrcInitDmem->INIT_DevThreshI0_S8[i + AvcVdencBrcConstSettings::m_numDevThreshlds / 2] =
413 (int8_t)(VDENC_AVC_POS_MULT_I * pow(brcSettings.BRC_DevThreshI0_FP_POS[i], bps_ratio));
414
415 hucVdencBrcInitDmem->INIT_DevThreshVBR0_S8[i] =
416 (int8_t)(VDENC_AVC_NEG_MULT_VBR * pow(brcSettings.BRC_DevThreshVBR0_NEG[i], bps_ratio));
417 hucVdencBrcInitDmem->INIT_DevThreshVBR0_S8[i + AvcVdencBrcConstSettings::m_numDevThreshlds / 2] =
418 (int8_t)(VDENC_AVC_POS_MULT_VBR * pow(brcSettings.BRC_DevThreshVBR0_POS[i], bps_ratio));
419 }
420 }
421
422 hucVdencBrcInitDmem->INIT_InitQPIP = (uint8_t)ComputeBRCInitQP();
423
424 // MBBRC control
425 if (m_mbBrcEnabled)
426 {
427 hucVdencBrcInitDmem->INIT_MbQpCtrl_U8 = 1;
428 MOS_SecureMemcpy(hucVdencBrcInitDmem->INIT_DistQPDelta_I8, 4 * sizeof(int8_t),
429 brcSettings.BRC_INIT_DistQPDelta_I8, 4 * sizeof(int8_t));
430 }
431
432 hucVdencBrcInitDmem->INIT_SliceSizeCtrlEn_U8 = avcSeqParams->EnableSliceLevelRateCtrl; // Enable slice size control
433
434 hucVdencBrcInitDmem->INIT_OscillationQpDelta_U8 =
435 ((avcSeqParams->RateControlMethod == RATECONTROL_VCM) || (avcSeqParams->RateControlMethod == RATECONTROL_QVBR)) ? 16 : 0;
436 hucVdencBrcInitDmem->INIT_HRDConformanceCheckDisable_U8 =
437 ((avcSeqParams->RateControlMethod == RATECONTROL_VCM) || (avcSeqParams->RateControlMethod == RATECONTROL_AVBR)) ? 1 : 0;
438
439 // Adaptive 2nd re-encode pass
440 if (m_basicFeature->m_picWidthInMb * m_basicFeature->m_picHeightInMb >= ((3840 * 2160) >> 8)) // >= 4K
441 {
442 hucVdencBrcInitDmem->INIT_TopQPDeltaThrForAdapt2Pass_U8 = VDENC_AVC_BRC_TOPQPDELTATHRFORADAPT2PASS_4K;
443 hucVdencBrcInitDmem->INIT_BotQPDeltaThrForAdapt2Pass_U8 = VDENC_AVC_BRC_BOTQPDELTATHRFORADAPT2PASS_4K;
444 hucVdencBrcInitDmem->INIT_TopFrmSzThrForAdapt2Pass_U8 = VDENC_AVC_BRC_TOPFRMSZTHRFORADAPT2PASS_4K;
445 hucVdencBrcInitDmem->INIT_BotFrmSzThrForAdapt2Pass_U8 = VDENC_AVC_BRC_BOTFRMSZTHRFORADAPT2PASS_4K;
446 }
447 else
448 {
449 if (avcSeqParams->RateControlMethod == RATECONTROL_AVBR)
450 {
451 hucVdencBrcInitDmem->INIT_TopQPDeltaThrForAdapt2Pass_U8 = VDENC_AVC_AVBR_TOPQPDELTATHRFORADAPT2PASS;
452 hucVdencBrcInitDmem->INIT_BotQPDeltaThrForAdapt2Pass_U8 = VDENC_AVC_AVBR_BOTQPDELTATHRFORADAPT2PASS;
453 hucVdencBrcInitDmem->INIT_TopFrmSzThrForAdapt2Pass_U8 = VDENC_AVC_AVBR_TOPFRMSZTHRFORADAPT2PASS;
454 hucVdencBrcInitDmem->INIT_BotFrmSzThrForAdapt2Pass_U8 = VDENC_AVC_AVBR_BOTFRMSZTHRFORADAPT2PASS;
455 }
456 else
457 {
458 hucVdencBrcInitDmem->INIT_TopQPDeltaThrForAdapt2Pass_U8 = VDENC_AVC_BRC_TOPQPDELTATHRFORADAPT2PASS;
459 hucVdencBrcInitDmem->INIT_BotQPDeltaThrForAdapt2Pass_U8 = VDENC_AVC_BRC_BOTQPDELTATHRFORADAPT2PASS;
460 hucVdencBrcInitDmem->INIT_TopFrmSzThrForAdapt2Pass_U8 = VDENC_AVC_BRC_TOPFRMSZTHRFORADAPT2PASS;
461 hucVdencBrcInitDmem->INIT_BotFrmSzThrForAdapt2Pass_U8 = VDENC_AVC_BRC_BOTFRMSZTHRFORADAPT2PASS;
462 }
463 }
464
465 hucVdencBrcInitDmem->INIT_QPSelectForFirstPass_U8 = 1;
466 hucVdencBrcInitDmem->INIT_MBHeaderCompensation_U8 = 1;
467 hucVdencBrcInitDmem->INIT_DeltaQP_Adaptation_U8 = 1;
468 hucVdencBrcInitDmem->INIT_MaxCRFQualityFactor_U8 = CODECHAL_ENCODE_AVC_MAX_ICQ_QUALITYFACTOR + 1;
469
470 if (RATECONTROL_QVBR == avcSeqParams->RateControlMethod || RATECONTROL_ICQ == avcSeqParams->RateControlMethod)
471 {
472 hucVdencBrcInitDmem->INIT_CRFQualityFactor_U8 = (uint8_t)avcSeqParams->ICQQualityFactor;
473 hucVdencBrcInitDmem->INIT_ScenarioInfo_U8 = (RATECONTROL_QVBR == avcSeqParams->RateControlMethod) ? 1 : 0;
474 }
475
476 if (m_basicFeature->m_picParam->NumDirtyROI)
477 {
478 hucVdencBrcInitDmem->INIT_ScenarioInfo_U8 = 1; //DISPLAYREMOTING
479 }
480
481 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_LOW) // Sliding Window BRC
482 {
483 hucVdencBrcInitDmem->INIT_SlidingWidowRCEnable_U8 = 1;
484 if (avcSeqParams->RateControlMethod == RATECONTROL_CBR && avcSeqParams->TargetBitRate != 0)
485 {
486 hucVdencBrcInitDmem->INIT_SlidingWindowSize_U8 = MOS_MIN((uint8_t)avcSeqParams->SlidingWindowSize, 60);
487 hucVdencBrcInitDmem->INIT_SlidingWindowMaxRateRatio_U8 = (uint8_t)((uint64_t)avcSeqParams->MaxBitRatePerSlidingWindow * 100 / avcSeqParams->TargetBitRate);
488 }
489 else
490 {
491 hucVdencBrcInitDmem->INIT_SlidingWindowSize_U8 = (uint8_t)(avcSeqParams->FramesPer100Sec / 100);
492 hucVdencBrcInitDmem->INIT_SlidingWindowMaxRateRatio_U8 = 120;
493 }
494 }
495
496 MOS_SecureMemcpy(hucVdencBrcInitDmem->INIT_EstRateThreshP0_U8, 7 * sizeof(uint8_t),
497 brcSettings.BRC_EstRateThreshP0_U8, 7 * sizeof(uint8_t));
498 MOS_SecureMemcpy(hucVdencBrcInitDmem->INIT_EstRateThreshI0_U8, 7 * sizeof(uint8_t),
499 brcSettings.BRC_EstRateThreshI0_U8, 7 * sizeof(uint8_t));
500
501 // fractional QP enable for extended rho domain
502 hucVdencBrcInitDmem->INIT_FracQPEnable_U8 = (uint8_t)m_vdencItf->IsRhoDomainStatsEnabled();
503
504 // force enabling fractional QP and disabling HRD conformance for TCBRC
505 if ((avcPicParams->TargetFrameSize > 0) && (m_basicFeature->m_lookaheadDepth == 0))
506 {
507 hucVdencBrcInitDmem->INIT_FracQPEnable_U8 = 1;
508 hucVdencBrcInitDmem->INIT_HRDConformanceCheckDisable_U8 = 1;
509 }
510
511 hucVdencBrcInitDmem->INIT_SinglePassOnly = (uint8_t)m_vdencSinglePassEnable;
512
513 if (avcSeqParams->ScenarioInfo == ESCENARIO_GAMESTREAMING)
514 {
515 if (avcSeqParams->RateControlMethod == RATECONTROL_VBR)
516 {
517 avcSeqParams->MaxBitRate = avcSeqParams->TargetBitRate;
518 }
519
520 // Disable delta QP adaption for non-VCM/ICQ/LowDelay until we have better algorithm
521 if ((avcSeqParams->RateControlMethod != RATECONTROL_VCM) &&
522 (avcSeqParams->RateControlMethod != RATECONTROL_ICQ) &&
523 (avcSeqParams->FrameSizeTolerance != EFRAMESIZETOL_EXTREMELY_LOW))
524 {
525 hucVdencBrcInitDmem->INIT_DeltaQP_Adaptation_U8 = 0;
526 }
527
528 hucVdencBrcInitDmem->INIT_New_DeltaQP_Adaptation_U8 = 1;
529 }
530
531 if (((avcSeqParams->TargetUsage & 0x07) == TARGETUSAGE_BEST_SPEED) &&
532 (avcSeqParams->FrameWidth >= setting->singlePassMinFrameWidth) &&
533 (avcSeqParams->FrameHeight >= setting->singlePassMinFrameHeight) &&
534 (avcSeqParams->FramesPer100Sec >= setting->singlePassMinFramePer100s))
535 {
536 hucVdencBrcInitDmem->INIT_SinglePassOnly = true;
537 }
538
539 hucVdencBrcInitDmem->INIT_LookaheadDepth_U8 = m_basicFeature->m_lookaheadDepth;
540
541 //Override the DistQPDelta setting
542 if (m_mbBrcEnabled)
543 {
544 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW)
545 {
546 MOS_SecureMemcpy(hucVdencBrcInitDmem->INIT_DistQPDelta_I8, 4 * sizeof(int8_t),
547 brcSettings.brcInitDistQpDeltaI8LowDelay, 4 * sizeof(int8_t));
548 }
549 else
550 {
551 MOS_SecureMemcpy(hucVdencBrcInitDmem->INIT_DistQPDelta_I8, 4 * sizeof(int8_t),
552 brcSettings.brcInitDistQpDeltaI8, 4 * sizeof(int8_t));
553 }
554 }
555
556 return MOS_STATUS_SUCCESS;
557 }
558
SetDmemForUpdate(void * params,uint16_t currPass,bool bIsLastPass)559 MOS_STATUS AvcEncodeBRC::SetDmemForUpdate(void *params, uint16_t currPass, bool bIsLastPass)
560 {
561 ENCODE_FUNC_CALL();
562
563 ENCODE_CHK_NULL_RETURN(params);
564 auto hucVdencBrcUpdateDmem =(VdencAvcHucBrcUpdateDmem*)params;
565 static_assert(sizeof(VdencAvcHucBrcUpdateDmem) == 448, "VdencAvcHucBrcUpdateDmem size MUST be equal to 448");
566
567 auto setting = static_cast<AvcVdencFeatureSettings *>(m_constSettings);
568 ENCODE_CHK_NULL_RETURN(setting);
569
570 auto brcSettings = setting->brcSettings;
571 auto avcSeqParams = m_basicFeature->m_seqParam;
572 auto avcPicParams = m_basicFeature->m_picParam;
573
574 hucVdencBrcUpdateDmem->BRCFunc_U8 = 1; // Update:1
575
576 if (!m_brcInit && (currPass == 0))
577 {
578 m_brcInitPreviousTargetBufFullInBits = (uint32_t)(m_dBrcInitCurrentTargetBufFullInBits);
579 m_dBrcInitCurrentTargetBufFullInBits += m_dBrcInitResetInputBitsPerFrame;
580 m_dBrcTargetSize += m_dBrcInitResetInputBitsPerFrame;
581 }
582
583 if (m_dBrcTargetSize > avcSeqParams->VBVBufferSizeInBit)
584 {
585 m_dBrcTargetSize -= avcSeqParams->VBVBufferSizeInBit;
586 }
587
588 hucVdencBrcUpdateDmem->UPD_FRAMENUM_U32 = m_basicFeature->m_frameNum;
589 hucVdencBrcUpdateDmem->UPD_TARGETSIZE_U32 = (uint32_t)(m_dBrcTargetSize);
590 hucVdencBrcUpdateDmem->UPD_PeakTxBitsPerFrame_U32 = (uint32_t)(m_dBrcInitCurrentTargetBufFullInBits - m_brcInitPreviousTargetBufFullInBits);
591
592 //Dynamic slice size control
593 if (avcSeqParams->EnableSliceLevelRateCtrl)
594 {
595 hucVdencBrcUpdateDmem->UPD_SLCSZ_TARGETSLCSZ_U16 = (uint16_t)avcPicParams->SliceSizeInBytes; // target slice size
596 hucVdencBrcUpdateDmem->UPD_TargetSliceSize_U16 = (uint16_t)avcPicParams->SliceSizeInBytes; // set max slice size to be same as target slice size
597 hucVdencBrcUpdateDmem->UPD_MaxNumSliceAllowed_U16 = (uint16_t)m_basicFeature->m_maxNumSlicesAllowed;
598
599 for (uint8_t k = 0; k < 42; k++)
600 {
601 hucVdencBrcUpdateDmem->UPD_SLCSZ_UPD_THRDELTAI_U16[k] = MOS_MIN(avcPicParams->SliceSizeInBytes - 150, setting->SliceSizeThrsholdsI[k + 10]);
602 hucVdencBrcUpdateDmem->UPD_SLCSZ_UPD_THRDELTAP_U16[k] = MOS_MIN(avcPicParams->SliceSizeInBytes - 150, setting->SliceSizeThrsholdsP[k + 10]);
603 }
604 }
605 else
606 {
607 hucVdencBrcUpdateDmem->UPD_SLCSZ_TARGETSLCSZ_U16 = 0;
608 hucVdencBrcUpdateDmem->UPD_TargetSliceSize_U16 = 0;
609 hucVdencBrcUpdateDmem->UPD_MaxNumSliceAllowed_U16 = 0;
610
611 for (uint8_t k = 0; k < 42; k++)
612 {
613 hucVdencBrcUpdateDmem->UPD_SLCSZ_UPD_THRDELTAI_U16[k] = 0;
614 hucVdencBrcUpdateDmem->UPD_SLCSZ_UPD_THRDELTAP_U16[k] = 0;
615 }
616 }
617
618 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_LOW) // Sliding Window BRC
619 {
620 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->UPD_gRateRatioThreshold_U8, 7 * sizeof(uint8_t),
621 brcSettings.BRC_UPD_slwin_global_rate_ratio_threshold, 7 * sizeof(uint8_t));
622 }
623 else
624 {
625 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->UPD_gRateRatioThreshold_U8, 7 * sizeof(uint8_t),
626 brcSettings.BRC_UPD_global_rate_ratio_threshold, 7 * sizeof(uint8_t));
627 }
628
629 SetFrameTypeForUpdate(hucVdencBrcUpdateDmem, currPass);
630
631 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->UPD_startGAdjFrame_U16, 4 * sizeof(uint16_t),
632 brcSettings.BRC_UPD_start_global_adjust_frame, 4 * sizeof(uint16_t));
633 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->UPD_startGAdjMult_U8, 5 * sizeof(uint8_t),
634 brcSettings.BRC_UPD_start_global_adjust_mult, 5 * sizeof(uint8_t));
635 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->UPD_startGAdjDiv_U8, 5 * sizeof(uint8_t),
636 brcSettings.BRC_UPD_start_global_adjust_div, 5 * sizeof(uint8_t));
637 MOS_SecureMemcpy(hucVdencBrcUpdateDmem->UPD_gRateRatioThresholdQP_U8, 8 * sizeof(uint8_t),
638 brcSettings.BRC_UPD_global_rate_ratio_threshold_qp, 8 * sizeof(uint8_t));
639
640 hucVdencBrcUpdateDmem->UPD_PAKPassNum_U8 = (uint8_t)currPass;
641 hucVdencBrcUpdateDmem->UPD_MaxNumPass_U8 = m_featureManager->GetNumPass();
642
643 uint32_t numP = 0;
644 if (avcSeqParams->GopRefDist && (avcSeqParams->GopPicSize > 0))
645 {
646 numP = (avcSeqParams->GopPicSize - 1) / avcSeqParams->GopRefDist;
647 }
648
649 for (int32_t i = 0; i < 2; i++)
650 {
651 hucVdencBrcUpdateDmem->UPD_SceneChgWidth_U8[i] = (uint8_t)MOS_MIN((numP + 1) / 5, 6);
652 }
653
654 hucVdencBrcUpdateDmem->UPD_SceneChgDetectEn_U8 = 1;
655 hucVdencBrcUpdateDmem->UPD_SceneChgPrevIntraPctThreshold_U8 = 0x60;
656 hucVdencBrcUpdateDmem->UPD_SceneChgCurIntraPctThreshold_U8 = 0xc0;
657
658 hucVdencBrcUpdateDmem->UPD_IPAverageCoeff_U8 = (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) ? 0 : 0x80;
659
660 hucVdencBrcUpdateDmem->UPD_CQP_FracQp_U8 = 0;
661
662 if (avcSeqParams->RateControlMethod == RATECONTROL_ICQ)
663 {
664 hucVdencBrcUpdateDmem->UPD_CQP_QpValue_U8 = 18; //Cmodel suggested a few values to try: 18,20,26,30
665 }
666 else
667 {
668 hucVdencBrcUpdateDmem->UPD_CQP_QpValue_U8 = 0;
669 }
670
671 hucVdencBrcUpdateDmem->UPD_HMEDetectionEnable_U8 = 0;
672
673 if (FRAME_SKIP_NORMAL == m_basicFeature->m_skipFrameFlag)
674 {
675 hucVdencBrcUpdateDmem->UPD_SkipFrameSize_U16 = (uint16_t)avcPicParams->SizeSkipFrames;
676 hucVdencBrcUpdateDmem->UPD_NumOfFramesSkipped_U16 = (uint16_t)avcPicParams->NumSkipFrames;
677 }
678 else
679 {
680 hucVdencBrcUpdateDmem->UPD_SkipFrameSize_U16 = 0;
681 hucVdencBrcUpdateDmem->UPD_NumOfFramesSkipped_U16 = 0;
682 }
683
684 // HMECost enabled by default in CModel V11738+
685 hucVdencBrcUpdateDmem->UPD_HMECostEnable_U8 = 1;
686
687 // ROI and static region pct parameters
688 // must be zero if they are not used
689 hucVdencBrcUpdateDmem->UPD_RoiQpViaForceQp_U8 = 0;
690 hucVdencBrcUpdateDmem->UPD_StaticRegionPct_U16 = 0;
691 hucVdencBrcUpdateDmem->UPD_ROISource_U8 = 0;
692 if (avcPicParams->NumROI)
693 {
694 ENCODE_CHK_COND_RETURN(avcPicParams->NumROIDistinctDeltaQp > sizeof(hucVdencBrcUpdateDmem->UPD_ROIQpDelta_I8) - 1, "Number of ROI is greater that dmem roi array size");
695
696 hucVdencBrcUpdateDmem->UPD_RoiQpViaForceQp_U8 = avcPicParams->bNativeROI ? 0 : 1;
697 for (uint8_t i = 0; i < avcPicParams->NumROIDistinctDeltaQp; i++)
698 {
699 hucVdencBrcUpdateDmem->UPD_ROIQpDelta_I8[i + 1] = avcPicParams->ROIDistinctDeltaQp[i];
700 }
701 }
702 else if (avcPicParams->NumDirtyROI)
703 {
704 //hucVdencBrcUpdateDmem->UPD_StaticRegionPct_U16 = (uint16_t)m_vdencStaticRegionPct;
705 if (m_mbBrcEnabled)
706 {
707 hucVdencBrcUpdateDmem->UPD_ROISource_U8 = 2;
708 }
709 }
710
711 hucVdencBrcUpdateDmem->UPD_SLBB_Size_U16 = (uint16_t)MOS_ALIGN_CEIL(m_hwInterface->m_vdencBrcImgStateBufferSize, CODECHAL_CACHELINE_SIZE);
712
713 hucVdencBrcUpdateDmem->UPD_WidthInMB_U16 = m_basicFeature->m_picWidthInMb;
714 hucVdencBrcUpdateDmem->UPD_HeightInMB_U16 = m_basicFeature->m_picHeightInMb;
715
716 hucVdencBrcUpdateDmem->MOTION_ADAPTIVE_G4 = (avcSeqParams->ScenarioInfo == ESCENARIO_GAMESTREAMING) || ((avcPicParams->TargetFrameSize > 0) && (m_basicFeature->m_lookaheadDepth == 0)); // GS or TCBRC
717 hucVdencBrcUpdateDmem->UPD_CQMEnabled_U8 = avcSeqParams->seq_scaling_matrix_present_flag || avcPicParams->pic_scaling_matrix_present_flag;
718
719 hucVdencBrcUpdateDmem->UPD_LA_TargetSize_U32 = avcPicParams->TargetFrameSize << 3;
720 hucVdencBrcUpdateDmem->UPD_TCBRC_SCENARIO_U8 = 0; // Temporal fix because of DDI flag deprication. Use Cloud Gaming mode by default
721 hucVdencBrcUpdateDmem->UPD_NumSlicesForRounding = GetAdaptiveRoundingNumSlices();
722 hucVdencBrcUpdateDmem->UPD_UserMaxFramePB = avcSeqParams->UserMaxPBFrameSize;
723
724 if (avcSeqParams->LookaheadDepth == 0 && avcPicParams->TargetFrameSize > 0 &&
725 (hucVdencBrcUpdateDmem->UPD_TCBRC_SCENARIO_U8 == 2 || avcSeqParams->UserMaxPBFrameSize <= avcPicParams->TargetFrameSize * 2))
726 {
727 if (avcSeqParams->UserMaxPBFrameSize == 0)
728 {
729 hucVdencBrcUpdateDmem->UPD_UserMaxFramePB = 2 * avcPicParams->TargetFrameSize;
730 }
731
732 uint32_t inputbitsperframe = avcPicParams->TargetFrameSize << 3;
733
734 if (avcPicParams->CodingType == I_TYPE)
735 {
736 hucVdencBrcUpdateDmem->UPD_LA_TargetSize_U32 = inputbitsperframe + inputbitsperframe / 8;
737 }
738 else if (abs((int)(8 * hucVdencBrcUpdateDmem->UPD_UserMaxFramePB - inputbitsperframe)) <= 8)
739 {
740 hucVdencBrcUpdateDmem->UPD_LA_TargetSize_U32 = inputbitsperframe * 9 / 10;
741 }
742 else
743 {
744 hucVdencBrcUpdateDmem->UPD_LA_TargetSize_U32 = inputbitsperframe;
745 }
746 }
747
748 if (m_basicFeature->m_lookaheadDepth > 0)
749 {
750 DeltaQPUpdate(avcPicParams->QpModulationStrength, bIsLastPass);
751 hucVdencBrcUpdateDmem->EnableLookAhead = 1;
752 #if (_DEBUG || _RELEASE_INTERNAL)
753 hucVdencBrcUpdateDmem->UPD_LA_TargetFulness_U32 = m_useBufferFulnessData ? m_bufferFulnessData_csv[m_basicFeature->m_frameNum % m_bufferFulnessDataSize] : m_basicFeature->m_targetBufferFulness;
754 #else
755 hucVdencBrcUpdateDmem->UPD_LA_TargetFulness_U32 = m_basicFeature->m_targetBufferFulness;
756 #endif
757 hucVdencBrcUpdateDmem->UPD_Delta_U8 = m_qpModulationStrength;
758 }
759
760 return MOS_STATUS_SUCCESS;
761 }
762
FillHucConstData(uint8_t * data,uint8_t pictureType)763 MOS_STATUS AvcEncodeBRC::FillHucConstData(uint8_t *data, uint8_t pictureType)
764 {
765 auto hucConstData = (VdencAvcHucBrcConstantData*)data;
766
767 auto setting = static_cast<AvcVdencFeatureSettings *>(m_constSettings);
768 ENCODE_CHK_NULL_RETURN(setting);
769
770 auto brcSettings = setting->brcSettings;
771 auto avcSeqParams = m_basicFeature->m_seqParam;
772
773 MOS_SecureMemcpy(hucConstData->UPD_GlobalRateQPAdjTabI_U8, 64 * sizeof(uint8_t),
774 brcSettings.BRC_UPD_GlobalRateQPAdjTabI_U8, 64 * sizeof(uint8_t));
775 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_LOW) // Sliding Window BRC
776 {
777 MOS_SecureMemcpy(hucConstData->UPD_GlobalRateQPAdjTabP_U8, 64 * sizeof(uint8_t),
778 brcSettings.BRC_UPD_SlWinGlobalRateQPAdjTabP_U8, 64 * sizeof(uint8_t));
779 }
780 else
781 {
782 MOS_SecureMemcpy(hucConstData->UPD_GlobalRateQPAdjTabP_U8, 64 * sizeof(uint8_t),
783 brcSettings.BRC_UPD_GlobalRateQPAdjTabP_U8, 64 * sizeof(uint8_t));
784 }
785 MOS_SecureMemcpy(hucConstData->UPD_GlobalRateQPAdjTabB_U8, 64 * sizeof(uint8_t),
786 brcSettings.BRC_UPD_GlobalRateQPAdjTabB_U8, 64 * sizeof(uint8_t));
787
788 MOS_SecureMemcpy(hucConstData->UPD_DistThreshldI_U8, 10 * sizeof(uint8_t),
789 brcSettings.BRC_UPD_DistThreshldI_U8, 10 * sizeof(uint8_t));
790 MOS_SecureMemcpy(hucConstData->UPD_DistThreshldP_U8, 10 * sizeof(uint8_t),
791 brcSettings.BRC_UPD_DistThreshldP_U8, 10 * sizeof(uint8_t));
792 MOS_SecureMemcpy(hucConstData->UPD_DistThreshldB_U8, 10 * sizeof(uint8_t),
793 brcSettings.BRC_UPD_DistThreshldB_U8, 10 * sizeof(uint8_t));
794
795 if (avcSeqParams->RateControlMethod == RATECONTROL_CBR)
796 {
797 MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabI_U8, 81 * sizeof(uint8_t),
798 brcSettings.CBR_UPD_DistQPAdjTabI_U8, 81 * sizeof(int8_t));
799 MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabP_U8, 81 * sizeof(uint8_t),
800 brcSettings.CBR_UPD_DistQPAdjTabP_U8, 81 * sizeof(int8_t));
801 MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabB_U8, 81 * sizeof(uint8_t),
802 brcSettings.CBR_UPD_DistQPAdjTabB_U8, 81 * sizeof(int8_t));
803 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabI_S8, 72 * sizeof(uint8_t),
804 brcSettings.CBR_UPD_FrmSzAdjTabI_S8, 72 * sizeof(int8_t));
805 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabP_S8, 72 * sizeof(uint8_t),
806 brcSettings.CBR_UPD_FrmSzAdjTabP_S8, 72 * sizeof(int8_t));
807 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabB_S8, 72 * sizeof(uint8_t),
808 brcSettings.CBR_UPD_FrmSzAdjTabB_S8, 72 * sizeof(int8_t));
809 }
810 else
811 {
812 MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabI_U8, 81 * sizeof(uint8_t),
813 brcSettings.VBR_UPD_DistQPAdjTabI_U8, 81 * sizeof(int8_t));
814 MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabP_U8, 81 * sizeof(uint8_t),
815 brcSettings.VBR_UPD_DistQPAdjTabP_U8, 81 * sizeof(int8_t));
816 MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabB_U8, 81 * sizeof(uint8_t),
817 brcSettings.VBR_UPD_DistQPAdjTabB_U8, 81 * sizeof(int8_t));
818
819 if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) // Low Delay Mode
820 {
821 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabI_S8, 72 * sizeof(uint8_t),
822 brcSettings.LOW_DELAY_UPD_FrmSzAdjTabI_S8, 72 * sizeof(int8_t));
823 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabP_S8, 72 * sizeof(uint8_t),
824 brcSettings.LOW_DELAY_UPD_FrmSzAdjTabP_S8, 72 * sizeof(int8_t));
825 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabB_S8, 72 * sizeof(uint8_t),
826 brcSettings.LOW_DELAY_UPD_FrmSzAdjTabB_S8, 72 * sizeof(int8_t));
827 }
828 else
829 {
830 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabI_S8, 72 * sizeof(uint8_t),
831 brcSettings.VBR_UPD_FrmSzAdjTabI_S8, 72 * sizeof(int8_t));
832
833 if (avcSeqParams->RateControlMethod == RATECONTROL_QVBR)
834 {
835 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabP_S8, 72 * sizeof(uint8_t),
836 brcSettings.QVBR_UPD_FrmSzAdjTabP_S8, 72 * sizeof(int8_t));
837 }
838 else
839 {
840 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabP_S8, 72 * sizeof(uint8_t),
841 brcSettings.VBR_UPD_FrmSzAdjTabP_S8, 72 * sizeof(int8_t));
842 }
843
844 MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabB_S8, 72 * sizeof(uint8_t),
845 brcSettings.VBR_UPD_FrmSzAdjTabB_S8, 72 * sizeof(int8_t));
846 }
847 }
848
849 MOS_SecureMemcpy(hucConstData->UPD_FrmSzMinTabP_U8, 9 * sizeof(uint8_t), brcSettings.BRC_UPD_FrmSzMinTabP_U8, 9 * sizeof(uint8_t));
850 MOS_SecureMemcpy(hucConstData->UPD_FrmSzMinTabI_U8, 9 * sizeof(uint8_t), brcSettings.BRC_UPD_FrmSzMinTabI_U8, 9 * sizeof(uint8_t));
851
852 MOS_SecureMemcpy(hucConstData->UPD_FrmSzMaxTabP_U8, 9 * sizeof(uint8_t), brcSettings.BRC_UPD_FrmSzMaxTabP_U8, 9 * sizeof(uint8_t));
853 MOS_SecureMemcpy(hucConstData->UPD_FrmSzMaxTabI_U8, 9 * sizeof(uint8_t), brcSettings.BRC_UPD_FrmSzMaxTabI_U8, 9 * sizeof(uint8_t));
854
855 MOS_SecureMemcpy(hucConstData->UPD_FrmSzSCGTabP_U8, 9 * sizeof(uint8_t), brcSettings.BRC_UPD_FrmSzSCGTabP_U8, 9 * sizeof(uint8_t));
856 MOS_SecureMemcpy(hucConstData->UPD_FrmSzSCGTabI_U8, 9 * sizeof(uint8_t), brcSettings.BRC_UPD_FrmSzSCGTabI_U8, 9 * sizeof(uint8_t));
857
858 MOS_SecureMemcpy(hucConstData->UPD_I_IntraNonPred, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_I_IntraNonPred, 42 * sizeof(uint8_t));
859 MOS_SecureMemcpy(hucConstData->UPD_I_Intra8x8, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_I_Intra8x8, 42 * sizeof(uint8_t));
860 MOS_SecureMemcpy(hucConstData->UPD_I_Intra4x4, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_I_Intra4x4, 42 * sizeof(uint8_t));
861
862 MOS_SecureMemcpy(hucConstData->UPD_P_IntraNonPred, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_P_IntraNonPred, 42 * sizeof(uint8_t));
863 MOS_SecureMemcpy(hucConstData->UPD_P_Intra16x16, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_P_Intra16x16, 42 * sizeof(uint8_t));
864 MOS_SecureMemcpy(hucConstData->UPD_P_Intra8x8, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_P_Intra8x8, 42 * sizeof(uint8_t));
865 MOS_SecureMemcpy(hucConstData->UPD_P_Intra4x4, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_P_Intra4x4, 42 * sizeof(uint8_t));
866
867 MOS_SecureMemcpy(hucConstData->UPD_P_Inter16x8, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_P_Inter16x8, 42 * sizeof(uint8_t));
868 MOS_SecureMemcpy(hucConstData->UPD_P_Inter8x8, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_P_Inter8x8, 42 * sizeof(uint8_t));
869 MOS_SecureMemcpy(hucConstData->UPD_P_Inter16x16, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_P_Inter16x16, 42 * sizeof(uint8_t));
870 MOS_SecureMemcpy(hucConstData->UPD_P_RefId, 42 * sizeof(uint8_t), brcSettings.BRC_UPD_P_RefId, 42 * sizeof(uint8_t));
871
872 ENCODE_CHK_STATUS_RETURN(LoadConstTable0(hucConstData->VdencAvcHucBrcConstantData_0));
873 ENCODE_CHK_STATUS_RETURN(LoadConstTable3(pictureType, hucConstData->VdencAvcHucBrcConstantData_1));
874 ENCODE_CHK_STATUS_RETURN(LoadConstTable5(pictureType, hucConstData->VdencAvcHucBrcConstantData_2));
875 ENCODE_CHK_STATUS_RETURN(LoadConstTable6(pictureType, hucConstData->VdencAvcHucBrcConstantData_3));
876 ENCODE_CHK_STATUS_RETURN(LoadConstTable7(pictureType, hucConstData->VdencAvcHucBrcConstantData_4));
877 ENCODE_CHK_STATUS_RETURN(LoadConstTable8(pictureType, hucConstData->VdencAvcHucBrcConstantData_5));
878
879 return MOS_STATUS_SUCCESS;
880 }
881
SaveBrcUpdateDmemBufferPtr(PMOS_RESOURCE vdencBrcUpdateDmemBuffer0,PMOS_RESOURCE vdencBrcUpdateDmemBuffer1)882 MOS_STATUS AvcEncodeBRC::SaveBrcUpdateDmemBufferPtr(
883 PMOS_RESOURCE vdencBrcUpdateDmemBuffer0,
884 PMOS_RESOURCE vdencBrcUpdateDmemBuffer1)
885 {
886 ENCODE_FUNC_CALL();
887
888 m_vdencBrcUpdateDmemBufferPtr[0] = vdencBrcUpdateDmemBuffer0;
889 m_vdencBrcUpdateDmemBufferPtr[1] = vdencBrcUpdateDmemBuffer1;
890
891 return MOS_STATUS_SUCCESS;
892 }
893
SaveHucStatus2Buffer(PMOS_RESOURCE hucStatus2Buffer)894 MOS_STATUS AvcEncodeBRC::SaveHucStatus2Buffer(PMOS_RESOURCE hucStatus2Buffer)
895 {
896 ENCODE_FUNC_CALL();
897
898 m_hucStatus2BufferPtr = hucStatus2Buffer;
899
900 return MOS_STATUS_SUCCESS;
901 }
902
SetMfcStatusParams(EncodeStatusReadParams & params)903 MOS_STATUS AvcEncodeBRC::SetMfcStatusParams(EncodeStatusReadParams ¶ms)
904 {
905 ENCODE_FUNC_CALL();
906
907 if (m_vdencBrcEnabled)
908 {
909 params.vdencBrcEnabled = true;
910 params.vdencBrcNumOfSliceOffset = CODECHAL_OFFSETOF(VdencAvcHucBrcUpdateDmem, NumOfSlice);
911 params.resVdencBrcUpdateDmemBufferPtr = m_vdencBrcUpdateDmemBufferPtr;
912 }
913
914 return MOS_STATUS_SUCCESS;
915 }
916
LoadConstTable0(uint8_t constTable[8][42])917 MOS_STATUS AvcEncodeBRC::LoadConstTable0(uint8_t constTable[8][42])
918 {
919 ENCODE_FUNC_CALL();
920
921 auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
922 ENCODE_CHK_NULL_RETURN(settings);
923
924 const auto &constTable1 = settings->vdencCMD3Table->AvcVdencCMD3ConstSettings_0;
925
926 for (auto i = 0; i < 8; i++)
927 {
928 for (auto j = 0; j < 42; j++)
929 {
930 constTable[i][j] = constTable1[i][j + 10];
931 }
932 }
933
934 return MOS_STATUS_SUCCESS;
935 }
936
LoadConstTable3(uint8_t pictureType,uint8_t ConstTable3[42])937 MOS_STATUS AvcEncodeBRC::LoadConstTable3(uint8_t pictureType, uint8_t ConstTable3[42])
938 {
939 ENCODE_FUNC_CALL();
940
941 auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
942 ENCODE_CHK_NULL_RETURN(settings);
943
944 const auto & table = settings->vdencCMD3Table->AvcVdencCMD3ConstSettings_3;
945 const uint8_t codingType = pictureType + 1;
946
947 for (auto i = 0; i < 42; i++)
948 {
949 if (codingType == I_TYPE || codingType == P_TYPE)
950 {
951 ConstTable3[i] = table[pictureType][i + 10];
952 }
953 else // B and Ref B
954 {
955 ConstTable3[i] = 14;
956 }
957 }
958
959 return MOS_STATUS_SUCCESS;
960 }
961
LoadConstTable5(uint8_t pictureType,uint16_t ConstTable5[42])962 MOS_STATUS AvcEncodeBRC::LoadConstTable5(uint8_t pictureType, uint16_t ConstTable5[42])
963 {
964 ENCODE_FUNC_CALL();
965
966 auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
967 ENCODE_CHK_NULL_RETURN(settings);
968
969 const auto & table = settings->vdencCMD3Table->AvcVdencCMD3ConstSettings_5;
970 uint8_t isIPGOP = m_basicFeature->m_seqParam->GopRefDist == 1 ? 1 : 0;
971 for (int8_t qp = 10; qp < 52; ++qp)
972 {
973 uint8_t idx = uint8_t(qp > 12 ? qp - 12 : 0);
974 ConstTable5[qp-10] = table[pictureType][isIPGOP][idx];
975 }
976
977 return MOS_STATUS_SUCCESS;
978 }
979
LoadConstTable6(uint8_t pictureType,uint16_t ConstTable6[42])980 MOS_STATUS AvcEncodeBRC::LoadConstTable6(uint8_t pictureType, uint16_t ConstTable6[42])
981 {
982 ENCODE_FUNC_CALL();
983
984 auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
985 ENCODE_CHK_NULL_RETURN(settings);
986
987 const auto & table = settings->vdencCMD3Table->AvcVdencCMD3ConstSettings_6;
988 uint8_t isIPGOP = m_basicFeature->m_seqParam->GopRefDist == 1 ? 1 : 0;
989 for (int8_t qp = 10; qp < 52; ++qp)
990 {
991 uint8_t idx = uint8_t(qp > 12 ? qp - 12 : 0);
992 ConstTable6[qp-10] = table[pictureType][isIPGOP][idx];
993 }
994
995 return MOS_STATUS_SUCCESS;
996 }
997
LoadConstTable7(uint8_t pictureType,uint8_t ConstTable7[42])998 MOS_STATUS AvcEncodeBRC::LoadConstTable7(uint8_t pictureType, uint8_t ConstTable7[42])
999 {
1000 ENCODE_FUNC_CALL();
1001
1002 const uint8_t codingType = pictureType + 1;
1003 if (codingType == I_TYPE)
1004 return MOS_STATUS_SUCCESS;
1005
1006 auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
1007 ENCODE_CHK_NULL_RETURN(settings);
1008
1009 uint8_t isIPGOP = m_basicFeature->m_seqParam->GopRefDist == 1;
1010 auto index = (codingType == P_TYPE) ? (isIPGOP ? 3 : 2) : (codingType == B_TYPE ? 0 : 1);
1011
1012 const auto &table = settings->AdaptiveInterRounding[index];
1013 for (int8_t qp = 10; qp < 52; ++qp)
1014 {
1015 ConstTable7[qp - 10] = table[qp];
1016 }
1017
1018 return MOS_STATUS_SUCCESS;
1019 }
1020
LoadConstTable8(uint8_t pictureType,uint8_t ConstTable8[42])1021 MOS_STATUS AvcEncodeBRC::LoadConstTable8(uint8_t pictureType, uint8_t ConstTable8[42])
1022 {
1023 ENCODE_FUNC_CALL();
1024
1025 const uint8_t codingType = pictureType + 1;
1026 if (codingType == I_TYPE)
1027 return MOS_STATUS_SUCCESS;
1028
1029 auto settings = static_cast<AvcVdencFeatureSettings *>(m_featureManager->GetFeatureSettings()->GetConstSettings());
1030 ENCODE_CHK_NULL_RETURN(settings);
1031
1032 uint8_t isIPGOP = m_basicFeature->m_seqParam->GopRefDist == 1;
1033 auto index = (codingType == P_TYPE) ? (isIPGOP ? 3 : 2) : (codingType == B_TYPE ? 0 : 1);
1034
1035 const auto &table = settings->AdaptiveIntraRounding[index];
1036 for (int8_t qp = 10; qp < 52; ++qp)
1037 {
1038 ConstTable8[qp - 10] = table[qp];
1039 }
1040
1041 return MOS_STATUS_SUCCESS;
1042 }
1043
1044
SetSequenceStructs()1045 MOS_STATUS AvcEncodeBRC::SetSequenceStructs()
1046 {
1047 ENCODE_FUNC_CALL();
1048
1049 auto seqParams = m_basicFeature->m_seqParam;
1050
1051 m_brcInit = m_basicFeature->m_resolutionChanged;
1052 m_vdencBrcEnabled = IsVdencBrcSupported(seqParams);
1053 m_rcMode = m_vdencBrcEnabled ? seqParams->RateControlMethod : 0;
1054
1055 if (IsRateControlBrc(seqParams->RateControlMethod) && m_vdencBrcEnabled == 0)
1056 {
1057 // Error propagation
1058 return MOS_STATUS_INVALID_PARAMETER;
1059 }
1060
1061 // control MBBRC if the user feature key does not exist
1062 if (m_vdencBrcEnabled && !m_mbBrcUserFeatureKeyControl)
1063 {
1064 SetMbBrc();
1065 }
1066
1067 // BRC Init or Reset
1068 if (seqParams->bInitBRC)
1069 {
1070 m_brcInit = seqParams->bInitBRC;
1071 }
1072 else
1073 {
1074 m_brcReset = seqParams->bResetBRC;
1075 }
1076
1077 if (seqParams->RateControlMethod == RATECONTROL_ICQ || seqParams->RateControlMethod == RATECONTROL_QVBR)
1078 {
1079 if (seqParams->ICQQualityFactor < ENCODE_AVC_VDENC_MIN_ICQ_QUALITYFACTOR ||
1080 seqParams->ICQQualityFactor > CODECHAL_ENCODE_AVC_MAX_ICQ_QUALITYFACTOR)
1081 {
1082 ENCODE_ASSERTMESSAGE("Invalid ICQ Quality Factor input\n");
1083 seqParams->ICQQualityFactor = (uint16_t)CodecHal_Clip3(ENCODE_AVC_VDENC_MIN_ICQ_QUALITYFACTOR,
1084 CODECHAL_ENCODE_AVC_MAX_ICQ_QUALITYFACTOR,
1085 seqParams->ICQQualityFactor);
1086 }
1087 }
1088
1089 return MOS_STATUS_SUCCESS;
1090 }
1091
SetMbBrc()1092 void AvcEncodeBRC::SetMbBrc()
1093 {
1094 ENCODE_FUNC_CALL();
1095
1096 auto seqParams = m_basicFeature->m_seqParam;
1097 if (seqParams->RateControlMethod == RATECONTROL_ICQ || seqParams->RateControlMethod == RATECONTROL_QVBR)
1098 {
1099 // If the rate control method is ICQ or QVBR then enable MBBRC by default for all TUs and ignore the app input
1100 m_mbBrcEnabled = true;
1101 ENCODE_NORMALMESSAGE("MBBRC enabled with rate control = %d", seqParams->RateControlMethod);
1102 }
1103 else if (seqParams->RateControlMethod == RATECONTROL_VCM)
1104 {
1105 // If the rate control method is VCM then disable MBBRC by default for all TUs and ignore the app input
1106 m_mbBrcEnabled = false;
1107 }
1108 else
1109 {
1110 switch (seqParams->MBBRC)
1111 {
1112 case mbBrcInternal:
1113 m_mbBrcEnabled = true;
1114 break;
1115 case mbBrcDisabled:
1116 m_mbBrcEnabled = false;
1117 break;
1118 case mbBrcEnabled:
1119 m_mbBrcEnabled = true;
1120 break;
1121 }
1122 }
1123 }
1124
FreeBrcResources()1125 MOS_STATUS AvcEncodeBRC::FreeBrcResources()
1126 {
1127 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1128
1129 ENCODE_FUNC_CALL();
1130 ENCODE_CHK_NULL_RETURN(m_hwInterface);
1131 ENCODE_CHK_NULL_RETURN(m_hwInterface->GetOsInterface());
1132
1133 if (m_batchBufferForVdencImgStat.iSize)
1134 {
1135 ENCODE_CHK_STATUS_RETURN(Mhw_FreeBb(m_hwInterface->GetOsInterface(), &m_batchBufferForVdencImgStat, nullptr));
1136 }
1137
1138 return eStatus;
1139 }
1140
ComputeBRCInitQP()1141 int32_t AvcEncodeBRC::ComputeBRCInitQP()
1142 {
1143 ENCODE_FUNC_CALL();
1144
1145 const float x0 = 0, y0 = 1.19f, x1 = 1.75f, y1 = 1.75f;
1146 uint32_t frameSize;
1147 int32_t QP, deltaQ;
1148
1149 auto seqParams = m_basicFeature->m_seqParam;
1150
1151 // InitQPIP calculation
1152 frameSize = ((m_basicFeature->m_frameWidth * m_basicFeature->m_frameHeight * 3) >> 1);
1153 QP = (int32_t)(1. / 1.2 * pow(10.0, (log10(frameSize * 2. / 3. * ((float)seqParams->FramesPer100Sec) / ((float)(seqParams->TargetBitRate) * 100)) - x0) * (y1 - y0) / (x1 - x0) + y0) + 0.5);
1154 QP += 2;
1155 //add additional change based on buffer size. It is especially useful for low delay
1156 deltaQ = (int32_t)(9 - (seqParams->VBVBufferSizeInBit * ((float)seqParams->FramesPer100Sec) / ((float)(seqParams->TargetBitRate) * 100)));
1157 QP += deltaQ < 0 ? 0 : deltaQ;
1158 QP = CodecHal_Clip3(ENCODE_AVC_BRC_MIN_QP, CODECHAL_ENCODE_AVC_MAX_SLICE_QP, QP);
1159 QP--;
1160 if (QP < 0)
1161 QP = 1;
1162
1163 return QP;
1164 }
1165
DeltaQPUpdate(uint8_t qpModulationStrength,bool bIsLastPass)1166 MOS_STATUS AvcEncodeBRC::DeltaQPUpdate(uint8_t qpModulationStrength, bool bIsLastPass)
1167 {
1168 ENCODE_FUNC_CALL();
1169
1170 uint8_t qpStrength = (uint8_t)(qpModulationStrength + (qpModulationStrength >> 1));
1171 if (!m_isFirstDeltaQPCalculation)
1172 {
1173 if (qpModulationStrength == 0)
1174 {
1175 m_qpModulationStrength = 0;
1176 }
1177 else
1178 {
1179 m_qpModulationStrength = (m_qpModulationStrength + qpStrength + 1) >> 1;
1180 }
1181 }
1182 else
1183 {
1184 m_qpModulationStrength = qpStrength;
1185 if (bIsLastPass)
1186 {
1187 m_isFirstDeltaQPCalculation = false;
1188 }
1189 }
1190
1191 return MOS_STATUS_SUCCESS;
1192 }
1193
SetFrameTypeForUpdate(VdencAvcHucBrcUpdateDmem * dmem,uint16_t currPass)1194 void AvcEncodeBRC::SetFrameTypeForUpdate(VdencAvcHucBrcUpdateDmem *dmem, uint16_t currPass)
1195 {
1196 dmem->UPD_CurrFrameType_U8 = (m_basicFeature->m_pictureCodingType + 1) % 3; // I:2, P:0, B:1. Same values in AvcBrcFrameType
1197 if (dmem->UPD_CurrFrameType_U8 == 1 && m_basicFeature->m_picParam->RefPicFlag == 1)
1198 {
1199 dmem->UPD_CurrFrameType_U8 = 3; // separated type for reference B for legacy BRC
1200 }
1201
1202 if (m_basicFeature->m_pictureCodingType == I_TYPE || m_basicFeature->m_pictureCodingType == P_TYPE)
1203 {
1204 m_frameIdxInBGop = 0;
1205 }
1206 else if (currPass == 0)
1207 {
1208 ++m_frameIdxInBGop;
1209 }
1210
1211 //
1212 // Calculate correct ExtCurrFrameType only for Golden GOPs
1213 //
1214 // Calculate B-frame type based on hierarchy level for B-pyramid
1215 if (IsBPyramidWithGoldenBGOP() && m_basicFeature->m_pictureCodingType == B_TYPE)
1216 {
1217 uint16_t curOrder = 0, curLvlInBGop = 0;
1218 CalculateCurLvlInBGop(m_frameIdxInBGop, 1, m_basicFeature->m_seqParam->GopRefDist, 0, curOrder, curLvlInBGop);
1219
1220 dmem->UPD_ExtCurrFrameType = curLvlInBGop == 1 ? AvcBrcFrameType::B1_FRAME : (curLvlInBGop == 2 ? AvcBrcFrameType::B2_FRAME : AvcBrcFrameType::B_FRAME);
1221 }
1222 }
1223
IsVdencBrcSupported(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams)1224 bool AvcEncodeBRC::IsVdencBrcSupported(
1225 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams)
1226 {
1227 ENCODE_FUNC_CALL();
1228
1229 bool vdencBrcSupported = false;
1230
1231 // HuC based BRC should be used when 1) BRC is requested by App and 2) HuC FW is loaded and HuC is enabled for use.
1232 if (IsRateControlBrc(avcSeqParams->RateControlMethod))
1233 {
1234 if (!MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrEnableMediaKernels))
1235 {
1236 ENCODE_ASSERTMESSAGE("Failed to load HuC firmware!");
1237 }
1238
1239 vdencBrcSupported = MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrEnableMediaKernels);
1240 }
1241
1242 // Simple check for BRC parameters; if error, disable BRC and continue encoding
1243 if ((vdencBrcSupported) &&
1244 (avcSeqParams->RateControlMethod != RATECONTROL_ICQ) &&
1245 (((!avcSeqParams->InitVBVBufferFullnessInBit || !avcSeqParams->VBVBufferSizeInBit || !avcSeqParams->MaxBitRate) &&
1246 (avcSeqParams->RateControlMethod != RATECONTROL_AVBR)) ||
1247 !avcSeqParams->TargetBitRate ||
1248 !avcSeqParams->FramesPer100Sec))
1249 {
1250 ENCODE_ASSERTMESSAGE("Fatal error in AVC Encoding BRC parameters.");
1251 ENCODE_ASSERTMESSAGE("RateControlMethod = %d, InitVBVBufferFullnessInBit = %d, VBVBufferSizeInBit = %d, MaxBitRate = %d, TargetBitRate = %d, FramesPer100Sec = %d",
1252 avcSeqParams->RateControlMethod,
1253 avcSeqParams->InitVBVBufferFullnessInBit,
1254 avcSeqParams->VBVBufferSizeInBit,
1255 avcSeqParams->MaxBitRate,
1256 avcSeqParams->TargetBitRate,
1257 avcSeqParams->FramesPer100Sec);
1258 vdencBrcSupported = false;
1259 }
1260
1261 return vdencBrcSupported;
1262 }
1263
GetVdencBRCImgStateBufferSize()1264 uint32_t AvcEncodeBRC::GetVdencBRCImgStateBufferSize()
1265 {
1266 return MOS_ALIGN_CEIL(MOS_ALIGN_CEIL(m_hwInterface->m_vdencBrcImgStateBufferSize, CODECHAL_CACHELINE_SIZE) +
1267 CODECHAL_ENCODE_AVC_MAX_SLICES_SUPPORTED * GetVdencOneSliceStateSize(),
1268 CODECHAL_PAGE_SIZE);
1269 }
1270
GetVdencOneSliceStateSize()1271 uint32_t AvcEncodeBRC::GetVdencOneSliceStateSize()
1272 {
1273 return m_mfxItf->MHW_GETSIZE_F(MFX_AVC_SLICE_STATE)() +
1274 m_vdencItf->MHW_GETSIZE_F(VDENC_AVC_SLICE_STATE)() +
1275 m_miItf->MHW_GETSIZE_F(MI_BATCH_BUFFER_END)();
1276 }
1277
IsBPyramidWithGoldenBGOP()1278 bool AvcEncodeBRC::IsBPyramidWithGoldenBGOP()
1279 {
1280 return
1281 // Add HierarchicalFlag to condition to not use hierarchy B-Frames when HierarchicalFlag==0
1282 // m_basicFeature->m_seqParam->HierarchicalFlag &&
1283 (m_basicFeature->m_seqParam->GopRefDist == 2 ||
1284 m_basicFeature->m_seqParam->GopRefDist == 4 ||
1285 m_basicFeature->m_seqParam->GopRefDist == 8);
1286 }
1287
CalculateCurLvlInBGop(uint16_t curFrameIdxInBGop,uint16_t begin,uint16_t end,uint16_t curLvl,uint16_t & curOrder,uint16_t & retLvl)1288 void AvcEncodeBRC::CalculateCurLvlInBGop(uint16_t curFrameIdxInBGop, uint16_t begin, uint16_t end, uint16_t curLvl, uint16_t &curOrder, uint16_t &retLvl)
1289 {
1290 curOrder += 1;
1291 if (curOrder == curFrameIdxInBGop)
1292 {
1293 retLvl = curLvl;
1294 return;
1295 }
1296
1297 if (end - begin > 1)
1298 {
1299 uint16_t pivot = (begin + end) >> 1;
1300 CalculateCurLvlInBGop(curFrameIdxInBGop, begin, pivot, curLvl + 1, curOrder, retLvl);
1301
1302 if (pivot + 1 != end)
1303 CalculateCurLvlInBGop(curFrameIdxInBGop, pivot + 1, end, curLvl + 1, curOrder, retLvl);
1304 }
1305 }
1306
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,AvcEncodeBRC)1307 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, AvcEncodeBRC)
1308 {
1309 params.frameStatisticsStreamOut = m_vdencBrcEnabled || m_basicFeature->m_picParam->StatusReportEnable.fields.FrameStats;
1310
1311 return MOS_STATUS_SUCCESS;
1312 }
1313
MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,AvcEncodeBRC)1314 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, AvcEncodeBRC)
1315 {
1316 if (params.function == BRC_UPDATE)
1317 {
1318 ENCODE_CHK_NULL_RETURN(m_basicFeature);
1319
1320 // Output regions
1321 params.regionParams[0].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencBRCHistoryBuffer, m_basicFeature->m_frameNum);
1322 params.regionParams[0].isWritable = true;
1323 params.regionParams[6].presRegion = const_cast<PMOS_RESOURCE>(&m_batchBufferForVdencImgStat.OsResource);
1324 params.regionParams[6].isWritable = true;
1325
1326 // region 15 always in clear
1327 params.regionParams[15].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcDebugBuffer, 0);
1328 }
1329
1330 return MOS_STATUS_SUCCESS;
1331 }
1332
1333 } // namespace encode
1334