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