1 /*
2 * Copyright (c) 2011-2017, 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_vdenc_avc_g9_skl.cpp
24 //! \brief This file implements the C++ class/interface for SKL's AVC
25 //! VDEnc encoding to be used CODECHAL components.
26 //!
27
28 #include "codechal_vdenc_avc_g9_skl.h"
29 #if USE_CODECHAL_DEBUG_TOOL
30 #include "mhw_vdbox_mfx_hwcmd_g9_skl.h"
31 #include "mhw_vdbox_vdenc_hwcmd_g9_skl.h"
32 #endif
33
34 typedef struct _CODECHAL_ENCODE_AVC_KERNEL_HEADER_G9_SKL {
35 int nKernelCount;
36
37 // Quality mode for Frame/Field
38 CODECHAL_KERNEL_HEADER AVCMBEnc_Qlty_I;
39 CODECHAL_KERNEL_HEADER AVCMBEnc_Qlty_P;
40 CODECHAL_KERNEL_HEADER AVCMBEnc_Qlty_B;
41 // Normal mode for Frame/Field
42 CODECHAL_KERNEL_HEADER AVCMBEnc_Norm_I;
43 CODECHAL_KERNEL_HEADER AVCMBEnc_Norm_P;
44 CODECHAL_KERNEL_HEADER AVCMBEnc_Norm_B;
45 // Performance modes for Frame/Field
46 CODECHAL_KERNEL_HEADER AVCMBEnc_Perf_I;
47 CODECHAL_KERNEL_HEADER AVCMBEnc_Perf_P;
48 CODECHAL_KERNEL_HEADER AVCMBEnc_Perf_B;
49 // Modes for Frame/Field
50 CODECHAL_KERNEL_HEADER AVCMBEnc_Adv_I;
51 CODECHAL_KERNEL_HEADER AVCMBEnc_Adv_P;
52 CODECHAL_KERNEL_HEADER AVCMBEnc_Adv_B;
53
54 // HME
55 CODECHAL_KERNEL_HEADER AVC_ME_P;
56 CODECHAL_KERNEL_HEADER AVC_ME_B;
57
58 // DownScaling
59 CODECHAL_KERNEL_HEADER PLY_DScale_PLY;
60 CODECHAL_KERNEL_HEADER PLY_DScale_2f_PLY_2f;
61
62 // BRC Init frame
63 CODECHAL_KERNEL_HEADER InitFrameBRC;
64
65 // FrameBRC Update
66 CODECHAL_KERNEL_HEADER FrameENCUpdate;
67
68 // BRC Reset frame
69 CODECHAL_KERNEL_HEADER BRC_ResetFrame;
70
71 // BRC I Frame Distortion
72 CODECHAL_KERNEL_HEADER BRC_IFrame_Dist;
73
74 // BRCBlockCopy
75 CODECHAL_KERNEL_HEADER BRCBlockCopy;
76
77 // MbBRC Update
78 CODECHAL_KERNEL_HEADER MbBRCUpdate;
79
80 // 2x DownScaling
81 CODECHAL_KERNEL_HEADER PLY_2xDScale_PLY;
82 CODECHAL_KERNEL_HEADER PLY_2xDScale_2f_PLY_2f;
83
84 //Motion estimation kernel for the VDENC StreamIN
85 CODECHAL_KERNEL_HEADER AVC_ME_VDENC;
86
87 //Weighted Prediction Kernel
88 CODECHAL_KERNEL_HEADER AVC_WeightedPrediction;
89
90 // Static frame detection Kernel
91 CODECHAL_KERNEL_HEADER AVC_StaticFrameDetection;
92 } CODECHAL_ENCODE_AVC_KERNEL_HEADER_G9_SKL, *PCODECHAL_ENCODE_AVC_KERNEL_HEADER_G9_SKL;
93
94 typedef struct _CODECHAL_VDENC_AVC_BRC_INIT_DMEM_G9_SKL
95 {
96 uint8_t BRCFunc_U8; // 0: Init; 2: Reset
97 uint8_t OpenSourceEnable_U8; // 0: disable opensource, 1: enable opensource
98 uint8_t RVSD[2];
99 uint16_t INIT_BRCFlag_U16; // ICQ or CQP with slice size control: 0x00 CBR: 0x10; VBR: 0x20; VCM: 0x40; LOWDELAY: 0x80.
100 uint16_t Reserved;
101 uint16_t INIT_FrameWidth_U16; // Luma width in bytes
102 uint16_t INIT_FrameHeight_U16; // Luma height in bytes
103 uint32_t INIT_TargetBitrate_U32; // target bitrate, set by application
104 uint32_t INIT_MinRate_U32; // 0
105 uint32_t INIT_MaxRate_U32; // Maximum bit rate in bits per second (bps).
106 uint32_t INIT_BufSize_U32; // buffer size
107 uint32_t INIT_InitBufFull_U32; // initial buffer fullness
108 uint32_t INIT_ProfileLevelMaxFrame_U32; // user defined. refer to AVC BRC for conformance check and correction
109 uint32_t INIT_FrameRateM_U32; // FrameRateM is the number of frames in FrameRateD
110 uint32_t INIT_FrameRateD_U32; // If driver gets this FrameRateD from VUI, it is the num_units_in_tick field (32 bits unsigned integer).
111 uint16_t INIT_GopP_U16; // number of P frames in a GOP
112 uint16_t INIT_GopB_U16; // number of B frames in a GOP
113 uint16_t INIT_MinQP_U16; // 10
114 uint16_t INIT_MaxQP_U16; // 51
115 int8_t INIT_DevThreshPB0_S8[8]; // lowdelay ? (-45, -33, -23, -15, -8, 0, 15, 25) : (-46, -38, -30, -23, 23, 30, 40, 46)
116 int8_t INIT_DevThreshVBR0_S8[8]; // lowdelay ? (-45, -35, -25, -15, -8, 0, 20, 40) : (-46, -40, -32, -23, 56, 64, 83, 93)
117 int8_t INIT_DevThreshI0_S8[8]; // lowdelay ? (-40, -30, -17, -10, -5, 0, 10, 20) : (-43, -36, -25, -18, 18, 28, 38, 46)
118 uint8_t INIT_InitQPIP; // Initial QP for I and P
119
120 uint8_t INIT_NotUseRhoDm_U8; // Reserved
121 uint8_t INIT_InitQPB; // Initial QP for B
122 uint8_t INIT_MbQpCtrl_U8; // Enable MB level QP control (global)
123 uint8_t INIT_SliceSizeCtrlEn_U8; // Enable slice size control
124 int8_t INIT_IntraQPDelta_I8[3]; // set to zero for all by default
125 int8_t INIT_SkipQPDelta_I8; // Reserved
126 int8_t INIT_DistQPDelta_I8[4]; // lowdelay ? (-5, -2, 2, 5) : (0, 0, 0, 0)
127 uint8_t INIT_OscillationQpDelta_U8; // BRCFLAG_ISVCM ? 16 : 0
128 uint8_t INIT_HRDConformanceCheckDisable_U8; // BRCFLAG_ISAVBR ? 1 : 0
129 uint8_t INIT_SkipFrameEnableFlag;
130 uint8_t INIT_TopQPDeltaThrForAdapt2Pass_U8; // =1. QP Delta threshold for second pass.
131 uint8_t INIT_TopFrmSzThrForAdapt2Pass_U8; // lowdelay ? 10 : 50. Top frame size threshold for second pass
132 uint8_t INIT_BotFrmSzThrForAdapt2Pass_U8; // lowdelay ? 10 : 200. Bottom frame size threshold for second pass
133 uint8_t INIT_QPSelectForFirstPass_U8; // lowdelay ? 0 : 1. =0 to use previous frame final QP; or =1 to use (targetQP + previousQP) / 2.
134 uint8_t INIT_MBHeaderCompensation_U8; // Reserved
135 uint8_t INIT_OverShootCarryFlag_U8; // set to zero by default
136 uint8_t INIT_OverShootSkipFramePct_U8; // set to zero by default
137 uint8_t INIT_EstRateThreshP0_U8[7]; // 4, 8, 12, 16, 20, 24, 28
138 uint8_t INIT_EstRateThreshB0_U8[7]; // 4, 8, 12, 16, 20, 24, 28
139 uint8_t INIT_EstRateThreshI0_U8[7]; // 4, 8, 12, 16, 20, 24, 28
140 uint8_t INIT_FracQPEnable_U8; // ExtendedRhoDomainEn from par file
141 uint8_t INIT_ScenarioInfo_U8; // 0: UNKNOWN, 1: DISPLAYREMOTING, 2: VIDEOCONFERENCE, 3: ARCHIVE, 4: LIVESTREAMING.
142 uint8_t INIT_StaticRegionStreamIn_U8; // should be programmed from par file
143 uint8_t INIT_DeltaQP_Adaptation_U8; // =1, should be programmed from par file
144 uint8_t INIT_MaxCRFQualityFactor_U8; // =52, should be programmed from par file
145 uint8_t INIT_CRFQualityFactor_U8; // =25, should be programmed from par file
146 uint8_t INIT_BotQPDeltaThrForAdapt2Pass_U8; // =1. QP Delta threshold for second pass.
147 uint8_t INIT_SlidingWindowSize_U8; // =30, the window size (in frames) used to compute bit rate
148 uint8_t INIT_SlidingWidowRCEnable_U8; // =0, sliding window based rate control (SWRC) disabled, 1: enabled
149 uint8_t INIT_SlidingWindowMaxRateRatio_U8; // =120, ratio between the max rate within the window and average target bitrate
150 uint8_t INIT_LowDelayGoldenFrameBoost_U8; // only for lowdelay mode, 0 (default): no boost for I and scene change frames, 1: boost
151 uint8_t RSVD2[61]; // must be zero
152 } CODECHAL_VDENC_AVC_BRC_INIT_DMEM_G9_SKL, *PCODECHAL_VDENC_AVC_BRC_INIT_DMEM_G9_SKL;
153
154 typedef struct _CODECHAL_VDENC_AVC_BRC_UPDATE_DMEM_G9_SKL
155 {
156 uint8_t BRCFunc_U8; // =1 for Update, other values are reserved for future use
157 uint8_t RSVD[3];
158 uint32_t UPD_TARGETSIZE_U32; // refer to AVC BRC for calculation
159 uint32_t UPD_FRAMENUM_U32; // frame number
160 uint32_t UPD_PeakTxBitsPerFrame_U32; // current global target bits - previous global target bits (global target bits += input bits per frame)
161 uint32_t UPD_FrameBudget_U32; // target time counter
162 uint32_t FrameByteCount; // PAK output via MMIO
163 uint32_t TimingBudgetOverflow; // PAK output via MMIO
164 uint32_t ImgStatusCtrl; // PAK output via MMIO
165 uint32_t IPCMNonConformant; // PAK output via MMIO
166
167 uint16_t UPD_startGAdjFrame_U16[4]; // 10, 50, 100, 150
168 uint16_t UPD_MBBudget_U16[52]; // MB bugdet for QP 0 � 51.
169 uint16_t UPD_SLCSZ_TARGETSLCSZ_U16; // target slice size
170 uint16_t UPD_SLCSZ_UPD_THRDELTAI_U16[42]; // slice size threshold delta for I frame
171 uint16_t UPD_SLCSZ_UPD_THRDELTAP_U16[42]; // slice size threshold delta for P frame
172 uint16_t UPD_NumOfFramesSkipped_U16; // Recording how many frames have been skipped.
173 uint16_t UPD_SkipFrameSize_U16; // Recording the skip frame size for one frame. =NumMBs * 1, assuming one bit per mb for skip frame.
174 uint16_t UPD_StaticRegionPct_U16; // One entry, recording the percentage of static region
175 uint8_t UPD_gRateRatioThreshold_U8[7]; // 80,95,99,101,105,125,160
176 uint8_t UPD_CurrFrameType_U8; // I frame: 2; P frame: 0; B frame: 1.
177 uint8_t UPD_startGAdjMult_U8[5]; // 1, 1, 3, 2, 1
178 uint8_t UPD_startGAdjDiv_U8[5]; // 40, 5, 5, 3, 1
179 uint8_t UPD_gRateRatioThresholdQP_U8[8]; // 253,254,255,0,1,1,2,3
180 uint8_t UPD_PAKPassNum_U8; // current pak pass number
181 uint8_t UPD_MaxNumPass_U8; // 2
182 uint8_t UPD_SceneChgWidth_U8[2]; // set both to MIN((NumP + 1) / 5, 6)
183 uint8_t UPD_SceneChgDetectEn_U8; // Enable scene change detection
184 uint8_t UPD_SceneChgPrevIntraPctThreshold_U8; // =96. scene change previous intra percentage threshold
185 uint8_t UPD_SceneChgCurIntraPctThreshold_U8; // =192. scene change current intra percentage threshold
186 uint8_t UPD_IPAverageCoeff_U8; // lowdelay ? 0 : 128
187 uint8_t UPD_MinQpAdjustment_U8; // Minimum QP increase step
188 uint8_t UPD_TimingBudgetCheck_U8; // Flag indicating if kernel will check timing budget.
189 int8_t UPD_ROIQpDelta_I8[4]; // Application specified ROI QP Adjustment for Zone0, Zone1, Zone2 and Zone3.
190 uint8_t UPD_CQP_QpValue_U8; // Application specified target QP in BRC_ICQ mode
191 uint8_t UPD_CQP_FracQp_U8; // Application specified fine position in BRC_ICQ mode
192 uint8_t UPD_HMEDetectionEnable_U8; // 0: default, 1: HuC BRC kernel requires information from HME detection kernel output
193 uint8_t UPD_HMECostEnable_U8; // 0: default, 1: driver provides HME cost table
194 uint8_t UPD_DisablePFrame8x8Transform_U8; // 0: enable, 1: disable
195 uint8_t UPD_SklCabacWAEnable_U8; // 0: disable, 1: enable
196 uint8_t UPD_ROISource_U8; // =0: disable, 1: ROIMap from HME Static Region or from App dirty rectangle, 2: ROIMap from App
197 uint8_t UPD_SLCSZ_ConsertativeThreshold_U8; // =0, 0: do not set conservative threshold (suggested for video conference) 1: set conservative threshold for non-video conference
198 uint16_t UPD_TargetSliceSize_U16; // default: 1498, max target slice size from app DDI
199 uint16_t UPD_MaxNumSliceAllowed_U16; // computed by driver based on level idc
200 uint16_t UPD_SLBB_Size_U16; // second level batch buffer (SLBB) size in bytes, the input buffer will contain two SLBBs A and B, A followed by B, A and B have the same structure.
201 uint16_t UPD_SLBB_B_Offset_U16; // offset in bytes from the beginning of the input buffer, it points to the start of SLBB B, set by driver for skip frame support
202 uint16_t UPD_AvcImgStateOffset_U16; // offset in bytes from the beginning of SLBB A
203
204 /* HME distortion based QP adjustment */
205 uint16_t AveHmeDist_U16;
206 uint8_t HmeDistAvailable_U8; // 0: disabled, 1: enabled
207
208 uint16_t AdditionalFrameSize_U16; // for slice size control improvement
209 uint8_t RSVD2;
210 uint8_t UPD_RoiQpViaForceQp_U8;
211
212 uint8_t RSVD3[59];
213 } CODECHAL_VDENC_AVC_BRC_UPDATE_DMEM_G9_SKL, *PCODECHAL_VDENC_AVC_BRC_UPDATE_DMEM_G9_SKL;
214
215 const uint32_t CodechalVdencAvcStateG9Skl::MV_Cost_SkipBias_QPel[8] =
216 {
217 //PREDSLICE
218 0, 6, 6, 9, 10, 13, 14, 16
219 };
220
221 const uint32_t CodechalVdencAvcStateG9Skl::HmeCost[8][CODEC_AVC_NUM_QP] =
222 {
223 //mv=0
224 {
225 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[0 ~12]
226 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[13 ~25]
227 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[26 ~38]
228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[39 ~51]
229 },
230 //mv<=16
231 {
232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[0 ~12]
233 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[13 ~25]
234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[26 ~38]
235 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[39 ~51]
236 },
237 //mv<=32
238 {
239 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //QP=[0 ~12]
240 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //QP=[13 ~25]
241 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //QP=[26 ~38]
242 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //QP=[39 ~51]
243 },
244 //mv<=64
245 {
246 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, //QP=[0 ~12]
247 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, //QP=[13 ~25]
248 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, //QP=[26 ~38]
249 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, //QP=[39 ~51]
250 },
251 //mv<=128
252 {
253 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, //QP=[0 ~12]
254 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, //QP=[13 ~25]
255 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, //QP=[26 ~38]
256 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, //QP=[39 ~51]
257 },
258 //mv<=256
259 {
260 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, //QP=[0 ~12]
261 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, //QP=[13 ~25]
262 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, //QP=[26 ~38]
263 10, 10, 10, 10, 20, 30, 40, 50, 50, 50, 50, 50, 50, //QP=[39 ~51]
264 },
265 //mv<=512
266 {
267 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, //QP=[0 ~12]
268 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, //QP=[13 ~25]
269 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, //QP=[26 ~38]
270 20, 20, 20, 40, 60, 80, 100, 100, 100, 100, 100, 100, 100, //QP=[39 ~51]
271 },
272 //mv<=1024
273 {
274 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, //QP=[0 ~12]
275 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, //QP=[13 ~25]
276 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, //QP=[26 ~38]
277 20, 20, 30, 50, 100, 200, 200, 200, 200, 200, 200, 200, 200, //QP=[39 ~51]
278 },
279 };
280
CodechalVdencAvcStateG9Skl(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)281 CodechalVdencAvcStateG9Skl::CodechalVdencAvcStateG9Skl(
282 CodechalHwInterface * hwInterface,
283 CodechalDebugInterface *debugInterface,
284 PCODECHAL_STANDARD_INFO standardInfo) : CodechalVdencAvcStateG9(hwInterface, debugInterface, standardInfo)
285 {
286 CODECHAL_ENCODE_FUNCTION_ENTER;
287
288 this->pfnGetKernelHeaderAndSize = this->EncodeGetKernelHeaderAndSize;
289 m_vdencBrcInitDmemBufferSize = sizeof(CODECHAL_VDENC_AVC_BRC_INIT_DMEM_G9_SKL);
290 m_vdencBrcUpdateDmemBufferSize = sizeof(CODECHAL_VDENC_AVC_BRC_UPDATE_DMEM_G9_SKL);
291 }
292
~CodechalVdencAvcStateG9Skl()293 CodechalVdencAvcStateG9Skl::~CodechalVdencAvcStateG9Skl()
294 {
295 }
296
EncodeGetKernelHeaderAndSize(void * pvBinary,EncOperation Operation,uint32_t dwKrnStateIdx,void * pvKrnHeader,uint32_t * pdwKrnSize)297 MOS_STATUS CodechalVdencAvcStateG9Skl::EncodeGetKernelHeaderAndSize(void *pvBinary, EncOperation Operation, uint32_t dwKrnStateIdx, void *pvKrnHeader, uint32_t *pdwKrnSize)
298 {
299 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
300
301 CODECHAL_ENCODE_FUNCTION_ENTER;
302
303 CODECHAL_ENCODE_CHK_NULL_RETURN(pvBinary);
304 CODECHAL_ENCODE_CHK_NULL_RETURN(pvKrnHeader);
305 CODECHAL_ENCODE_CHK_NULL_RETURN(pdwKrnSize);
306
307 auto pKernelHeaderTable = (PCODECHAL_ENCODE_AVC_KERNEL_HEADER_G9_SKL)pvBinary;
308 auto pInvalidEntry = &(pKernelHeaderTable->AVC_StaticFrameDetection) + 1;
309 uint32_t dwNextKrnOffset = *pdwKrnSize;
310
311 PCODECHAL_KERNEL_HEADER pCurrKrnHeader;
312 if (Operation == ENC_SCALING4X)
313 {
314 pCurrKrnHeader = &pKernelHeaderTable->PLY_DScale_PLY;
315 }
316 else if (Operation == ENC_SCALING2X)
317 {
318 pCurrKrnHeader = &pKernelHeaderTable->PLY_2xDScale_PLY;
319 }
320 else if (Operation == ENC_ME)
321 {
322 pCurrKrnHeader = &pKernelHeaderTable->AVC_ME_P;
323 }
324 else if (Operation == VDENC_ME)
325 {
326 pCurrKrnHeader = &pKernelHeaderTable->AVC_ME_VDENC;
327 }
328 else if (Operation == ENC_SFD)
329 {
330 pCurrKrnHeader = &pKernelHeaderTable->AVC_StaticFrameDetection;
331 }
332 else
333 {
334 CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested");
335 eStatus = MOS_STATUS_INVALID_PARAMETER;
336 return eStatus;
337 }
338
339 pCurrKrnHeader += dwKrnStateIdx;
340 *((PCODECHAL_KERNEL_HEADER)pvKrnHeader) = *pCurrKrnHeader;
341
342 PCODECHAL_KERNEL_HEADER pNextKrnHeader = (pCurrKrnHeader + 1);
343 if (pNextKrnHeader < pInvalidEntry)
344 {
345 dwNextKrnOffset = pNextKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT;
346 }
347 *pdwKrnSize = dwNextKrnOffset - (pCurrKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
348
349 return eStatus;
350 }
351
GetTrellisQuantization(PCODECHAL_ENCODE_AVC_TQ_INPUT_PARAMS pParams,PCODECHAL_ENCODE_AVC_TQ_PARAMS pTrellisQuantParams)352 MOS_STATUS CodechalVdencAvcStateG9Skl::GetTrellisQuantization(PCODECHAL_ENCODE_AVC_TQ_INPUT_PARAMS pParams, PCODECHAL_ENCODE_AVC_TQ_PARAMS pTrellisQuantParams)
353 {
354 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
355
356 CODECHAL_ENCODE_FUNCTION_ENTER;
357
358 CODECHAL_ENCODE_CHK_NULL_RETURN(pParams);
359 CODECHAL_ENCODE_CHK_NULL_RETURN(pTrellisQuantParams);
360
361 pTrellisQuantParams->dwTqEnabled = TrellisQuantizationEnable[pParams->ucTargetUsage];
362 pTrellisQuantParams->dwTqRounding =
363 pTrellisQuantParams->dwTqEnabled ? TrellisQuantizationRounding[pParams->ucTargetUsage] : 0;
364
365 return eStatus;
366 }
367
SetDmemHuCBrcInitReset()368 MOS_STATUS CodechalVdencAvcStateG9Skl::SetDmemHuCBrcInitReset()
369 {
370 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
371
372 CODECHAL_ENCODE_FUNCTION_ENTER;
373
374 // Setup BRC DMEM
375 MOS_LOCK_PARAMS LockFlagsWriteOnly;
376 MOS_ZeroMemory(&LockFlagsWriteOnly, sizeof(LockFlagsWriteOnly));
377 LockFlagsWriteOnly.WriteOnly = 1;
378 auto pHucVDEncBrcInitDmem = (PCODECHAL_VDENC_AVC_BRC_INIT_DMEM_G9_SKL)m_osInterface->pfnLockResource(
379 m_osInterface, &m_resVdencBrcInitDmemBuffer[m_currRecycledBufIdx], &LockFlagsWriteOnly);
380 CODECHAL_ENCODE_CHK_NULL_RETURN(pHucVDEncBrcInitDmem);
381 SetDmemHuCBrcInitResetImpl<CODECHAL_VDENC_AVC_BRC_INIT_DMEM_G9_SKL>(pHucVDEncBrcInitDmem);
382
383 CODECHAL_DEBUG_TOOL(
384 CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateBrcInitParam(
385 pHucVDEncBrcInitDmem));
386 )
387
388 m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcInitDmemBuffer[m_currRecycledBufIdx]);
389
390 return eStatus;
391 }
392
SetDmemHuCBrcUpdate()393 MOS_STATUS CodechalVdencAvcStateG9Skl::SetDmemHuCBrcUpdate()
394 {
395 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
396
397 CODECHAL_ENCODE_FUNCTION_ENTER;
398
399 // Program update DMEM
400 MOS_LOCK_PARAMS LockFlags;
401 MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS));
402 LockFlags.WriteOnly = 1;
403 auto pHucVDEncBrcDmem = (PCODECHAL_VDENC_AVC_BRC_UPDATE_DMEM_G9_SKL)m_osInterface->pfnLockResource(
404 m_osInterface, &m_resVdencBrcUpdateDmemBuffer[m_currRecycledBufIdx][m_currPass], &LockFlags);
405
406 CODECHAL_ENCODE_CHK_NULL_RETURN(pHucVDEncBrcDmem);
407 SetDmemHuCBrcUpdateImpl<CODECHAL_VDENC_AVC_BRC_UPDATE_DMEM_G9_SKL>(pHucVDEncBrcDmem);
408
409 if (m_avcSeqParam->EnableSliceLevelRateCtrl)
410 {
411 pHucVDEncBrcDmem->UPD_SLCSZ_ConsertativeThreshold_U8 = (uint8_t)(m_avcSeqParam->RateControlMethod != RATECONTROL_VCM);
412 }
413 else
414 {
415 pHucVDEncBrcDmem->UPD_SLCSZ_ConsertativeThreshold_U8 = 0;
416 }
417
418 if (m_vdencEnabled && m_16xMeSupported && (m_pictureCodingType == P_TYPE))
419 {
420 pHucVDEncBrcDmem->HmeDistAvailable_U8 = 1;
421 }
422 else
423 {
424 pHucVDEncBrcDmem->HmeDistAvailable_U8 = 0;
425 }
426
427 pHucVDEncBrcDmem->AdditionalFrameSize_U16 = 0; // need to update from DDI
428
429 CODECHAL_DEBUG_TOOL(
430 CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateBrcUpdateParam(
431 pHucVDEncBrcDmem));
432 )
433
434 m_osInterface->pfnUnlockResource(m_osInterface, &(m_resVdencBrcUpdateDmemBuffer[m_currRecycledBufIdx][m_currPass]));
435
436 return eStatus;
437 }
438
LoadMvCost(uint8_t QP)439 MOS_STATUS CodechalVdencAvcStateG9Skl::LoadMvCost(uint8_t QP)
440 {
441 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
442
443 CODECHAL_ENCODE_FUNCTION_ENTER;
444
445 m_vdEncMvCost[0] = Map44LutValue((uint32_t)(MV_Cost_SkipBias_QPel[0]), 0x6f);
446 m_vdEncMvCost[1] = Map44LutValue((uint32_t)(MV_Cost_SkipBias_QPel[1]), 0x6f);
447 m_vdEncMvCost[2] = Map44LutValue((uint32_t)(MV_Cost_SkipBias_QPel[2]), 0x6f);
448 m_vdEncMvCost[3] = Map44LutValue((uint32_t)(MV_Cost_SkipBias_QPel[3]), 0x6f);
449 m_vdEncMvCost[4] = Map44LutValue((uint32_t)(MV_Cost_SkipBias_QPel[4]), 0x6f);
450 m_vdEncMvCost[5] = Map44LutValue((uint32_t)(MV_Cost_SkipBias_QPel[5]), 0x6f);
451 m_vdEncMvCost[6] = Map44LutValue((uint32_t)(MV_Cost_SkipBias_QPel[6]), 0x6f);
452 m_vdEncMvCost[7] = Map44LutValue((uint32_t)(MV_Cost_SkipBias_QPel[7]), 0x6f);
453
454 return eStatus;
455 }
456
LoadHmeMvCost(uint8_t QP)457 MOS_STATUS CodechalVdencAvcStateG9Skl::LoadHmeMvCost(uint8_t QP)
458 {
459 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
460
461 CODECHAL_ENCODE_FUNCTION_ENTER;
462
463 m_vdEncHmeMvCost[0] = Map44LutValue(*(HmeCost[0] + QP), 0x6f);
464 m_vdEncHmeMvCost[1] = Map44LutValue(*(HmeCost[1] + QP), 0x6f);
465 m_vdEncHmeMvCost[2] = Map44LutValue(*(HmeCost[2] + QP), 0x6f);
466 m_vdEncHmeMvCost[3] = Map44LutValue(*(HmeCost[3] + QP), 0x6f);
467 m_vdEncHmeMvCost[4] = Map44LutValue(*(HmeCost[4] + QP), 0x6f);
468 m_vdEncHmeMvCost[5] = Map44LutValue(*(HmeCost[5] + QP), 0x6f);
469 m_vdEncHmeMvCost[6] = Map44LutValue(*(HmeCost[6] + QP), 0x6f);
470 m_vdEncHmeMvCost[7] = Map44LutValue(*(HmeCost[7] + QP), 0x6f);
471
472 return eStatus;
473 }
474
LoadHmeMvCostTable(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS pSeqParams,uint8_t HMEMVCostTable[8][42])475 MOS_STATUS CodechalVdencAvcStateG9Skl::LoadHmeMvCostTable(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS pSeqParams, uint8_t HMEMVCostTable[8][42])
476 {
477 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
478
479 CODECHAL_ENCODE_FUNCTION_ENTER;
480
481 const uint32_t(*puiVdencHmeCostTable)[CODEC_AVC_NUM_QP];
482 puiVdencHmeCostTable = HmeCost;
483
484 for (int i = 0; i < 8; i++)
485 {
486 for (int j = 0; j < 42; j++)
487 {
488 HMEMVCostTable[i][j] = Map44LutValue(*(puiVdencHmeCostTable[i] + j + 10), 0x6f);
489 }
490 }
491
492 return eStatus;
493 }
494
495 #if USE_CODECHAL_DEBUG_TOOL
PopulateBrcInitParam(void * cmd)496 MOS_STATUS CodechalVdencAvcStateG9Skl::PopulateBrcInitParam(
497 void *cmd)
498 {
499 CODECHAL_DEBUG_FUNCTION_ENTER;
500
501 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
502
503 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
504 {
505 return MOS_STATUS_SUCCESS;
506 }
507
508 PCODECHAL_VDENC_AVC_BRC_INIT_DMEM_G9_SKL dmem = (PCODECHAL_VDENC_AVC_BRC_INIT_DMEM_G9_SKL)cmd;
509
510 if (m_pictureCodingType == I_TYPE)
511 {
512 m_avcPar->MBBRCEnable = m_mbBrcEnabled;
513 m_avcPar->MBRC = m_mbBrcEnabled;
514 m_avcPar->BitRate = dmem->INIT_TargetBitrate_U32;
515 m_avcPar->InitVbvFullnessInBit = dmem->INIT_InitBufFull_U32;
516 m_avcPar->MaxBitRate = dmem->INIT_MaxRate_U32;
517 m_avcPar->VbvSzInBit = dmem->INIT_BufSize_U32;
518 m_avcPar->UserMaxFrame = dmem->INIT_ProfileLevelMaxFrame_U32;
519 m_avcPar->SlidingWindowEnable = dmem->INIT_SlidingWidowRCEnable_U8;
520 m_avcPar->SlidingWindowSize = dmem->INIT_SlidingWindowSize_U8;
521 m_avcPar->SlidingWindowMaxRateRatio = dmem->INIT_SlidingWindowMaxRateRatio_U8;
522 m_avcPar->LowDelayGoldenFrameBoost = dmem->INIT_LowDelayGoldenFrameBoost_U8;
523 m_avcPar->TopQPDeltaThrforAdaptive2Pass = dmem->INIT_TopQPDeltaThrForAdapt2Pass_U8;
524 m_avcPar->BotQPDeltaThrforAdaptive2Pass = dmem->INIT_BotQPDeltaThrForAdapt2Pass_U8;
525 m_avcPar->TopFrmSzPctThrforAdaptive2Pass = dmem->INIT_TopFrmSzThrForAdapt2Pass_U8;
526 m_avcPar->BotFrmSzPctThrforAdaptive2Pass = dmem->INIT_BotFrmSzThrForAdapt2Pass_U8;
527 m_avcPar->MBHeaderCompensation = dmem->INIT_MBHeaderCompensation_U8;
528 m_avcPar->QPSelectMethodforFirstPass = dmem->INIT_QPSelectForFirstPass_U8;
529 m_avcPar->MBQpCtrl = (dmem->INIT_MbQpCtrl_U8 > 0) ? true : false;
530 m_avcPar->QPMax = dmem->INIT_MaxQP_U16;
531 m_avcPar->QPMin = dmem->INIT_MinQP_U16;
532 m_avcPar->HrdConformanceCheckDisable = (dmem->INIT_HRDConformanceCheckDisable_U8 > 0) ? true : false;
533 m_avcPar->StreamInStaticRegion = dmem->INIT_StaticRegionStreamIn_U8;
534 ;
535 m_avcPar->ScenarioInfo = dmem->INIT_ScenarioInfo_U8;
536 ;
537 }
538
539 return MOS_STATUS_SUCCESS;
540 }
541
PopulateBrcUpdateParam(void * cmd)542 MOS_STATUS CodechalVdencAvcStateG9Skl::PopulateBrcUpdateParam(
543 void *cmd)
544 {
545 CODECHAL_DEBUG_FUNCTION_ENTER;
546
547 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
548
549 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
550 {
551 return MOS_STATUS_SUCCESS;
552 }
553
554 PCODECHAL_VDENC_AVC_BRC_UPDATE_DMEM_G9_SKL dmem = (PCODECHAL_VDENC_AVC_BRC_UPDATE_DMEM_G9_SKL)cmd;
555
556 if (m_pictureCodingType == I_TYPE)
557 {
558 m_avcPar->EnableMultipass = (dmem->UPD_MaxNumPass_U8 > 0) ? true : false;
559 m_avcPar->MaxNumPakPasses = dmem->UPD_MaxNumPass_U8;
560 m_avcPar->SceneChgDetectEn = (dmem->UPD_SceneChgDetectEn_U8 > 0) ? true : false;
561 m_avcPar->SceneChgPrevIntraPctThresh = dmem->UPD_SceneChgPrevIntraPctThreshold_U8;
562 m_avcPar->SceneChgCurIntraPctThresh = dmem->UPD_SceneChgCurIntraPctThreshold_U8;
563 m_avcPar->SceneChgWidth0 = dmem->UPD_SceneChgWidth_U8[0];
564 m_avcPar->SceneChgWidth1 = dmem->UPD_SceneChgWidth_U8[1];
565 m_avcPar->SliceSizeThr = dmem->UPD_SLCSZ_TARGETSLCSZ_U16;
566 m_avcPar->SliceMaxSize = dmem->UPD_TargetSliceSize_U16;
567 }
568 else if (m_pictureCodingType == P_TYPE)
569 {
570 m_avcPar->Transform8x8PDisable = (dmem->UPD_DisablePFrame8x8Transform_U8 > 0) ? true : false;
571 }
572
573 return MOS_STATUS_SUCCESS;
574 }
575
PopulateEncParam(uint8_t meMethod,void * cmd)576 MOS_STATUS CodechalVdencAvcStateG9Skl::PopulateEncParam(
577 uint8_t meMethod,
578 void *cmd)
579 {
580 CODECHAL_DEBUG_FUNCTION_ENTER;
581
582 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
583
584 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
585 {
586 return MOS_STATUS_SUCCESS;
587 }
588
589 uint8_t *data = nullptr;
590 MOS_LOCK_PARAMS lockFlags;
591 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
592 lockFlags.ReadOnly = 1;
593
594 if (m_vdencBrcEnabled)
595 {
596 // BRC case: VDENC IMG STATE is updated by HuC FW
597 data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx], &lockFlags);
598 data = data + mhw_vdbox_mfx_g9_skl::MFX_AVC_IMG_STATE_CMD::byteSize;
599 }
600 else
601 {
602 // CQP case: VDENC IMG STATE is updated by driver or SFD kernel
603 if (!m_staticFrameDetectionInUse)
604 {
605 data = m_batchBufferForVdencImgStat[m_currRecycledBufIdx].pData;
606 data = data + mhw_vdbox_mfx_g9_skl::MFX_AVC_IMG_STATE_CMD::byteSize;
607 }
608 else
609 {
610 data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &m_resVdencSfdImageStateReadBuffer, &lockFlags);
611 }
612 }
613
614 CODECHAL_DEBUG_CHK_NULL(data);
615
616 mhw_vdbox_vdenc_g9_skl::VDENC_IMG_STATE_CMD vdencCmd;
617 vdencCmd = *(mhw_vdbox_vdenc_g9_skl::VDENC_IMG_STATE_CMD *)(data);
618
619 if (m_pictureCodingType == I_TYPE)
620 {
621 m_avcPar->BlockBasedSkip = vdencCmd.DW4.BlockBasedSkipEnabled;
622 }
623 else if (m_pictureCodingType == P_TYPE)
624 {
625 m_avcPar->SubPelMode = vdencCmd.DW4.SubPelMode;
626 m_avcPar->FTQBasedSkip = vdencCmd.DW4.ForwardTransformSkipCheckEnable;
627 m_avcPar->BiMixDisable = vdencCmd.DW1.BidirectionalMixDisable;
628 m_avcPar->SurvivedSkipCost = (vdencCmd.DW8.NonSkipZeroMvCostAdded << 1) + vdencCmd.DW8.NonSkipMbModeCostAdded;
629 m_avcPar->UniMixDisable = vdencCmd.DW2.UnidirectionalMixDisable;
630 m_avcPar->VdencExtPakObjDisable = !vdencCmd.DW1.VdencExtendedPakObjCmdEnable;
631 m_avcPar->PPMVDisable = vdencCmd.DW34.PpmvDisable;
632 }
633
634 if (data)
635 {
636 if (m_vdencBrcEnabled)
637 {
638 m_osInterface->pfnUnlockResource(
639 m_osInterface,
640 &m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx]);
641 }
642 else
643 {
644 if (m_staticFrameDetectionInUse)
645 {
646 m_osInterface->pfnUnlockResource(
647 m_osInterface,
648 &m_resVdencSfdImageStateReadBuffer);
649 }
650 }
651 }
652
653 return MOS_STATUS_SUCCESS;
654 }
655
PopulatePakParam(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER secondLevelBatchBuffer)656 MOS_STATUS CodechalVdencAvcStateG9Skl::PopulatePakParam(
657 PMOS_COMMAND_BUFFER cmdBuffer,
658 PMHW_BATCH_BUFFER secondLevelBatchBuffer)
659 {
660 CODECHAL_DEBUG_FUNCTION_ENTER;
661
662 CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
663
664 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
665 {
666 return MOS_STATUS_SUCCESS;
667 }
668
669 uint8_t *data = nullptr;
670 MOS_LOCK_PARAMS lockFlags;
671 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
672 lockFlags.ReadOnly = 1;
673
674 if (cmdBuffer != nullptr)
675 {
676 data = (uint8_t*)(cmdBuffer->pCmdPtr - (mhw_vdbox_mfx_g9_skl::MFX_AVC_IMG_STATE_CMD::byteSize / sizeof(uint32_t)));
677 }
678 else if (secondLevelBatchBuffer != nullptr)
679 {
680 data = secondLevelBatchBuffer->pData;
681 }
682 else
683 {
684 data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx], &lockFlags);
685 }
686
687 CODECHAL_DEBUG_CHK_NULL(data);
688
689 mhw_vdbox_mfx_g9_skl::MFX_AVC_IMG_STATE_CMD mfxCmd;
690 mfxCmd = *(mhw_vdbox_mfx_g9_skl::MFX_AVC_IMG_STATE_CMD *)(data);
691
692 if (m_pictureCodingType == I_TYPE)
693 {
694 m_avcPar->TrellisQuantizationEnable = mfxCmd.DW5.TrellisQuantizationEnabledTqenb;
695 m_avcPar->EnableAdaptiveTrellisQuantization = mfxCmd.DW5.TrellisQuantizationEnabledTqenb;
696 m_avcPar->TrellisQuantizationRounding = mfxCmd.DW5.TrellisQuantizationRoundingTqr;
697 m_avcPar->TrellisQuantizationChromaDisable = mfxCmd.DW5.TrellisQuantizationChromaDisableTqchromadisable;
698 m_avcPar->ExtendedRhoDomainEn = mfxCmd.DW16_17.ExtendedRhodomainStatisticsEnable;
699 }
700
701 if (data && (cmdBuffer == nullptr) && (secondLevelBatchBuffer == nullptr))
702 {
703 m_osInterface->pfnUnlockResource(
704 m_osInterface,
705 &m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx]);
706 }
707
708 return MOS_STATUS_SUCCESS;
709 }
710 #endif
711