1 /*
2 * Copyright (c) 2017-2019, 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     codechal_encode_hevc_brc_g12.cpp
24 //! \brief    HEVC dual-pipe encoder brc kernels for GEN12.
25 //!
26 
27 #include "codechal_encode_hevc_mbenc_g12.h"
28 #include "codechal_encode_hevc_brc_g12.h"
29 #include "codechal_encode_hevc_g12.h"
30 #include "mhw_vdbox_hcp_g12_X.h"
31 #include "Gen12_HEVC_B_LCU32.h"
32 #include "Gen12_HEVC_B_LCU64.h"
33 #include "cm_wrapper.h"
34 
35 #include "Gen12_HEVC_BRC_INIT.h"
36 #include "Gen12_HEVC_BRC_RESET.h"
37 #include "Gen12_HEVC_BRC_UPDATE.h"
38 #include "Gen12_HEVC_BRC_LCUQP.h"
39 
40 #include "codechal_debug.h"
41 
42 #if USE_PROPRIETARY_CODE
43 #include "cm_device_rt.h"
44 #endif
45 
46 #if MOS_MEDIASOLO_SUPPORTED
47 #include "mos_os_solo.h"
48 #endif // (_DEBUG || _RELEASE_INTERNAL)
49 
AllocateBrcResources()50 MOS_STATUS CodecHalHevcBrcG12::AllocateBrcResources()
51 {
52     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
53 
54     CODECHAL_ENCODE_FUNCTION_ENTER;
55 
56     return MOS_STATUS_SUCCESS;
57 }
58 
FreeBrcResources()59 MOS_STATUS CodecHalHevcBrcG12::FreeBrcResources()
60 {
61     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
62 
63     CODECHAL_ENCODE_FUNCTION_ENTER;
64     // Destroy the container for BRC buffers
65     if (m_histBufferBrc)
66     {
67         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_histBufferBrc));
68         m_histBufferBrc = nullptr;
69     }
70     if (m_PAKStatsBufferBrc)
71     {
72         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_PAKStatsBufferBrc));
73         m_PAKStatsBufferBrc = nullptr;
74     }
75     if (m_PICStateInBufferBrc)
76     {
77         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_PICStateInBufferBrc));
78         m_PICStateInBufferBrc = nullptr;
79     }
80     if (m_PICStateOutBufferBrc)
81     {
82         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_PICStateOutBufferBrc));
83         m_PICStateOutBufferBrc = nullptr;
84     }
85     if (m_CombinedEncBufferBrc)
86     {
87         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_CombinedEncBufferBrc));
88         m_CombinedEncBufferBrc = nullptr;
89     }
90     if (m_PixelMBStatsBufferBrc)
91     {
92         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_PixelMBStatsBufferBrc));
93         m_PixelMBStatsBufferBrc = nullptr;
94     }
95     if (m_ConstDataBufferBRC)
96     {
97         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_ConstDataBufferBRC));
98         m_ConstDataBufferBRC = nullptr;
99     }
100     if (m_BrcMbQp)
101     {
102         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_BrcMbQp));
103         m_BrcMbQp = nullptr;
104     }
105     if (m_BrcROISurf)
106     {
107         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroySurface(m_BrcROISurf));
108         m_BrcROISurf = nullptr;
109     }
110 
111     if (m_cmKrnBrcInit)
112     {
113         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyKernel(m_cmKrnBrcInit));
114         m_cmKrnBrcInit = nullptr;
115     }
116     if (m_cmProgramBrcInit)
117     {
118         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyProgram(m_cmProgramBrcInit));
119         m_cmProgramBrcInit = nullptr;
120     }
121     if (m_cmKrnBrcReset)
122     {
123         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyKernel(m_cmKrnBrcReset));
124         m_cmKrnBrcReset = nullptr;
125     }
126     if (m_cmProgramBrcReset)
127     {
128         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyProgram(m_cmProgramBrcReset));
129         m_cmProgramBrcReset = nullptr;
130     }
131     if (m_cmKrnBrcUpdate)
132     {
133         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyKernel(m_cmKrnBrcUpdate));
134         m_cmKrnBrcUpdate = nullptr;
135     }
136     if (m_cmProgramBrcUpdate)
137     {
138         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyProgram(m_cmProgramBrcUpdate));
139         m_cmProgramBrcUpdate = nullptr;
140     }
141     if (m_cmKrnBrcLCUQP)
142     {
143         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyKernel(m_cmKrnBrcLCUQP));
144         m_cmKrnBrcLCUQP = nullptr;
145     }
146     if (m_cmProgramBrcLCUQP)
147     {
148         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyProgram(m_cmProgramBrcLCUQP));
149         m_cmProgramBrcLCUQP = nullptr;
150     }
151     if (m_threadSpaceBrcInitReset)
152     {
153         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyThreadSpace(m_threadSpaceBrcInitReset));
154         m_threadSpaceBrcInitReset = nullptr;
155     }
156     if (m_threadSpaceBrcUpdate)
157     {
158         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyThreadSpace(m_threadSpaceBrcUpdate));
159         m_threadSpaceBrcUpdate = nullptr;
160     }
161     if (m_threadSpaceBrcLCUQP)
162     {
163         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyThreadSpace(m_threadSpaceBrcLCUQP));
164         m_threadSpaceBrcLCUQP = nullptr;
165     }
166     return eStatus;
167 }
168 
InitBrcKernelState()169 MOS_STATUS CodecHalHevcBrcG12::InitBrcKernelState()
170 {
171     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
172 
173     CODECHAL_ENCODE_FUNCTION_ENTER;
174 
175     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->LoadProgram((void *)HEVC_BRC_INIT_GENX,
176         HEVC_BRC_INIT_GENX_SIZE,
177         m_cmProgramBrcInit,
178         "-nojitter"));
179 
180     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateKernel(m_cmProgramBrcInit,
181         "HEVC_brc_init",
182         m_cmKrnBrcInit));
183 
184     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->LoadProgram((void *)HEVC_BRC_RESET_GENX,
185         HEVC_BRC_RESET_GENX_SIZE,
186         m_cmProgramBrcReset,
187         "-nojitter"));
188 
189     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateKernel(m_cmProgramBrcReset,
190         "HEVC_brc_reset",
191         m_cmKrnBrcReset));
192 
193     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->LoadProgram((void *)HEVC_BRC_UPDATE_GENX,
194         HEVC_BRC_UPDATE_GENX_SIZE,
195         m_cmProgramBrcUpdate,
196         "-nojitter"));
197 
198     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateKernel(m_cmProgramBrcUpdate,
199         "HEVC_brc_update",
200         m_cmKrnBrcUpdate));
201 
202     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->LoadProgram((void *)HEVC_BRC_LCUQP_GENX,
203         HEVC_BRC_LCUQP_GENX_SIZE,
204         m_cmProgramBrcLCUQP,
205         "-nojitter"));
206 
207     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateKernel(m_cmProgramBrcLCUQP,
208         "HEVC_brc_lcuqp",
209         m_cmKrnBrcLCUQP));
210 
211     return eStatus;
212 }
SetupKernelArgsBrcInit()213 MOS_STATUS CodecHalHevcBrcG12::SetupKernelArgsBrcInit()
214 {
215     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
216 
217     //Setup surfaces
218 
219     int idx = 0;
220     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrc->SetKernelArg(idx++, sizeof(encoderBrc->curbe), &encoderBrc->curbe));
221 
222     SurfaceIndex *pIndex0 = nullptr;
223     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_histBufferBrc->GetIndex(pIndex0));
224     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrc->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
225 
226     //Setup Distortion 2D surface
227     CmSurface2D *brcDistortion = (encoderBrc->m_pictureCodingType == I_TYPE) ? encoderBrc->m_brcBuffers.brcIntraDistortionSurface
228                                                                              : encoderBrc->m_brcBuffers.meBrcDistortionSurface;
229     CODECHAL_ENCODE_CHK_STATUS_RETURN(brcDistortion->GetIndex(pIndex0));
230     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrc->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
231 
232     return eStatus;
233 }
234 
SetupThreadSpace(CmKernel * cmKernel,CmThreadSpace * & threadSpace)235 MOS_STATUS CodecHalHevcBrcG12::SetupThreadSpace(CmKernel *cmKernel, CmThreadSpace *& threadSpace)
236 {
237     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
238 
239     CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKernel->SetThreadCount(1));
240 
241     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateThreadSpace(1, 1, threadSpace));
242     CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKernel->AssociateThreadSpace(threadSpace));
243     return eStatus;
244 }
245 
SetupBrcLcuqpThreadSpace(CmKernel * cmKernel,CmThreadSpace * & threadSpace)246 MOS_STATUS CodecHalHevcBrcG12::SetupBrcLcuqpThreadSpace(CmKernel *cmKernel, CmThreadSpace *& threadSpace)
247 {
248     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
249     uint32_t xThread = (encoderBrc->m_downscaledWidthInMb4x * SCALE_FACTOR_4x + 15) >> 4;
250     uint32_t yThread = (encoderBrc->m_downscaledHeightInMb4x * SCALE_FACTOR_4x + 7) >> 3;
251 
252     CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKernel->SetThreadCount(xThread * yThread));
253 
254     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateThreadSpace(xThread, yThread, threadSpace));
255     CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKernel->AssociateThreadSpace(threadSpace));
256 
257     return eStatus;
258 }
259 
InitCurbeDataBrcInit()260 MOS_STATUS CodecHalHevcBrcG12::InitCurbeDataBrcInit()
261 {
262     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
263     return eStatus;
264 }
265 
SetupSurfacesBrcInit()266 MOS_STATUS CodecHalHevcBrcG12::SetupSurfacesBrcInit()
267 {
268     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
269 
270     if (!m_histBufferBrc)
271     {
272         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateBuffer(
273             &encoderBrc->m_brcBuffers.resBrcHistoryBuffer, //m_brcHistoryBufferSize,
274             m_histBufferBrc));
275     }
276 
277     return eStatus;
278 }
279 
EncodeBrcInitResetKernel()280 MOS_STATUS CodecHalHevcBrcG12::EncodeBrcInitResetKernel()
281 {
282     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
283     // Setup curbe for BrcInitReset kernel
284     if (encoderBrc->m_brcInit)
285     {
286         m_cmKrnBrc = m_cmKrnBrcInit;
287     }
288     else
289     {
290         m_cmKrnBrc = m_cmKrnBrcReset;
291     }
292 
293     /* Only one CM kernel is used to switch between brcInit and brcReset, same rule for threadSpace.
294        Destroy old one and create a new threadSpace when only brcReset is triggered. */
295     if (encoderBrc->m_brcReset && m_threadSpaceBrcInitReset)
296     {
297         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyThreadSpace(m_threadSpaceBrcInitReset));
298         m_threadSpaceBrcInitReset = nullptr;
299     }
300 
301     if (!m_threadSpaceBrcInitReset)
302     {
303         CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupThreadSpace(m_cmKrnBrc, m_threadSpaceBrcInitReset));
304     }
305 
306     CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcInitResetCurbe());
307 
308     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupSurfacesBrcInit());
309     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupKernelArgsBrcInit());
310 
311     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmTask->AddKernel(m_cmKrnBrc));
312 
313     if (!encoderBrc->m_singleTaskPhaseSupported || encoderBrc->m_lastTaskInPhase)
314     {
315         CmEvent * event = CM_NO_EVENT;
316         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmQueue->EnqueueFast(encoderBrc->m_cmTask, event));
317 
318         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmTask->Reset());
319 
320         encoderBrc->m_lastTaskInPhase = false;
321     }
322     else
323     {
324         encoderBrc->m_cmTask->AddSync();
325     }
326 
327     encoderBrc->m_brcInit = encoderBrc->m_brcReset = false;
328     // End FW
329     return eStatus;
330 }
331 
BrcInitResetCurbe()332 MOS_STATUS CodecHalHevcBrcG12::BrcInitResetCurbe()
333 {
334     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
335 
336     // Initialize the CURBE data
337     encoderBrc->curbe = encoderBrc->m_brcInitResetCurbeInit;
338 
339     uint32_t   profileLevelMaxFrame = encoderBrc->GetProfileLevelMaxFrameSize();
340 
341     if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_CBR ||
342         encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_VBR ||
343         encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_AVBR)
344     {
345         if (encoderBrc->m_hevcSeqParams->InitVBVBufferFullnessInBit == 0)
346         {
347             CODECHAL_ENCODE_ASSERTMESSAGE("Initial VBV Buffer Fullness is zero\n");
348             return MOS_STATUS_INVALID_PARAMETER;
349         }
350 
351         if (encoderBrc->m_hevcSeqParams->VBVBufferSizeInBit == 0)
352         {
353             CODECHAL_ENCODE_ASSERTMESSAGE("VBV buffer size in bits is zero\n");
354             return MOS_STATUS_INVALID_PARAMETER;
355         }
356     }
357 
358     encoderBrc->curbe.DW0_ProfileLevelMaxFrame = profileLevelMaxFrame;
359     encoderBrc->curbe.DW1_InitBufFull = encoderBrc->m_hevcSeqParams->InitVBVBufferFullnessInBit;
360     encoderBrc->curbe.DW2_BufSize = encoderBrc->m_hevcSeqParams->VBVBufferSizeInBit;
361     encoderBrc->curbe.DW3_TargetBitRate = encoderBrc->m_hevcSeqParams->TargetBitRate * CODECHAL_ENCODE_BRC_KBPS;    //DDI in Kbits
362     encoderBrc->curbe.DW4_MaximumBitRate = encoderBrc->m_hevcSeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS;
363     encoderBrc->curbe.DW5_MinimumBitRate = 0;
364     encoderBrc->curbe.DW6_FrameRateM = encoderBrc->m_hevcSeqParams->FrameRate.Numerator;
365     encoderBrc->curbe.DW7_FrameRateD = encoderBrc->m_hevcSeqParams->FrameRate.Denominator;
366     encoderBrc->curbe.DW8_BRCFlag = encoderBrc->BRCINIT_IGNORE_PICTURE_HEADER_SIZE;  // always ignore the picture header size set in BRC Update curbe;
367 
368     if (encoderBrc->m_hevcPicParams->NumROI)
369     {
370         encoderBrc->curbe.DW8_BRCFlag |= encoderBrc->BRCINIT_DISABLE_MBBRC; // BRC ROI need disable MBBRC logic in LcuBrc Kernel
371     }
372     else
373     {
374         encoderBrc->curbe.DW8_BRCFlag |= (encoderBrc->m_lcuBrcEnabled) ? 0 : encoderBrc->BRCINIT_DISABLE_MBBRC;
375     }
376 
377     encoderBrc->curbe.DW8_BRCFlag |= (encoderBrc->m_brcEnabled && encoderBrc->m_numPipe > 1) ? encoderBrc->BRCINIT_USEHUCBRC : 0;
378     encoderBrc->curbe.DW8_BRCFlag |= (encoderBrc->m_enableFramePanicMode) ? encoderBrc->BRCINIT_PANIC_MODE_ISENABLED : 0;
379 
380     // For non-ICQ, ACQP Buffer always set to 1
381     encoderBrc->curbe.DW25_ACQPBuffer = 1;
382 
383     encoderBrc->curbe.DW25_SlidingWindowSize = encoderBrc->m_slidingWindowSize;
384 
385     if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_CBR)
386     {
387         encoderBrc->curbe.DW4_MaximumBitRate = encoderBrc->curbe.DW3_TargetBitRate;
388         encoderBrc->curbe.DW8_BRCFlag |= encoderBrc->BRCINIT_ISCBR;
389     }
390     else if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_VBR)
391     {
392         if (encoderBrc->curbe.DW4_MaximumBitRate < encoderBrc->curbe.DW3_TargetBitRate)
393         {
394             encoderBrc->curbe.DW4_MaximumBitRate = 2 * encoderBrc->curbe.DW3_TargetBitRate;
395         }
396         encoderBrc->curbe.DW8_BRCFlag |= encoderBrc->BRCINIT_ISVBR;
397     }
398     else if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_AVBR)
399     {
400         encoderBrc->curbe.DW8_BRCFlag |= encoderBrc->BRCINIT_ISAVBR;
401         // For AVBR, max bitrate = target bitrate,
402         encoderBrc->curbe.DW3_TargetBitRate = encoderBrc->m_hevcSeqParams->TargetBitRate * CODECHAL_ENCODE_BRC_KBPS;    //DDI in Kbits
403         encoderBrc->curbe.DW4_MaximumBitRate = encoderBrc->m_hevcSeqParams->TargetBitRate * CODECHAL_ENCODE_BRC_KBPS;
404     }
405     else if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_ICQ)
406     {
407         encoderBrc->curbe.DW8_BRCFlag |= encoderBrc->BRCINIT_ISICQ;
408         encoderBrc->curbe.DW25_ACQPBuffer = encoderBrc->m_hevcSeqParams->ICQQualityFactor;
409     }
410     else if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_VCM)
411     {
412         encoderBrc->curbe.DW4_MaximumBitRate = encoderBrc->curbe.DW3_TargetBitRate;
413         encoderBrc->curbe.DW8_BRCFlag |= encoderBrc->BRCINIT_ISVCM;
414     }
415     else if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_CQP)
416     {
417         encoderBrc->curbe.DW8_BRCFlag = encoderBrc->BRCINIT_ISCQP;
418     }
419     else if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_QVBR)
420     {
421         if (encoderBrc->curbe.DW4_MaximumBitRate < encoderBrc->curbe.DW3_TargetBitRate)
422         {
423             encoderBrc->curbe.DW4_MaximumBitRate = encoderBrc->curbe.DW3_TargetBitRate; // Use max bit rate for HRD compliance
424         }
425         encoderBrc->curbe.DW8_BRCFlag = encoderBrc->curbe.DW8_BRCFlag | encoderBrc->BRCINIT_ISQVBR | encoderBrc->BRCINIT_ISVBR; // We need to make sure that VBR is used for QP determination.
426         // use ICQQualityFactor to determine the larger Qp for each MB
427         encoderBrc->curbe.DW25_ACQPBuffer = encoderBrc->m_hevcSeqParams->ICQQualityFactor;
428     }
429 
430     encoderBrc->curbe.DW9_FrameWidth = encoderBrc->m_oriFrameWidth;
431     encoderBrc->curbe.DW10_FrameHeight = encoderBrc->m_oriFrameHeight;
432     encoderBrc->curbe.DW10_AVBRAccuracy = encoderBrc->m_usAvbrAccuracy;
433     encoderBrc->curbe.DW11_AVBRConvergence = encoderBrc->m_usAvbrConvergence;
434     encoderBrc->curbe.DW12_NumberSlice = encoderBrc->m_numSlices;
435 
436     /**********************************************************************
437     In case of non-HB/BPyramid Structure
438     BRC_Param_A = GopP
439     BRC_Param_B = GopB
440     In case of HB/BPyramid GOP Structure
441     BRC_Param_A, BRC_Param_B, BRC_Param_C, BRC_Param_D are
442     BRC Parameters set as follows as per CModel equation
443     ***********************************************************************/
444     // BPyramid GOP
445     const auto GopPicSize = encoderBrc->m_hevcSeqParams->GopPicSize;
446     const auto GopRefDist = encoderBrc->m_hevcSeqParams->GopRefDist;
447 
448     encoderBrc->m_HierchGopBRCEnabled = false;
449     if(encoderBrc->m_hevcSeqParams->HierarchicalFlag && GopRefDist > 1 && GopRefDist <= 8 )
450     {
451         uint32_t numB[9]      = {0, 0, 1, 1, 1, 1, 1, 1, 1};
452         uint32_t numB1[9]     = {0, 0, 0, 1, 2, 2, 2, 2, 2};
453         uint32_t numB2[9]     = {0, 0, 0, 0, 0, 1, 2, 3, 4};
454 
455         uint32_t numOfPyramid = (GopPicSize - 1) / GopRefDist;
456         uint32_t remOfPyramid = (GopPicSize - 1) % GopRefDist;
457 
458         encoderBrc->curbe.DW8_BRCGopP   = numOfPyramid * numB[GopRefDist] + numB[remOfPyramid + 1];
459         encoderBrc->curbe.DW9_BRCGopB   = numOfPyramid * numB[GopRefDist] + numB[remOfPyramid];
460         encoderBrc->curbe.DW13_BRCGopB1 = numOfPyramid * numB1[GopRefDist] + numB1[remOfPyramid];
461         encoderBrc->curbe.DW14_BRCGopB2 = numOfPyramid * numB2[GopRefDist] + numB2[remOfPyramid];
462 
463         encoderBrc->m_HierchGopBRCEnabled = true;
464 
465         // B1 Level GOP
466         if (GopRefDist <= 4 || encoderBrc->curbe.DW14_BRCGopB2 == 0)
467         {
468             encoderBrc->curbe.DW14_MaxBRCLevel = 3;
469         }
470         // B2 Level GOP
471         else
472         {
473             encoderBrc->curbe.DW14_MaxBRCLevel = 4;
474         }
475     }
476     // For Regular GOP - No BPyramid
477     else
478     {
479         encoderBrc->curbe.DW14_MaxBRCLevel = 1;
480         encoderBrc->curbe.DW8_BRCGopP      = (GopRefDist) ? MOS_ROUNDUP_DIVIDE(GopPicSize - 1, GopRefDist) : 0;
481         encoderBrc->curbe.DW9_BRCGopB      = GopPicSize - 1 - encoderBrc->curbe.DW8_BRCGopP;
482     }
483 
484     // Set dynamic thresholds
485     double inputBitsPerFrame = (double)((double)encoderBrc->curbe.DW4_MaximumBitRate * (double)encoderBrc->curbe.DW7_FrameRateD);
486     inputBitsPerFrame = (double)(inputBitsPerFrame / encoderBrc->curbe.DW6_FrameRateM);
487 
488     if (encoderBrc->curbe.DW2_BufSize < (uint32_t)inputBitsPerFrame * 4)
489     {
490         encoderBrc->curbe.DW2_BufSize = (uint32_t)inputBitsPerFrame * 4;
491     }
492 
493     if (encoderBrc->curbe.DW1_InitBufFull == 0)
494     {
495         encoderBrc->curbe.DW1_InitBufFull = 7 * encoderBrc->curbe.DW2_BufSize / 8;
496     }
497     if (encoderBrc->curbe.DW1_InitBufFull < (uint32_t)(inputBitsPerFrame * 2))
498     {
499         encoderBrc->curbe.DW1_InitBufFull = (uint32_t)(inputBitsPerFrame * 2);
500     }
501     if (encoderBrc->curbe.DW1_InitBufFull > encoderBrc->curbe.DW2_BufSize)
502     {
503         encoderBrc->curbe.DW1_InitBufFull = encoderBrc->curbe.DW2_BufSize;
504     }
505 
506     if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_AVBR)
507     {
508         // For AVBR, Buffer size =  2*Bitrate, InitVBV = 0.75 * BufferSize
509         encoderBrc->curbe.DW2_BufSize = 2 * encoderBrc->m_hevcSeqParams->TargetBitRate * CODECHAL_ENCODE_BRC_KBPS;
510         encoderBrc->curbe.DW1_InitBufFull = (uint32_t)(0.75 * encoderBrc->curbe.DW2_BufSize);
511     }
512 
513     if (encoderBrc->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW)
514     {
515         encoderBrc->curbe.DW15_LongTermInterval = 0; // no LTR for low delay brc
516     }
517     else
518     {
519         encoderBrc->curbe.DW15_LongTermInterval = (encoderBrc->m_enableBrcLTR && encoderBrc->m_ltrInterval) ?
520                                                    encoderBrc->m_ltrInterval : encoderBrc->m_enableBrcLTR ? HEVC_BRC_LONG_TERM_REFRENCE_FLAG : 0;
521     }
522 
523     double bpsRatio = ( (double) inputBitsPerFrame / (( (double) encoderBrc->curbe.DW2_BufSize) / 30));
524     bpsRatio = (bpsRatio < 0.1) ? 0.1 : (bpsRatio > 3.5) ? 3.5 : bpsRatio;
525 
526     encoderBrc->curbe.DW19_DeviationThreshold0_PBframe = (uint32_t)(-50 * pow(0.90, bpsRatio));
527     encoderBrc->curbe.DW19_DeviationThreshold1_PBframe = (uint32_t)(-50 * pow(0.66, bpsRatio));
528     encoderBrc->curbe.DW19_DeviationThreshold2_PBframe = (uint32_t)(-50 * pow(0.46, bpsRatio));
529     encoderBrc->curbe.DW19_DeviationThreshold3_PBframe = (uint32_t)(-50 * pow(0.3, bpsRatio));
530 
531     encoderBrc->curbe.DW20_DeviationThreshold4_PBframe = (uint32_t)(50 * pow(0.3, bpsRatio));
532     encoderBrc->curbe.DW20_DeviationThreshold5_PBframe = (uint32_t)(50 * pow(0.46, bpsRatio));
533     encoderBrc->curbe.DW20_DeviationThreshold6_PBframe = (uint32_t)(50 * pow(0.7, bpsRatio));
534     encoderBrc->curbe.DW20_DeviationThreshold7_PBframe = (uint32_t)(50 * pow(0.9, bpsRatio));
535 
536     encoderBrc->curbe.DW21_DeviationThreshold0_VBRcontrol = (uint32_t)(-50 * pow(0.9, bpsRatio));
537     encoderBrc->curbe.DW21_DeviationThreshold1_VBRcontrol = (uint32_t)(-50 * pow(0.7, bpsRatio));
538     encoderBrc->curbe.DW21_DeviationThreshold2_VBRcontrol = (uint32_t)(-50 * pow(0.5, bpsRatio));
539     encoderBrc->curbe.DW21_DeviationThreshold3_VBRcontrol = (uint32_t)(-50 * pow(0.3, bpsRatio));
540 
541     encoderBrc->curbe.DW22_DeviationThreshold4_VBRcontrol = (uint32_t)(100 * pow(0.4, bpsRatio));
542     encoderBrc->curbe.DW22_DeviationThreshold5_VBRcontrol = (uint32_t)(100 * pow(0.5, bpsRatio));
543     encoderBrc->curbe.DW22_DeviationThreshold6_VBRcontrol = (uint32_t)(100 * pow(0.75, bpsRatio));
544     encoderBrc->curbe.DW22_DeviationThreshold7_VBRcontrol = (uint32_t)(100 * pow(0.9, bpsRatio));
545 
546     encoderBrc->curbe.DW23_DeviationThreshold0_Iframe = (uint32_t)(-50 * pow(0.8, bpsRatio));
547     encoderBrc->curbe.DW23_DeviationThreshold1_Iframe = (uint32_t)(-50 * pow(0.6, bpsRatio));
548     encoderBrc->curbe.DW23_DeviationThreshold2_Iframe = (uint32_t)(-50 * pow(0.34, bpsRatio));
549     encoderBrc->curbe.DW23_DeviationThreshold3_Iframe = (uint32_t)(-50 * pow(0.2, bpsRatio));
550 
551     encoderBrc->curbe.DW24_DeviationThreshold4_Iframe = (uint32_t)(50 * pow(0.2, bpsRatio));
552     encoderBrc->curbe.DW24_DeviationThreshold5_Iframe = (uint32_t)(50 * pow(0.4, bpsRatio));
553     encoderBrc->curbe.DW24_DeviationThreshold6_Iframe = (uint32_t)(50 * pow(0.66, bpsRatio));
554     encoderBrc->curbe.DW24_DeviationThreshold7_Iframe = (uint32_t)(50 * pow(0.9, bpsRatio));
555 
556     if (encoderBrc->m_hevcSeqParams->HierarchicalFlag && !encoderBrc->m_hevcSeqParams->LowDelayMode &&
557         (encoderBrc->m_hevcSeqParams->GopRefDist == 4 || encoderBrc->m_hevcSeqParams->GopRefDist == 8))
558     {
559         encoderBrc->curbe.DW26_RandomAccess = true;
560     }
561     else
562     {
563         encoderBrc->curbe.DW26_RandomAccess = false;
564     }
565 
566     if (encoderBrc->m_brcInit)
567     {
568         encoderBrc->m_dBrcInitCurrentTargetBufFullInBits = encoderBrc->curbe.DW1_InitBufFull;
569     }
570 
571     encoderBrc->m_brcInitResetBufSizeInBits = encoderBrc->curbe.DW2_BufSize;
572     encoderBrc->m_dBrcInitResetInputBitsPerFrame = inputBitsPerFrame;
573 
574     return eStatus;
575 }
576 
BrcUpdateCurbe()577 MOS_STATUS CodecHalHevcBrcG12::BrcUpdateCurbe()
578 {
579     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
580 
581     // Initialize the CURBE data
582     encoderBrc->curbeBrcUpdate = encoderBrc->m_brcUpdateCurbeInit;
583 
584     encoderBrc->curbeBrcUpdate.DW5_TargetSize_Flag = 0;
585 
586     if (encoderBrc->m_dBrcInitCurrentTargetBufFullInBits > (double)encoderBrc->m_brcInitResetBufSizeInBits)
587     {
588         encoderBrc->m_dBrcInitCurrentTargetBufFullInBits -= (double)encoderBrc->m_brcInitResetBufSizeInBits;
589         encoderBrc->curbeBrcUpdate.DW5_TargetSize_Flag = 1;
590     }
591 
592     if (encoderBrc->m_numSkipFrames)
593     {
594         // pass num/size of skipped frames to update BRC
595         encoderBrc->curbeBrcUpdate.DW6_NumSkippedFrames = encoderBrc->m_numSkipFrames;
596         encoderBrc->curbeBrcUpdate.DW15_SizeOfSkippedFrames = encoderBrc->m_sizeSkipFrames;
597 
598         // account for skipped frame in calculating CurrentTargetBufFullInBits
599         encoderBrc->m_dBrcInitCurrentTargetBufFullInBits += encoderBrc->m_dBrcInitResetInputBitsPerFrame * encoderBrc->m_numSkipFrames;
600     }
601 
602     encoderBrc->curbeBrcUpdate.DW0_TargetSize = (uint32_t)(encoderBrc->m_dBrcInitCurrentTargetBufFullInBits);
603     encoderBrc->curbeBrcUpdate.DW1_FrameNumber = encoderBrc->m_storeData - 1; // Check if we can remove this (set to 0)
604 
605     uint32_t picHdrSize = encoderBrc->GetPicHdrSize();
606     encoderBrc->curbeBrcUpdate.DW2_PictureHeaderSize = picHdrSize;
607 
608     encoderBrc->curbeBrcUpdate.DW5_CurrFrameBrcLevel = encoderBrc->m_currFrameBrcLevel;
609 
610     encoderBrc->curbeBrcUpdate.DW5_MaxNumPAKs = m_brcNumPakPasses;
611 
612     if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_CQP)
613     {
614         encoderBrc->curbeBrcUpdate.DW6_CqpValue = encoderBrc->m_hevcPicParams->QpY + encoderBrc->m_hevcSliceParams->slice_qp_delta;
615     }
616 
617     encoderBrc->curbeBrcUpdate.DW6_SlidingWindowEnable = (encoderBrc->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_LOW);
618 
619     if (encoderBrc->m_hevcPicParams->NumROI)
620     {
621         encoderBrc->curbeBrcUpdate.DW6_ROIEnable = encoderBrc->m_brcEnabled ? false : true;
622         encoderBrc->curbeBrcUpdate.DW6_BRCROIEnable = encoderBrc->m_brcEnabled ? true : false;
623         encoderBrc->curbeBrcUpdate.DW6_RoiRatio = encoderBrc->CalculateROIRatio();
624     }
625 
626     if (encoderBrc->m_minMaxQpControlEnabled)
627     {
628         if (encoderBrc->m_hevcPicParams->CodingType == I_TYPE)
629         {
630             encoderBrc->curbeBrcUpdate.DW7_FrameMaxQP = encoderBrc->m_maxQpForI;
631             encoderBrc->curbeBrcUpdate.DW7_FrameMinQP = encoderBrc->m_minQpForI;
632         }
633         else if (encoderBrc->m_hevcPicParams->CodingType == P_TYPE)
634         {
635             encoderBrc->curbeBrcUpdate.DW7_FrameMaxQP = encoderBrc->m_maxQpForP;
636             encoderBrc->curbeBrcUpdate.DW7_FrameMinQP = encoderBrc->m_minQpForP;
637         }
638         else if (encoderBrc->m_hevcPicParams->CodingType == B_TYPE)
639         {
640             encoderBrc->curbeBrcUpdate.DW7_FrameMaxQP = encoderBrc->m_maxQpForB;
641             encoderBrc->curbeBrcUpdate.DW7_FrameMinQP = encoderBrc->m_minQpForB;
642         }
643     }
644 
645     //for low delay brc
646     encoderBrc->curbeBrcUpdate.DW6_LowDelayEnable      = (encoderBrc->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW);
647     encoderBrc->curbeBrcUpdate.DW16_UserMaxFrameSize   = encoderBrc->GetProfileLevelMaxFrameSize();
648 
649     encoderBrc->curbeBrcUpdate.DW14_ParallelMode = encoderBrc->m_hevcSeqParams->ParallelBRC;
650 
651     if (encoderBrc->m_hevcSeqParams->RateControlMethod == RATECONTROL_AVBR)
652     {
653         encoderBrc->curbeBrcUpdate.DW3_StartGAdjFrame0 = (uint32_t)((10 * encoderBrc->m_usAvbrConvergence) / (double)150);
654         encoderBrc->curbeBrcUpdate.DW3_StartGAdjFrame1 = (uint32_t)((50 * encoderBrc->m_usAvbrConvergence) / (double)150);
655         encoderBrc->curbeBrcUpdate.DW4_StartGAdjFrame2 = (uint32_t)((100 * encoderBrc->m_usAvbrConvergence) / (double)150);
656         encoderBrc->curbeBrcUpdate.DW4_StartGAdjFrame3 = (uint32_t)((150 * encoderBrc->m_usAvbrConvergence) / (double)150);
657 
658         encoderBrc->curbeBrcUpdate.DW11_gRateRatioThreshold0 =
659             (uint32_t)((100 - (encoderBrc->m_usAvbrAccuracy / (double)30)*(100 - 40)));
660         encoderBrc->curbeBrcUpdate.DW11_gRateRatioThreshold1 =
661             (uint32_t)((100 - (encoderBrc->m_usAvbrAccuracy / (double)30)*(100 - 75)));
662         encoderBrc->curbeBrcUpdate.DW12_gRateRatioThreshold2 = (uint32_t)((100 - (encoderBrc->m_usAvbrAccuracy / (double)30)*(100 - 97)));
663         encoderBrc->curbeBrcUpdate.DW12_gRateRatioThreshold3 = (uint32_t)((100 + (encoderBrc->m_usAvbrAccuracy / (double)30)*(103 - 100)));
664         encoderBrc->curbeBrcUpdate.DW12_gRateRatioThreshold4 = (uint32_t)((100 + (encoderBrc->m_usAvbrAccuracy / (double)30)*(125 - 100)));
665         encoderBrc->curbeBrcUpdate.DW12_gRateRatioThreshold5 = (uint32_t)((100 + (encoderBrc->m_usAvbrAccuracy / (double)30)*(160 - 100)));
666     }
667 
668     if (encoderBrc->m_hevcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW)
669     {
670         encoderBrc->curbeBrcUpdate.DW17_LongTerm_Current = 0; // no LTR for low delay brc
671     }
672     else
673     {
674         encoderBrc->m_isFrameLTR = (CodecHal_PictureIsLongTermRef(encoderBrc->m_currReconstructedPic));
675         encoderBrc->curbeBrcUpdate.DW17_LongTerm_Current = (encoderBrc->m_enableBrcLTR && encoderBrc->m_isFrameLTR) ? 1 : 0;
676     }
677 
678     return eStatus;
679 }
EncodeBrcFrameUpdateKernel()680 MOS_STATUS CodecHalHevcBrcG12::EncodeBrcFrameUpdateKernel()
681 {
682     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
683     CODECHAL_ENCODE_FUNCTION_ENTER;
684 
685     PerfTagSetting perfTag;
686     perfTag.Value = 0;
687     perfTag.Mode = (uint16_t)encoderBrc->m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
688     perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE;
689     perfTag.PictureCodingType = encoderBrc->m_pictureCodingType;
690     encoderBrc->GetOsInterface()->pfnSetPerfTag(encoderBrc->GetOsInterface(), perfTag.Value);
691     encoderBrc->GetOsInterface()->pfnIncPerfBufferID(encoderBrc->GetOsInterface());
692 
693     if (!m_threadSpaceBrcUpdate)
694     {
695         CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupThreadSpace(m_cmKrnBrcUpdate, m_threadSpaceBrcUpdate));
696     }
697 
698     CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcUpdateCurbe());
699     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupSurfacesBrcUpdate());
700     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupKernelArgsBrcUpdate());
701     CODECHAL_DEBUG_TOOL(
702         CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpBrcInputBuffers()));
703 
704     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmTask->AddKernel(m_cmKrnBrcUpdate));
705 
706     if (!encoderBrc->m_singleTaskPhaseSupported || encoderBrc->m_lastTaskInPhase)
707     {
708         CmEvent * event = CM_NO_EVENT;
709         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmQueue->EnqueueFast(encoderBrc->m_cmTask, event));
710 
711         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmTask->Reset());
712 
713         encoderBrc->m_lastTaskInPhase = false;
714     }
715     else
716     {
717         encoderBrc->m_cmTask->AddSync();
718     }
719     return eStatus;
720 }
721 
SetupSurfacesBrcUpdate()722 MOS_STATUS CodecHalHevcBrcG12::SetupSurfacesBrcUpdate()
723 {
724     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
725 
726     // Fill HCP_IMG_STATE so that BRC kernel can use it to generate the write buffer for PAK
727     PMOS_RESOURCE brcHcpStateReadBuffer = &encoderBrc->m_brcBuffers.resBrcImageStatesReadBuffer[encoderBrc->m_currRecycledBufIdx];
728     MHW_VDBOX_HEVC_PIC_STATE_G12 mhwHevcPicState;
729     mhwHevcPicState.pHevcEncSeqParams = encoderBrc->m_hevcSeqParams;
730     mhwHevcPicState.pHevcEncPicParams = encoderBrc->m_hevcPicParams;
731     mhwHevcPicState.brcNumPakPasses = m_brcNumPakPasses;
732     mhwHevcPicState.rhodomainRCEnable = encoderBrc->m_brcEnabled && (encoderBrc->m_numPipe > 1);
733     mhwHevcPicState.bSAOEnable = encoderBrc->m_hevcSeqParams->SAO_enabled_flag ? (encoderBrc->m_hevcSliceParams->slice_sao_luma_flag || encoderBrc->m_hevcSliceParams->slice_sao_chroma_flag) : 0;
734     mhwHevcPicState.bTransformSkipEnable = encoderBrc->m_hevcPicParams->transform_skip_enabled_flag;
735     mhwHevcPicState.bHevcRdoqEnabled      = encoderBrc->m_hevcRdoqEnabled;
736     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_hcpInterface->AddHcpHevcPicBrcBuffer(brcHcpStateReadBuffer, &mhwHevcPicState));
737 
738     PMOS_SURFACE brcConstantData = &encoderBrc->m_brcBuffers.sBrcConstantDataBuffer[encoderBrc->m_currRecycledBufIdx];
739     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->SetupBrcConstantTable(brcConstantData));
740 
741     if (!m_histBufferBrc)
742     {
743         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateBuffer(
744             &encoderBrc->m_brcBuffers.resBrcHistoryBuffer, //m_brcHistoryBufferSize,
745             m_histBufferBrc));
746     }
747 
748     // BRC Prev PAK statistics output buffer
749     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->UpdateBuffer(
750         &encoderBrc->m_brcBuffers.resBrcPakStatisticBuffer[encoderBrc->m_brcBuffers.uiCurrBrcPakStasIdxForRead],
751         m_PAKStatsBufferBrc));
752 
753     // BRC HCP_PIC_STATE read
754     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->UpdateBuffer(
755         brcHcpStateReadBuffer,
756         m_PICStateInBufferBrc));
757 
758     // BRC HCP_PIC_STATE write
759     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->UpdateBuffer(
760         &encoderBrc->m_brcBuffers.resBrcImageStatesWriteBuffer[encoderBrc->m_currRecycledBufIdx],
761         m_PICStateOutBufferBrc));
762 
763     // BRC Data Surface
764     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->UpdateSurface2D(
765         &brcConstantData->OsResource,
766         m_ConstDataBufferBRC));
767 
768     // Pixel MB Statistics surface
769     if (!m_PixelMBStatsBufferBrc)
770     {
771         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateBuffer(
772             &encoderBrc->m_resMbStatsBuffer,
773             m_PixelMBStatsBufferBrc));
774     }
775 
776     // Combined ENC-parameter buffer
777     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->UpdateBuffer(
778         &encoderBrc->m_brcInputForEncKernelBuffer->sResource,
779         m_CombinedEncBufferBrc));
780 
781     return eStatus;
782 }
783 
SetupKernelArgsBrcUpdate()784 MOS_STATUS CodecHalHevcBrcG12::SetupKernelArgsBrcUpdate()
785 {
786     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
787 
788     int idx = 0;
789     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(encoderBrc->m_brcUpdateCurbeInit), &encoderBrc->curbeBrcUpdate));
790 
791     SurfaceIndex *pIndex0 = nullptr;
792     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_histBufferBrc->GetIndex(pIndex0));
793     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
794 
795     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_PAKStatsBufferBrc->GetIndex(pIndex0));
796     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
797 
798     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_PICStateInBufferBrc->GetIndex(pIndex0));
799     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
800 
801     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_PICStateOutBufferBrc->GetIndex(pIndex0));
802     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
803 
804     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_CombinedEncBufferBrc->GetIndex(pIndex0));
805     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
806 
807     //Setup Distortion 2D surface
808     CmSurface2D *brcDistortion = (encoderBrc->m_pictureCodingType == I_TYPE) ? encoderBrc->m_brcBuffers.brcIntraDistortionSurface
809                                                                              : encoderBrc->m_brcBuffers.meBrcDistortionSurface;
810     CODECHAL_ENCODE_CHK_STATUS_RETURN(brcDistortion->GetIndex(pIndex0));
811     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
812 
813     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_ConstDataBufferBRC->GetIndex(pIndex0));
814     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
815 
816     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_PixelMBStatsBufferBrc->GetIndex(pIndex0));
817     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
818 
819     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_brcBuffers.mvAndDistortionSumSurface->GetIndex(pIndex0));
820     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcUpdate->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
821 
822     return eStatus;
823 }
824 
EncodeBrcLcuUpdateKernel()825 MOS_STATUS CodecHalHevcBrcG12::EncodeBrcLcuUpdateKernel()
826 {
827     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
828     CODECHAL_ENCODE_FUNCTION_ENTER;
829 
830     PerfTagSetting perfTag;
831     perfTag.Value = 0;
832     perfTag.Mode = (uint16_t)encoderBrc->m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
833     perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE_LCU;
834     perfTag.PictureCodingType = encoderBrc->m_pictureCodingType;
835     encoderBrc->GetOsInterface()->pfnSetPerfTag(encoderBrc->GetOsInterface(), perfTag.Value);
836     encoderBrc->GetOsInterface()->pfnIncPerfBufferID(encoderBrc->GetOsInterface());
837 
838     CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcUpdateCurbe());
839     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupSurfacesBrcLcuQp());
840 
841     if (encoderBrc->m_hevcPicParams->NumROI)
842     {
843         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->SetupROISurface());
844     }
845 
846     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupKernelArgsBrcLcuQp());
847 
848     if (encoderBrc->m_resolutionChanged && m_threadSpaceBrcLCUQP)
849     {
850         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->DestroyThreadSpace(m_threadSpaceBrcLCUQP));
851         m_threadSpaceBrcLCUQP = nullptr;
852     }
853 
854     if (!m_threadSpaceBrcLCUQP)
855     {
856         CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupBrcLcuqpThreadSpace(m_cmKrnBrcLCUQP, m_threadSpaceBrcLCUQP));
857     }
858 
859     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmTask->AddKernel(m_cmKrnBrcLCUQP));
860 
861     if (!encoderBrc->m_singleTaskPhaseSupported || encoderBrc->m_lastTaskInPhase)
862     {
863         CmEvent * event = CM_NO_EVENT;
864         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmQueue->EnqueueFast(encoderBrc->m_cmTask, event));
865 
866         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmTask->Reset());
867 
868         encoderBrc->m_lastTaskInPhase = false;
869     }
870     else
871     {
872         encoderBrc->m_cmTask->AddSync();
873     }
874 
875     return eStatus;
876 }
877 
SetupSurfacesBrcLcuQp()878 MOS_STATUS CodecHalHevcBrcG12::SetupSurfacesBrcLcuQp()
879 {
880     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
881 
882     if (!m_histBufferBrc)
883     {
884         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateBuffer(
885              &encoderBrc->m_brcBuffers.resBrcHistoryBuffer,
886              m_histBufferBrc));
887     }
888 
889     // Pixel MB Statistics surface
890     if (!m_PixelMBStatsBufferBrc)
891     {
892         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateBuffer(
893              &encoderBrc->m_resMbStatsBuffer,
894              m_PixelMBStatsBufferBrc));
895     }
896 
897     if (!m_BrcMbQp) {
898 
899         // BRC Data Surface
900         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateSurface2D(
901             &encoderBrc->m_brcBuffers.sBrcMbQpBuffer.OsResource,
902             m_BrcMbQp));
903     }
904 
905     if (!m_BrcROISurf)
906     {
907         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->m_cmDev->CreateSurface2D(
908             &encoderBrc->m_brcBuffers.sBrcRoiSurface.OsResource,
909             m_BrcROISurf));
910     }
911 
912     return eStatus;
913 }
914 
SetupKernelArgsBrcLcuQp()915 MOS_STATUS CodecHalHevcBrcG12::SetupKernelArgsBrcLcuQp()
916 {
917     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
918 
919     int idx = 0;
920     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcLCUQP->SetKernelArg(idx++, sizeof(encoderBrc->m_brcUpdateCurbeInit), &encoderBrc->curbeBrcUpdate));
921 
922     SurfaceIndex *pIndex0 = nullptr;
923     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_histBufferBrc->GetIndex(pIndex0));
924     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcLCUQP->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
925 
926     //Setup Distortion 2D surface
927     CmSurface2D *brcDistortion = (encoderBrc->m_pictureCodingType == I_TYPE) ? encoderBrc->m_brcBuffers.brcIntraDistortionSurface
928                                                                              : encoderBrc->m_brcBuffers.meBrcDistortionSurface;
929     CODECHAL_ENCODE_CHK_STATUS_RETURN(brcDistortion->GetIndex(pIndex0));
930 
931     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcLCUQP->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
932 
933     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_PixelMBStatsBufferBrc->GetIndex(pIndex0));
934     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcLCUQP->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
935 
936     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_BrcMbQp->GetIndex(pIndex0));
937     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcLCUQP->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
938 
939     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_BrcROISurf->GetIndex(pIndex0));
940     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrnBrcLCUQP->SetKernelArg(idx++, sizeof(SurfaceIndex), pIndex0));
941     return eStatus;
942 }
943 
944 #if USE_CODECHAL_DEBUG_TOOL
DumpBrcInputBuffers()945 MOS_STATUS CodecHalHevcBrcG12::DumpBrcInputBuffers()
946 {
947     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
948 
949     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->GetDebugInterface()->DumpBuffer(
950         &encoderBrc->m_mvAndDistortionSumSurface.sResource,
951         CodechalDbgAttr::attrInput,
952         "MvDistSum",
953         encoderBrc->m_mvAndDistortionSumSurface.dwSize,
954         0,
955         CODECHAL_MEDIA_STATE_BRC_UPDATE));
956 
957     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->GetDebugInterface()->DumpBuffer(
958         &encoderBrc->m_brcBuffers.resBrcImageStatesReadBuffer[encoderBrc->m_currRecycledBufIdx],
959         CodechalDbgAttr::attrInput,
960         "ImgStateRead",
961         BRC_IMG_STATE_SIZE_PER_PASS * encoderBrc->GetHwInterface()->GetMfxInterface()->GetBrcNumPakPasses(),
962         0,
963         CODECHAL_MEDIA_STATE_BRC_UPDATE));
964 
965     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->GetDebugInterface()->DumpSurface(
966         &encoderBrc->m_brcBuffers.sBrcConstantDataBuffer[encoderBrc->m_currRecycledBufIdx],
967         CodechalDbgAttr::attrInput,
968         "ConstData",
969         CODECHAL_MEDIA_STATE_BRC_UPDATE));
970 
971     // PAK statistics buffer is only dumped for BrcUpdate kernel input
972     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->GetDebugInterface()->DumpBuffer(
973         &encoderBrc->m_brcBuffers.resBrcPakStatisticBuffer[encoderBrc->m_brcBuffers.uiCurrBrcPakStasIdxForRead],
974         CodechalDbgAttr::attrInput,
975         "PakStats",
976         HEVC_BRC_PAK_STATISTCS_SIZE,
977         0,
978         CODECHAL_MEDIA_STATE_BRC_UPDATE));
979     // HEVC maintains a ptr to its own distortion surface, as it may be a couple different surfaces
980     if (encoderBrc->m_brcDistortion)
981     {
982         CODECHAL_ENCODE_CHK_STATUS_RETURN(
983             encoderBrc->GetDebugInterface()->DumpBuffer(
984                 &encoderBrc->m_brcDistortion->OsResource,
985                 CodechalDbgAttr::attrInput,
986                 "BrcDist_BeforeFrameBrc",
987                 encoderBrc->m_brcBuffers.sMeBrcDistortionBuffer.dwPitch * encoderBrc->m_brcBuffers.sMeBrcDistortionBuffer.dwHeight,
988                 encoderBrc->m_brcBuffers.dwMeBrcDistortionBottomFieldOffset,
989                 CODECHAL_MEDIA_STATE_BRC_UPDATE));
990     }
991 
992     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->GetDebugInterface()->DumpBuffer(&encoderBrc->m_brcBuffers.resBrcHistoryBuffer,
993         CodechalDbgAttr::attrInput,
994         "HistoryRead_beforeFramBRC",
995         encoderBrc->m_brcHistoryBufferSize,
996         0,
997         CODECHAL_MEDIA_STATE_BRC_UPDATE));
998 
999     if (encoderBrc->m_brcBuffers.pMbEncKernelStateInUse)
1000     {
1001         CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->GetDebugInterface()->DumpCurbe(
1002             CODECHAL_MEDIA_STATE_BRC_UPDATE,
1003             encoderBrc->m_brcBuffers.pMbEncKernelStateInUse));
1004     }
1005 
1006     CODECHAL_ENCODE_CHK_STATUS_RETURN(encoderBrc->GetDebugInterface()->DumpBuffer(&encoderBrc->m_resMbStatsBuffer,
1007         CodechalDbgAttr::attrInput,
1008         "MBStatsSurf",
1009         encoderBrc->GetHwInterface()->m_avcMbStatBufferSize,
1010         0,
1011         CODECHAL_MEDIA_STATE_BRC_UPDATE));
1012 
1013     return eStatus;
1014 }
1015 #endif
1016