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