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