1 /*
2 * Copyright (c) 2017-2020, 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_avc_g12.cpp
24 //! \brief    This file implements the C++ class/interface for Gen12 platform's AVC
25 //!           DualPipe encoding to be used across CODECHAL components.
26 //!
27 #include "codechal_encode_avc_g12.h"
28 #include "codechal_mmc_encode_avc_g12.h"
29 #include "codechal_kernel_header_g12.h"
30 #include "codechal_kernel_hme_g12.h"
31 #include "mhw_render_g12_X.h"
32 #include "codeckrnheader.h"
33 #include "igcodeckrn_g12.h"
34 #include "hal_oca_interface.h"
35 #if USE_CODECHAL_DEBUG_TOOL
36 #include "codechal_debug_encode_par_g12.h"
37 #include "mhw_vdbox_mfx_hwcmd_g12_X.h"
38 #include "mos_util_user_interface.h"
39 #endif
40 
41 enum MbencBindingTableOffset
42 {
43     mbencMfcAvcPakObj            = 0,
44     mbencIndMvData               = 1,
45     mbencBrcDistortion           = 2,  // For BRC distortion for I
46     mbencCurrY                   = 3,
47     mbencCurrUv                  = 4,
48     mbencMbSpecificData          = 5,
49     mbencAuxVmeOut               = 6,
50     mbencRefpicselectL0          = 7,
51     mbencMvDataFromMe            = 8,
52     mbenc4xMeDistortion          = 9,
53     mbencSlicemapData            = 10,
54     mbencFwdMbData               = 11,
55     mbencFwdMvData               = 12,
56     mbencMbqp                    = 13,
57     mbencMbbrcConstData          = 14,
58     mbencVmeInterPredCurrPicIdx0 = 15,
59     mbencVmeInterPredFwdPicIDX0  = 16,
60     mbencVmeInterPredBwdPicIDX00 = 17,
61     mbencVmeInterPredFwdPicIDX1  = 18,
62     mbencVmeInterPredBwdPicIDX10 = 19,
63     mbencVmeInterPredFwdPicIDX2  = 20,
64     mbencReserved0               = 21,
65     mbencVmeInterPredFwdPicIDX3  = 22,
66     mbencReserved1               = 23,
67     mbencVmeInterPredFwdPicIDX4  = 24,
68     mbencReserved2               = 25,
69     mbencVmeInterPredFwdPicIDX5  = 26,
70     mbencReserved3               = 27,
71     mbencVmeInterPredFwdPicIDX6  = 28,
72     mbencReserved4               = 29,
73     mbencVmeInterPredFwdPicIDX7  = 30,
74     mbencReserved5               = 31,
75     mbencVmeInterPredCurrPicIdx1 = 32,
76     mbencVmeInterPredBwdPicIDX01 = 33,
77     mbencReserved6               = 34,
78     mbencVmeInterPredBwdPicIDX11 = 35,
79     mbencReserved7               = 36,
80     mbencMbStats                 = 37,
81     mbencMadData                 = 38,
82     mbencBrcCurbeData            = 39,
83     mbencForceNonskipMbMap       = 40,
84     mbEncAdv                     = 41,
85     mbencSfdCostTable            = 42,
86     mbencSwScoreboard            = 43,
87     mbencNumSurfaces             = 44
88 };
89 
90 enum WpBindingTableOffset
91 {
92     wpInputRefSurface     = 0,
93     wpOutputScaledSurface = 1,
94     wpNumSurfaces         = 2
95 };
96 
97 enum MbencIdOffset
98 {
99     mbencIOffset      = 0,
100     mbencPOffset      = 1,
101     mbencBOffset      = 2,
102     mbencFrameTypeNum = 3
103 };
104 
105 // AVC MBEnc CURBE init data for TGL Kernel
106 const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalIFrame[89] =
107 {
108     0x00000082, 0x00000000, 0x00003910, 0x00a83000, 0x00000000, 0x28300000, 0x05000000, 0x00000000,
109     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
110     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
111     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
112     0x80800000, 0x00040c24, 0x00000000, 0xffff00ff, 0x40000000, 0x00000080, 0x00003900, 0x28300000,
113     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002,
114     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
115     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
116     0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
117     0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
118     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
119     0xffffffff
120 };
121 
122 const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalIField[89] =
123 {
124     0x00000082, 0x00000000, 0x00003910, 0x00a830c0, 0x02000000, 0x28300000, 0x05000000, 0x00000000,
125     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
126     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
127     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
128     0x80800000, 0x00040c24, 0x00000000, 0xffff00ff, 0x40000000, 0x00000080, 0x00003900, 0x28300000,
129     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002,
130     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
131     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
132     0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
133     0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
134     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
135     0xffffffff
136 };
137 
138 const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalPFrame[89] =
139 {
140     0x000000a3, 0x00000008, 0x00003910, 0x00ae3000, 0x30000000, 0x28300000, 0x05000000, 0x01400060,
141     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
142     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
143     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
144     0x80010000, 0x00040c24, 0x00000000, 0xffff00ff, 0x60000000, 0x000000a1, 0x00003900, 0x28300000,
145     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08000002,
146     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
147     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
148     0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
149     0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
150     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
151     0xffffffff
152 };
153 
154 const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalPField[89] =
155 {
156     0x000000a3, 0x00000008, 0x00003910, 0x00ae30c0, 0x30000000, 0x28300000, 0x05000000, 0x01400060,
157     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
158     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
159     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
160     0x80010000, 0x00040c24, 0x00000000, 0xffff00ff, 0x40000000, 0x000000a1, 0x00003900, 0x28300000,
161     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000002,
162     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
163     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
164     0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
165     0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
166     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
167     0xffffffff
168 };
169 
170 const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalBFrame[89] =
171 {
172     0x000000a3, 0x00200008, 0x00003910, 0x00aa7700, 0x50020000, 0x20200000, 0x05000000, 0xff400000,
173     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
174     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
175     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
176     0x01010000, 0x00040c24, 0x00000000, 0xffff00ff, 0x60000000, 0x000000a1, 0x00003900, 0x28300000,
177     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08000002,
178     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
179     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
180     0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
181     0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
182     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
183     0xffffffff
184 };
185 
186 const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalBField[89] =
187 {
188     0x000000a3, 0x00200008, 0x00003919, 0x00aa77c0, 0x50020000, 0x20200000, 0x05000000, 0xff400000,
189     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
190     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
191     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
192     0x01010000, 0x00040c24, 0x00000000, 0xffff00ff, 0x40000000, 0x000000a1, 0x00003900, 0x28300000,
193     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000002,
194     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
195     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
196     0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
197     0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
198     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
199     0xffffffff
200 };
201 
202 // AVC I_DIST CURBE init data for TGL Kernel
203 const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeIFrameDist[89] =
204 {
205     0x00000082, 0x00200008, 0x001e3910, 0x00a83000, 0x90000000, 0x28300000, 0x00000000, 0x00000000,
206     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000,
207     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
208     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100,
209     0x80800000, 0x00000000, 0x00000800, 0xffff00ff, 0x40000000, 0x00000080, 0x00003900, 0x28300000,
210     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
211     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
212     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
213     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
214     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
215     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
216     0xffffffff
217 };
218 
219 class CodechalEncodeAvcEncG12::WpCurbe
220 {
221    public:
WpCurbe()222     WpCurbe()
223     {
224         memset((void *)&m_wpCurbeCmd, 0, sizeof(WpCurbe));
225     }
226 
227     struct
228     {
229         // DW0
230         union
231         {
232             struct
233             {
234                 uint32_t m_defaultWeight : MOS_BITFIELD_RANGE(0, 15);
235                 uint32_t m_defaultOffset : MOS_BITFIELD_RANGE(16, 31);
236             };
237             struct
238             {
239                 uint32_t m_value;
240             };
241         } DW0;
242 
243         // DW1
244         union
245         {
246             struct
247             {
248                 uint32_t m_roi0XLeft : MOS_BITFIELD_RANGE(0, 15);
249                 uint32_t m_roi0YTop : MOS_BITFIELD_RANGE(16, 31);
250             };
251             struct
252             {
253                 uint32_t m_value;
254             };
255         } DW1;
256 
257         // DW2
258         union
259         {
260             struct
261             {
262                 uint32_t m_roi0XRight : MOS_BITFIELD_RANGE(0, 15);
263                 uint32_t m_roi0YBottom : MOS_BITFIELD_RANGE(16, 31);
264             };
265             struct
266             {
267                 uint32_t m_value;
268             };
269         } DW2;
270 
271         // DW3
272         union
273         {
274             struct
275             {
276                 uint32_t m_roi0Weight : MOS_BITFIELD_RANGE(0, 15);
277                 uint32_t m_roi0Offset : MOS_BITFIELD_RANGE(16, 31);
278             };
279             struct
280             {
281                 uint32_t m_value;
282             };
283         } DW3;
284 
285         // DW4
286         union
287         {
288             struct
289             {
290                 uint32_t m_roi1XLeft : MOS_BITFIELD_RANGE(0, 15);
291                 uint32_t m_roi1YTop : MOS_BITFIELD_RANGE(16, 31);
292             };
293             struct
294             {
295                 uint32_t m_value;
296             };
297         } DW4;
298 
299         // DW5
300         union
301         {
302             struct
303             {
304                 uint32_t m_roi1XRight : MOS_BITFIELD_RANGE(0, 15);
305                 uint32_t m_roi1YBottom : MOS_BITFIELD_RANGE(16, 31);
306             };
307             struct
308             {
309                 uint32_t m_value;
310             };
311         } DW5;
312 
313         // DW6
314         union
315         {
316             struct
317             {
318                 uint32_t m_roi1Weight : MOS_BITFIELD_RANGE(0, 15);
319                 uint32_t m_roi1Offset : MOS_BITFIELD_RANGE(16, 31);
320             };
321             struct
322             {
323                 uint32_t m_value;
324             };
325         } DW6;
326 
327         // DW7
328         union
329         {
330             struct
331             {
332                 uint32_t m_roi2XLeft : MOS_BITFIELD_RANGE(0, 15);
333                 uint32_t m_roi2YTop : MOS_BITFIELD_RANGE(16, 31);
334             };
335             struct
336             {
337                 uint32_t m_value;
338             };
339         } DW7;
340 
341         // DW8
342         union
343         {
344             struct
345             {
346                 uint32_t m_roi2XRight : MOS_BITFIELD_RANGE(0, 15);
347                 uint32_t m_roi2YBottom : MOS_BITFIELD_RANGE(16, 31);
348             };
349             struct
350             {
351                 uint32_t m_value;
352             };
353         } DW8;
354 
355         // DW9
356         union
357         {
358             struct
359             {
360                 uint32_t m_roi2Weight : MOS_BITFIELD_RANGE(0, 15);
361                 uint32_t m_roi2Offset : MOS_BITFIELD_RANGE(16, 31);
362             };
363             struct
364             {
365                 uint32_t m_value;
366             };
367         } DW9;
368 
369         // DW10
370         union
371         {
372             struct
373             {
374                 uint32_t m_roi3XLeft : MOS_BITFIELD_RANGE(0, 15);
375                 uint32_t m_roi3YTop : MOS_BITFIELD_RANGE(16, 31);
376             };
377             struct
378             {
379                 uint32_t m_value;
380             };
381         } DW10;
382 
383         // DW11
384         union
385         {
386             struct
387             {
388                 uint32_t m_roi3XRight : MOS_BITFIELD_RANGE(0, 15);
389                 uint32_t m_roi3YBottom : MOS_BITFIELD_RANGE(16, 31);
390             };
391             struct
392             {
393                 uint32_t m_value;
394             };
395         } DW11;
396 
397         // DW12
398         union
399         {
400             struct
401             {
402                 uint32_t m_roi3Weight : MOS_BITFIELD_RANGE(0, 15);
403                 uint32_t m_roi3Offset : MOS_BITFIELD_RANGE(16, 31);
404             };
405             struct
406             {
407                 uint32_t m_value;
408             };
409         } DW12;
410 
411         // DW13
412         union
413         {
414             struct
415             {
416                 uint32_t m_roi4XLeft : MOS_BITFIELD_RANGE(0, 15);
417                 uint32_t m_roi4YTop : MOS_BITFIELD_RANGE(16, 31);
418             };
419             struct
420             {
421                 uint32_t m_value;
422             };
423         } DW13;
424 
425         // DW14
426         union
427         {
428             struct
429             {
430                 uint32_t m_roi4XRight : MOS_BITFIELD_RANGE(0, 15);
431                 uint32_t m_roi4YBottom : MOS_BITFIELD_RANGE(16, 31);
432             };
433             struct
434             {
435                 uint32_t m_value;
436             };
437         } DW14;
438 
439         // DW15
440         union
441         {
442             struct
443             {
444                 uint32_t m_roi4Weight : MOS_BITFIELD_RANGE(0, 15);
445                 uint32_t m_roi4Offset : MOS_BITFIELD_RANGE(16, 31);
446             };
447             struct
448             {
449                 uint32_t m_value;
450             };
451         } DW15;
452 
453         // DW16
454         union
455         {
456             struct
457             {
458                 uint32_t m_roi5XLeft : MOS_BITFIELD_RANGE(0, 15);
459                 uint32_t m_roi5YTop : MOS_BITFIELD_RANGE(16, 31);
460             };
461             struct
462             {
463                 uint32_t m_value;
464             };
465         } DW16;
466 
467         // DW17
468         union
469         {
470             struct
471             {
472                 uint32_t m_roi5XRight : MOS_BITFIELD_RANGE(0, 15);
473                 uint32_t m_roi5YBottom : MOS_BITFIELD_RANGE(16, 31);
474             };
475             struct
476             {
477                 uint32_t m_value;
478             };
479         } DW17;
480 
481         // DW18
482         union
483         {
484             struct
485             {
486                 uint32_t m_roi5Weight : MOS_BITFIELD_RANGE(0, 15);
487                 uint32_t m_roi5Offset : MOS_BITFIELD_RANGE(16, 31);
488             };
489             struct
490             {
491                 uint32_t m_value;
492             };
493         } DW18;
494 
495         // DW19
496         union
497         {
498             struct
499             {
500                 uint32_t m_roi6XLeft : MOS_BITFIELD_RANGE(0, 15);
501                 uint32_t m_roi6YTop : MOS_BITFIELD_RANGE(16, 31);
502             };
503             struct
504             {
505                 uint32_t m_value;
506             };
507         } DW19;
508 
509         // DW20
510         union
511         {
512             struct
513             {
514                 uint32_t m_roi6XRight : MOS_BITFIELD_RANGE(0, 15);
515                 uint32_t m_roi6YBottom : MOS_BITFIELD_RANGE(16, 31);
516             };
517             struct
518             {
519                 uint32_t m_value;
520             };
521         } DW20;
522 
523         // DW21
524         union
525         {
526             struct
527             {
528                 uint32_t m_roi6Weight : MOS_BITFIELD_RANGE(0, 15);
529                 uint32_t m_roi6Offset : MOS_BITFIELD_RANGE(16, 31);
530             };
531             struct
532             {
533                 uint32_t m_value;
534             };
535         } DW21;
536 
537         // DW22
538         union
539         {
540             struct
541             {
542                 uint32_t m_roi7XLeft : MOS_BITFIELD_RANGE(0, 15);
543                 uint32_t m_roi7YTop : MOS_BITFIELD_RANGE(16, 31);
544             };
545             struct
546             {
547                 uint32_t m_value;
548             };
549         } DW22;
550 
551         // DW23
552         union
553         {
554             struct
555             {
556                 uint32_t m_roi7XRight : MOS_BITFIELD_RANGE(0, 15);
557                 uint32_t m_roi7YBottom : MOS_BITFIELD_RANGE(16, 31);
558             };
559             struct
560             {
561                 uint32_t m_value;
562             };
563         } DW23;
564 
565         // DW24
566         union
567         {
568             struct
569             {
570                 uint32_t m_roi7Weight : MOS_BITFIELD_RANGE(0, 15);
571                 uint32_t m_roi7Offset : MOS_BITFIELD_RANGE(16, 31);
572             };
573             struct
574             {
575                 uint32_t m_value;
576             };
577         } DW24;
578 
579         // DW25
580         union
581         {
582             struct
583             {
584                 uint32_t m_roi8XLeft : MOS_BITFIELD_RANGE(0, 15);
585                 uint32_t m_roi8YTop : MOS_BITFIELD_RANGE(16, 31);
586             };
587             struct
588             {
589                 uint32_t m_value;
590             };
591         } DW25;
592 
593         // DW26
594         union
595         {
596             struct
597             {
598                 uint32_t m_roi8XRight : MOS_BITFIELD_RANGE(0, 15);
599                 uint32_t m_roi8YBottom : MOS_BITFIELD_RANGE(16, 31);
600             };
601             struct
602             {
603                 uint32_t m_value;
604             };
605         } DW26;
606 
607         // DW27
608         union
609         {
610             struct
611             {
612                 uint32_t m_roi8Weight : MOS_BITFIELD_RANGE(0, 15);
613                 uint32_t m_roi8Offset : MOS_BITFIELD_RANGE(16, 31);
614             };
615             struct
616             {
617                 uint32_t m_value;
618             };
619         } DW27;
620 
621         // DW28
622         union
623         {
624             struct
625             {
626                 uint32_t m_roi9XLeft : MOS_BITFIELD_RANGE(0, 15);
627                 uint32_t m_roi9YTop : MOS_BITFIELD_RANGE(16, 31);
628             };
629             struct
630             {
631                 uint32_t m_value;
632             };
633         } DW28;
634 
635         // DW29
636         union
637         {
638             struct
639             {
640                 uint32_t m_roi9XRight : MOS_BITFIELD_RANGE(0, 15);
641                 uint32_t m_roi9YBottom : MOS_BITFIELD_RANGE(16, 31);
642             };
643             struct
644             {
645                 uint32_t m_value;
646             };
647         } DW29;
648 
649         // DW30
650         union
651         {
652             struct
653             {
654                 uint32_t m_roi9Weight : MOS_BITFIELD_RANGE(0, 15);
655                 uint32_t m_roi9Offset : MOS_BITFIELD_RANGE(16, 31);
656             };
657             struct
658             {
659                 uint32_t m_value;
660             };
661         } DW30;
662 
663         // DW31
664         union
665         {
666             struct
667             {
668                 uint32_t m_roi10XLeft : MOS_BITFIELD_RANGE(0, 15);
669                 uint32_t m_roi10YTop : MOS_BITFIELD_RANGE(16, 31);
670             };
671             struct
672             {
673                 uint32_t m_value;
674             };
675         } DW31;
676 
677         // DW32
678         union
679         {
680             struct
681             {
682                 uint32_t m_roi10XRight : MOS_BITFIELD_RANGE(0, 15);
683                 uint32_t m_roi10YBottom : MOS_BITFIELD_RANGE(16, 31);
684             };
685             struct
686             {
687                 uint32_t m_value;
688             };
689         } DW32;
690 
691         // DW33
692         union
693         {
694             struct
695             {
696                 uint32_t m_roi10Weight : MOS_BITFIELD_RANGE(0, 15);
697                 uint32_t m_roi10Offset : MOS_BITFIELD_RANGE(16, 31);
698             };
699             struct
700             {
701                 uint32_t m_value;
702             };
703         } DW33;
704 
705         // DW34
706         union
707         {
708             struct
709             {
710                 uint32_t m_roi11XLeft : MOS_BITFIELD_RANGE(0, 15);
711                 uint32_t m_roi11YTop : MOS_BITFIELD_RANGE(16, 31);
712             };
713             struct
714             {
715                 uint32_t m_value;
716             };
717         } DW34;
718 
719         // DW35
720         union
721         {
722             struct
723             {
724                 uint32_t m_roi11XRight : MOS_BITFIELD_RANGE(0, 15);
725                 uint32_t m_roi11YBottom : MOS_BITFIELD_RANGE(16, 31);
726             };
727             struct
728             {
729                 uint32_t m_value;
730             };
731         } DW35;
732 
733         // DW36
734         union
735         {
736             struct
737             {
738                 uint32_t m_roi11Weight : MOS_BITFIELD_RANGE(0, 15);
739                 uint32_t m_roi11Offset : MOS_BITFIELD_RANGE(16, 31);
740             };
741             struct
742             {
743                 uint32_t m_value;
744             };
745         } DW36;
746 
747         // DW37
748         union
749         {
750             struct
751             {
752                 uint32_t m_roi12XLeft : MOS_BITFIELD_RANGE(0, 15);
753                 uint32_t m_roi12YTop : MOS_BITFIELD_RANGE(16, 31);
754             };
755             struct
756             {
757                 uint32_t m_value;
758             };
759         } DW37;
760 
761         // DW38
762         union
763         {
764             struct
765             {
766                 uint32_t m_roi12XRight : MOS_BITFIELD_RANGE(0, 15);
767                 uint32_t m_roi12YBottom : MOS_BITFIELD_RANGE(16, 31);
768             };
769             struct
770             {
771                 uint32_t m_value;
772             };
773         } DW38;
774 
775         // DW39
776         union
777         {
778             struct
779             {
780                 uint32_t m_roi12Weight : MOS_BITFIELD_RANGE(0, 15);
781                 uint32_t m_roi12Offset : MOS_BITFIELD_RANGE(16, 31);
782             };
783             struct
784             {
785                 uint32_t m_value;
786             };
787         } DW39;
788 
789         // DW40
790         union
791         {
792             struct
793             {
794                 uint32_t m_roi13XLeft : MOS_BITFIELD_RANGE(0, 15);
795                 uint32_t m_roi13YTop : MOS_BITFIELD_RANGE(16, 31);
796             };
797             struct
798             {
799                 uint32_t m_value;
800             };
801         } DW40;
802 
803         // DW41
804         union
805         {
806             struct
807             {
808                 uint32_t m_roi13XRight : MOS_BITFIELD_RANGE(0, 15);
809                 uint32_t m_roi13YBottom : MOS_BITFIELD_RANGE(16, 31);
810             };
811             struct
812             {
813                 uint32_t m_value;
814             };
815         } DW41;
816 
817         // DW42
818         union
819         {
820             struct
821             {
822                 uint32_t m_roi13Weight : MOS_BITFIELD_RANGE(0, 15);
823                 uint32_t m_roi13Offset : MOS_BITFIELD_RANGE(16, 31);
824             };
825             struct
826             {
827                 uint32_t m_value;
828             };
829         } DW42;
830 
831         // DW43
832         union
833         {
834             struct
835             {
836                 uint32_t m_roi14XLeft : MOS_BITFIELD_RANGE(0, 15);
837                 uint32_t m_roi14YTop : MOS_BITFIELD_RANGE(16, 31);
838             };
839             struct
840             {
841                 uint32_t m_value;
842             };
843         } DW43;
844 
845         // DW44
846         union
847         {
848             struct
849             {
850                 uint32_t m_roi14XRight : MOS_BITFIELD_RANGE(0, 15);
851                 uint32_t m_roi14YBottom : MOS_BITFIELD_RANGE(16, 31);
852             };
853             struct
854             {
855                 uint32_t m_value;
856             };
857         } DW44;
858 
859         // DW45
860         union
861         {
862             struct
863             {
864                 uint32_t m_roi14Weight : MOS_BITFIELD_RANGE(0, 15);
865                 uint32_t m_roi14Offset : MOS_BITFIELD_RANGE(16, 31);
866             };
867             struct
868             {
869                 uint32_t m_value;
870             };
871         } DW45;
872 
873         // DW46
874         union
875         {
876             struct
877             {
878                 uint32_t m_roi15XLeft : MOS_BITFIELD_RANGE(0, 15);
879                 uint32_t m_roi15YTop : MOS_BITFIELD_RANGE(16, 31);
880             };
881             struct
882             {
883                 uint32_t m_value;
884             };
885         } DW46;
886 
887         // DW47
888         union
889         {
890             struct
891             {
892                 uint32_t m_roi15XRight : MOS_BITFIELD_RANGE(0, 15);
893                 uint32_t m_roi15YBottom : MOS_BITFIELD_RANGE(16, 31);
894             };
895             struct
896             {
897                 uint32_t m_value;
898             };
899         } DW47;
900 
901         // DW48
902         union
903         {
904             struct
905             {
906                 uint32_t m_roi15Weight : MOS_BITFIELD_RANGE(0, 15);
907                 uint32_t m_roi15Offset : MOS_BITFIELD_RANGE(16, 31);
908             };
909             struct
910             {
911                 uint32_t m_value;
912             };
913         } DW48;
914 
915         // DW49
916         union
917         {
918             struct
919             {
920                 uint32_t m_inputSurface;
921             };
922             struct
923             {
924                 uint32_t m_value;
925             };
926         } DW49;
927 
928         // DW50
929         union
930         {
931             struct
932             {
933                 uint32_t m_outputSurface;
934             };
935             struct
936             {
937                 uint32_t m_value;
938             };
939         } DW50;
940     } m_wpCurbeCmd;
941 };
942 
943 static const uint32_t trellisQuantizationRounding[NUM_TARGET_USAGE_MODES] =
944 {
945     0, 3, 0, 0, 0, 0, 0, 0
946 };
947 
948 const uint8_t CodechalEncodeAvcEncG12::m_QPAdjustmentDistThresholdMaxFrameThresholdIPB[576] =
949 {
950     0x01, 0x02, 0x03, 0x05, 0x06, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00, 0x01, 0x02, 0x03, 0xff,
951     0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x01, 0xfe, 0xfe, 0xff, 0x00, 0x01, 0xfd, 0xfd,
952     0xff, 0xff, 0x00, 0xfb, 0xfd, 0xfe, 0xff, 0xff, 0xfa, 0xfb, 0xfd, 0xfe, 0xff, 0x00, 0x04, 0x1e,
953     0x3c, 0x50, 0x78, 0x8c, 0xc8, 0xff, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
954     0x01, 0x02, 0x03, 0x05, 0x06, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x01, 0x01, 0x02, 0x03, 0xff,
955     0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfe, 0xff,
956     0xff, 0xff, 0x00, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0xfb, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x04, 0x1e,
957     0x3c, 0x50, 0x78, 0x8c, 0xc8, 0xff, 0x04, 0x05, 0x06, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
958     0x01, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00, 0x01, 0x01, 0x02, 0xff,
959     0x00, 0x00, 0x01, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfe, 0xff,
960     0xff, 0xff, 0x00, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0xfb, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x02, 0x14,
961     0x28, 0x46, 0x82, 0xa0, 0xc8, 0xff, 0x04, 0x04, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
962     0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03,
963     0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00,
964     0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff,
965     0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe,
966     0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
967     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
968     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
969     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
970     0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03,
971     0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00,
972     0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff,
973     0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe,
974     0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
975     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
976     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
977     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
978     0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03,
979     0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00,
980     0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff,
981     0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe,
982     0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
983     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
984     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
985     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
986 };
987 
988 const CODECHAL_ENCODE_AVC_IPCM_THRESHOLD CodechalEncodeAvcEncG12::m_IPCMThresholdTable[5] =
989 {
990     { 2, 3000 },
991     { 4, 3600 },
992     { 6, 5000 },
993     { 10, 7500 },
994     { 18, 9000 },
995 };
996 
997 const uint32_t CodechalEncodeAvcEncG12::m_intraModeCostForHighTextureMB[CODEC_AVC_NUM_QP]
998 {
999     0x00000303, 0x00000304, 0x00000404, 0x00000405, 0x00000505, 0x00000506, 0x00000607, 0x00000708,
1000     0x00000809, 0x0000090a, 0x00000a0b, 0x00000b0c, 0x00000c0e, 0x00000e18, 0x00001819, 0x00001918,
1001     0x00001a19, 0x00001b19, 0x00001d19, 0x00001e18, 0x00002818, 0x00002918, 0x00002a18, 0x00002b19,
1002     0x00002d18, 0x00002e18, 0x00003818, 0x00003918, 0x00003a18, 0x00003b0f, 0x00003d0e, 0x00003e0e,
1003     0x0000480e, 0x0000490e, 0x00004a0e, 0x00004b0d, 0x00004d0d, 0x00004e0d, 0x0000580e, 0x0000590e,
1004     0x00005a0e, 0x00005b0d, 0x00005d0c, 0x00005e0b, 0x0000680a, 0x00006908, 0x00006a09, 0x00006b0a,
1005     0x00006d0b, 0x00006e0d, 0x0000780e, 0x00007918
1006 };
1007 
1008 const uint16_t CodechalEncodeAvcEncG12::m_lambdaData[256] = {
1009     9,     7,     9,     6,    12,     8,    12,     8,    15,    10,    15,     9,    19,    13,    19,    12,    24,
1010     17,    24,    15,    30,    21,    30,    19,    38,    27,    38,    24,    48,    34,    48,    31,    60,    43,
1011     60,    39,    76,    54,    76,    49,    96,    68,    96,    62,   121,    85,   121,    78,   153,   108,   153,
1012     99,   193,   135,   193,   125,   243,   171,   243,   157,   306,   215,   307,   199,   385,   271,   387,   251,
1013     485,   342,   488,   317,   612,   431,   616,   400,   771,   543,   777,   505,   971,   684,   981,   638,  1224,
1014     862,  1237,   806,  1542,  1086,  1562,  1018,  1991,  1402,  1971,  1287,  2534,  1785,  2488,  1626,  3077,  2167,
1015     3141,  2054,  3982,  2805,  3966,  2596,  4887,  3442,  5007,  3281,  6154,  4335,  6322,  4148,  7783,  5482,  7984,
1016     5243,  9774,  6885, 10082,  6629, 12489,  8797, 12733,  8382, 15566, 10965, 16082, 10599, 19729, 13897, 20313, 13404,
1017     24797, 17467, 25660, 16954, 31313, 22057, 32415, 21445, 39458, 27795, 40953, 27129, 49594, 34935, 51742, 34323, 61440,
1018     43987, 61440, 43428, 61440, 55462, 61440, 54954, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440,
1019     61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440,
1020     61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440,
1021     61440, 61440, 61440, 61440,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
1022     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
1023     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
1024     0,
1025 };
1026 
1027 const uint8_t CodechalEncodeAvcEncG12::m_ftQ25[64] = //27 value 4 dummy
1028 {
1029     0,                                      //qp=0
1030     0, 0, 0, 0, 0, 0,                       //qp=1,2;3,4;5,6;
1031     1, 1, 3, 3, 6, 6, 8, 8, 11, 11,         //qp=7,8;9,10;11,12;13,14;15;16
1032     13, 13, 16, 16, 19, 19, 22, 22, 26, 26, //qp=17,18;19,20;21,22;23,24;25,26
1033     30, 30, 34, 34, 39, 39, 44, 44, 50, 50, //qp=27,28;29,30;31,32;33,34;35,36
1034     56, 56, 62, 62, 69, 69, 77, 77, 85, 85, //qp=37,38;39,40;41,42;43,44;45,46
1035     94, 94, 104, 104, 115, 115,             //qp=47,48;49,50;51
1036     0, 0, 0, 0, 0, 0, 0, 0                  //dummy
1037 };
1038 
1039 // AVC MBEnc RefCost tables, index [CodingType][QP]
1040 // QP is from 0 - 51, pad it to 64 since BRC needs each subarray size to be 128bytes
1041 const uint16_t CodechalEncodeAvcEncG12::m_refCostMultiRefQp[NUM_PIC_TYPES][64] =
1042 {
1043     // I-frame
1044     {
1045         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1046         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1047         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1048         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1049         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1050         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1051         0x0000, 0x0000, 0x0000, 0x0000
1052     },
1053     // P-slice
1054     {
1055         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1056         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1057         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1058         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1059         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1060         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1061         0x0000, 0x0000, 0x0000, 0x0000
1062     },
1063     //B-slice
1064     {
1065         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1066         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1067         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1068         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1069         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1070         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1071         0x0000, 0x0000, 0x0000, 0x0000
1072     }
1073 };
1074 
1075 const uint32_t CodechalEncodeAvcEncG12::m_multiPred[NUM_TARGET_USAGE_MODES] =
1076 {
1077     0, 3, 3, 0, 0, 0, 0, 0
1078 };
1079 
1080 const uint32_t CodechalEncodeAvcEncG12::m_multiRefDisableQPCheck[NUM_TARGET_USAGE_MODES] =
1081 {
1082     0, 1, 0, 0, 0, 0, 0, 0
1083 };
1084 // clang-format on
1085 
1086 const int32_t CodechalEncodeAvcEncG12::m_brcBTCounts[CODECHAL_ENCODE_BRC_IDX_NUM] = {
1087     CODECHAL_ENCODE_AVC_BRC_INIT_RESET_NUM_SURFACES,
1088     frameBrcUpdateNumSurfaces,
1089     CODECHAL_ENCODE_AVC_BRC_INIT_RESET_NUM_SURFACES,
1090     mbencNumSurfaces,
1091     CODECHAL_ENCODE_AVC_BRC_BLOCK_COPY_NUM_SURFACES,
1092     mbBrcUpdateNumSurfaces
1093 };
1094 
1095 const int32_t CodechalEncodeAvcEncG12::m_brcCurbeSize[CODECHAL_ENCODE_BRC_IDX_NUM] = {
1096     (sizeof(BrcInitResetCurbe)),
1097     (sizeof(FrameBrcUpdateCurbe)),
1098     (sizeof(BrcInitResetCurbe)),
1099     (sizeof(MbencCurbe)),
1100     0,
1101     (sizeof(MbBrcUpdateCurbe))
1102 };
1103 
1104 class CodechalEncodeAvcEncG12::EncKernelHeader
1105 {
1106 public:
1107     int m_kernelCount;
1108     // Quality mode for Frame/Field
1109     CODECHAL_KERNEL_HEADER m_mbEncQltyI;
1110     CODECHAL_KERNEL_HEADER m_mbEncQltyP;
1111     CODECHAL_KERNEL_HEADER m_mEncQltyB;
1112     // Normal mode for Frame/Field
1113     CODECHAL_KERNEL_HEADER m_mbEncNormI;
1114     CODECHAL_KERNEL_HEADER m_mbEncNormP;
1115     CODECHAL_KERNEL_HEADER m_mbEncNormB;
1116     // Performance modes for Frame/Field
1117     CODECHAL_KERNEL_HEADER m_mbEncPerfI;
1118     CODECHAL_KERNEL_HEADER m_mbEncPerfP;
1119     CODECHAL_KERNEL_HEADER m_mbEncPerfB;
1120     // Modes for Frame/Field
1121     CODECHAL_KERNEL_HEADER m_mbEncAdvI;
1122     CODECHAL_KERNEL_HEADER m_mbEncAdvP;
1123     CODECHAL_KERNEL_HEADER m_mbEncAdvB;
1124     // BRC Init frame
1125     CODECHAL_KERNEL_HEADER m_initFrameBrc;
1126     // FrameBRC Update
1127     CODECHAL_KERNEL_HEADER m_frameEncUpdate;
1128     // BRC Reset frame
1129     CODECHAL_KERNEL_HEADER m_brcResetFrame;
1130     // BRC I Frame Distortion
1131     CODECHAL_KERNEL_HEADER m_brcIFrameDist;
1132     // BRCBlockCopy
1133     CODECHAL_KERNEL_HEADER m_brcBlockCopy;
1134     // MbBRC Update
1135     CODECHAL_KERNEL_HEADER m_mbBrcUpdate;
1136     //Weighted Prediction Kernel
1137     CODECHAL_KERNEL_HEADER m_weightedPrediction;
1138     // SW scoreboard initialization kernel
1139     CODECHAL_KERNEL_HEADER m_initSwScoreboard;
1140 };
1141 
GetKernelHeaderAndSize(void * binary,EncOperation operation,uint32_t krnStateIdx,void * krnHeader,uint32_t * krnSize)1142 MOS_STATUS CodechalEncodeAvcEncG12::GetKernelHeaderAndSize(
1143     void                         *binary,
1144     EncOperation                 operation,
1145     uint32_t                     krnStateIdx,
1146     void                         *krnHeader,
1147     uint32_t                     *krnSize)
1148 {
1149     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1150 
1151     CODECHAL_ENCODE_FUNCTION_ENTER;
1152     CODECHAL_ENCODE_CHK_NULL_RETURN(binary);
1153     CODECHAL_ENCODE_CHK_NULL_RETURN(krnHeader);
1154     CODECHAL_ENCODE_CHK_NULL_RETURN(krnSize);
1155 
1156     auto kernelHeaderTable = (EncKernelHeader *)binary;
1157     auto invalidEntry = &(kernelHeaderTable->m_weightedPrediction) + 1;
1158     auto nextKrnOffset = *krnSize;
1159 
1160     PCODECHAL_KERNEL_HEADER currKrnHeader = nullptr;
1161 
1162     if (operation == ENC_BRC)
1163     {
1164         currKrnHeader = &kernelHeaderTable->m_initFrameBrc;
1165     }
1166     else if (operation == ENC_MBENC)
1167     {
1168         currKrnHeader = &kernelHeaderTable->m_mbEncQltyI;
1169     }
1170     else if (operation == ENC_MBENC_ADV)
1171     {
1172         currKrnHeader = &kernelHeaderTable->m_mbEncAdvI;
1173     }
1174     else if (operation == ENC_WP)
1175     {
1176         currKrnHeader = &kernelHeaderTable->m_weightedPrediction;
1177     }
1178     else
1179     {
1180         CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested");
1181         return MOS_STATUS_INVALID_PARAMETER;
1182     }
1183 
1184     currKrnHeader += krnStateIdx;
1185     *((PCODECHAL_KERNEL_HEADER)krnHeader) = *currKrnHeader;
1186 
1187     auto nextKrnHeader = (currKrnHeader + 1);
1188     if (nextKrnHeader < invalidEntry)
1189     {
1190         nextKrnOffset = nextKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT;
1191     }
1192     *krnSize = nextKrnOffset - (currKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
1193 
1194     return eStatus;
1195 }
1196 
CodechalEncodeAvcEncG12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1197 CodechalEncodeAvcEncG12::CodechalEncodeAvcEncG12(
1198         CodechalHwInterface *   hwInterface,
1199         CodechalDebugInterface *debugInterface,
1200         PCODECHAL_STANDARD_INFO standardInfo) : CodechalEncodeAvcEnc(hwInterface, debugInterface, standardInfo),
1201         m_sinlgePipeVeState(nullptr)
1202 {
1203     CODECHAL_ENCODE_FUNCTION_ENTER;
1204 
1205     CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
1206 
1207     m_osInterface->pfnVirtualEngineSupported(m_osInterface, false, true);
1208 
1209     // Virtual Engine is enabled in default.
1210     Mos_SetVirtualEngineSupported(m_osInterface, true);
1211 
1212     bKernelTrellis             = true;
1213     bExtendedMvCostRange       = true;
1214     bBrcSplitEnable            = true;
1215     bDecoupleMbEncCurbeFromBRC = true;
1216     bHighTextureModeCostEnable = true;
1217     bMvDataNeededByBRC         = false;
1218 
1219     this->pfnGetKernelHeaderAndSize = CodechalEncodeAvcEncG12::GetKernelHeaderAndSize;
1220 
1221     m_cmKernelEnable         = true;
1222     m_mbStatsSupported       = true;
1223     m_useCommonKernel        = true;
1224 
1225     m_kernelBase = (uint8_t *)IGCODECKRN_G12;
1226     m_kuidCommon = IDR_CODEC_HME_DS_SCOREBOARD_KERNEL;
1227     AddIshSize(m_kuid, m_kernelBase);
1228     AddIshSize(m_kuidCommon, m_kernelBase);
1229 
1230     m_vdboxOneDefaultUsed = true;
1231 
1232     m_osInterface->pfnVirtualEngineSupported(m_osInterface, false, false);
1233 
1234     CODECHAL_DEBUG_TOOL(
1235         CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(m_encodeParState = MOS_New(CodechalDebugEncodeParG12, this));
1236         CreateAvcPar();
1237     )
1238 }
1239 
~CodechalEncodeAvcEncG12()1240 CodechalEncodeAvcEncG12::~CodechalEncodeAvcEncG12()
1241 {
1242     CODECHAL_ENCODE_FUNCTION_ENTER;
1243 
1244     MOS_Delete(m_intraDistKernel);
1245 
1246     if (m_swScoreboardState)
1247     {
1248         MOS_Delete(m_swScoreboardState);
1249         m_swScoreboardState = nullptr;
1250     }
1251 
1252     if (m_sinlgePipeVeState)
1253     {
1254         MOS_FreeMemAndSetNull(m_sinlgePipeVeState);
1255     }
1256 
1257     CODECHAL_DEBUG_TOOL(
1258         DestroyAvcPar();
1259         MOS_Delete(m_encodeParState);
1260     )
1261 }
1262 
MbEncKernel(bool mbEncIFrameDistInUse)1263 MOS_STATUS CodechalEncodeAvcEncG12::MbEncKernel(bool mbEncIFrameDistInUse)
1264 {
1265     MOS_STATUS                                  eStatus = MOS_STATUS_SUCCESS;
1266 
1267     CODECHAL_ENCODE_FUNCTION_ENTER;
1268 
1269     uint8_t ppsIdx          = m_avcSliceParams->pic_parameter_set_id;
1270     uint8_t spsIdx          = m_avcPicParams[ppsIdx]->seq_parameter_set_id;
1271     auto refList            = &m_refList[0];
1272     auto currRefList        = m_refList[m_currReconstructedPic.FrameIdx];
1273     bool use45DegreePattern = false;
1274     bool roiEnabled         = (m_avcPicParams[ppsIdx]->NumROI > 0) ? true : false;
1275     uint8_t refPicListIdx   = m_avcSliceParams[ppsIdx].RefPicList[0][0].FrameIdx;
1276     uint8_t refFrameListIdx = m_avcPicParam[ppsIdx].RefFrameList[refPicListIdx].FrameIdx;
1277     bool dirtyRoiEnabled    = (m_pictureCodingType == P_TYPE
1278         && m_avcPicParams[ppsIdx]->NumDirtyROI > 0
1279         && m_prevReconFrameIdx == refFrameListIdx);
1280 
1281     //  Two flags(bMbConstDataBufferNeeded, bMbQpBufferNeeded)
1282     //  would be used as there are two buffers and not all cases need both the buffers
1283     //  Constant Data buffer  needed for MBBRC, MBQP, ROI, RollingIntraRefresh
1284     //  Please note that this surface needs to be programmed for
1285     //  all usage cases(including CQP cases) because DWord13 includes mode cost for high texture MB?s cost.
1286     bool mbConstDataBufferInUse = bMbBrcEnabled || bMbQpDataEnabled || roiEnabled || dirtyRoiEnabled ||
1287         m_avcPicParam->EnableRollingIntraRefresh || bHighTextureModeCostEnable;
1288 
1289     bool mbQpBufferInUse = bMbBrcEnabled || bBrcRoiEnabled || bMbQpDataEnabled;
1290 
1291     if (m_feiEnable)
1292     {
1293         CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcFeiPicParams);
1294         mbConstDataBufferInUse |= m_avcFeiPicParams->bMBQp;
1295         mbQpBufferInUse |= m_avcFeiPicParams->bMBQp;
1296     }
1297 
1298     PerfTagSetting perfTag;
1299     perfTag.Value             = 0;
1300     perfTag.Mode              = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
1301     perfTag.CallType          = (mbEncIFrameDistInUse && !m_singleTaskPhaseSupported) ?
1302         CODECHAL_ENCODE_PERFTAG_CALL_INTRA_DIST : CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL;
1303     perfTag.PictureCodingType = m_pictureCodingType;
1304     m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
1305 
1306     CODECHAL_MEDIA_STATE_TYPE encFunctionType;
1307     if (mbEncIFrameDistInUse)
1308     {
1309         encFunctionType = CODECHAL_MEDIA_STATE_ENC_I_FRAME_DIST;
1310     }
1311     else if (bUseMbEncAdvKernel)
1312     {
1313         encFunctionType = CODECHAL_MEDIA_STATE_ENC_ADV;
1314     }
1315     else if (m_kernelMode == encodeNormalMode)
1316     {
1317         encFunctionType = CODECHAL_MEDIA_STATE_ENC_NORMAL;
1318     }
1319     else if (m_kernelMode == encodePerformanceMode)
1320     {
1321         encFunctionType = CODECHAL_MEDIA_STATE_ENC_PERFORMANCE;
1322     }
1323     else
1324     {
1325         encFunctionType = CODECHAL_MEDIA_STATE_ENC_QUALITY;
1326     }
1327 
1328     // Initialize DSH kernel region
1329     PMHW_KERNEL_STATE kernelState;
1330     if (mbEncIFrameDistInUse)
1331     {
1332         kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_IFRAMEDIST];
1333     }
1334     else
1335     {
1336         CodechalEncodeIdOffsetParams idOffsetParams;
1337         MOS_ZeroMemory(&idOffsetParams, sizeof(idOffsetParams));
1338         idOffsetParams.Standard           = m_standard;
1339         idOffsetParams.EncFunctionType    = encFunctionType;
1340         idOffsetParams.wPictureCodingType = m_pictureCodingType;
1341         idOffsetParams.ucDmvPredFlag      = m_avcSliceParams->direct_spatial_mv_pred_flag;
1342         idOffsetParams.interlacedField   = CodecHal_PictureIsField(m_currOriginalPic);
1343 
1344         uint32_t krnStateIdx;
1345         CODECHAL_ENCODE_CHK_STATUS_RETURN(GetMbEncKernelStateIdx(
1346             &idOffsetParams,
1347             &krnStateIdx));
1348         kernelState = &pMbEncKernelStates[krnStateIdx];
1349     }
1350 
1351     // If Single Task Phase is not enabled, use BT count for the kernel state.
1352     if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
1353     {
1354         uint32_t maxBtCount = m_singleTaskPhaseSupported ?
1355             m_maxBtCount : kernelState->KernelParams.iBTCount;
1356         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
1357             m_stateHeapInterface,
1358             maxBtCount));
1359         m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
1360         CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
1361     }
1362 
1363     // Allocate DSH and SSH for the first stream, which will be passed to other streams through the shared kernel state.
1364     if (!bMbEncCurbeSetInBrcUpdate)
1365     {
1366         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
1367             m_stateHeapInterface,
1368             kernelState,
1369             false,
1370             0,
1371             false,
1372             m_storeData));
1373 
1374         MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
1375         MOS_ZeroMemory(&idParams, sizeof(idParams));
1376         idParams.pKernelState = kernelState;
1377         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
1378             m_stateHeapInterface,
1379             1,
1380             &idParams));
1381     }
1382 
1383     if (bMbEncCurbeSetInBrcUpdate)
1384     {
1385         // If BRC update was used to set up the DSH & SSH, SSH only needs to
1386         // be obtained if single task phase is enabled because the same SSH
1387         // could not be shared between BRC update and MbEnc
1388         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
1389             m_stateHeapInterface,
1390             kernelState,
1391             true,
1392             0,
1393             m_singleTaskPhaseSupported,
1394             m_storeData));
1395     }
1396     else
1397     {
1398         // Setup AVC Curbe
1399         CODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS mbEncCurbeParams;
1400         MOS_ZeroMemory(&mbEncCurbeParams, sizeof(mbEncCurbeParams));
1401         mbEncCurbeParams.pPicParams              = m_avcPicParams[ppsIdx];
1402         mbEncCurbeParams.pSeqParams              = m_avcSeqParams[spsIdx];
1403         mbEncCurbeParams.pSlcParams              = m_avcSliceParams;
1404         mbEncCurbeParams.ppRefList               = &(m_refList[0]);
1405         mbEncCurbeParams.pPicIdx                 = &(m_picIdx[0]);
1406         mbEncCurbeParams.bRoiEnabled             = roiEnabled;
1407         mbEncCurbeParams.bDirtyRoiEnabled        = dirtyRoiEnabled;
1408         mbEncCurbeParams.bMbEncIFrameDistEnabled = mbEncIFrameDistInUse;
1409         mbEncCurbeParams.pdwBlockBasedSkipEn     = &dwMbEncBlockBasedSkipEn;
1410         if (mbEncIFrameDistInUse)
1411         {
1412             mbEncCurbeParams.bBrcEnabled           = false;
1413             mbEncCurbeParams.wPicWidthInMb         = (uint16_t)m_downscaledWidthInMb4x;
1414             mbEncCurbeParams.wFieldFrameHeightInMb = (uint16_t)m_downscaledFrameFieldHeightInMb4x;
1415             mbEncCurbeParams.usSliceHeight         = (m_sliceHeight + SCALE_FACTOR_4x - 1) / SCALE_FACTOR_4x;
1416         }
1417         else
1418         {
1419             mbEncCurbeParams.bBrcEnabled           = bBrcEnabled;
1420             mbEncCurbeParams.wPicWidthInMb         = m_picWidthInMb;
1421             mbEncCurbeParams.wFieldFrameHeightInMb = m_frameFieldHeightInMb;
1422             mbEncCurbeParams.usSliceHeight         = (m_arbitraryNumMbsInSlice) ?
1423                 m_frameFieldHeightInMb : m_sliceHeight;
1424             mbEncCurbeParams.bUseMbEncAdvKernel    = bUseMbEncAdvKernel;
1425         }
1426         mbEncCurbeParams.pKernelState                     = kernelState;
1427         mbEncCurbeParams.pAvcQCParams                     = m_avcQCParams;
1428         mbEncCurbeParams.bMbDisableSkipMapEnabled         = bMbDisableSkipMapEnabled;
1429         mbEncCurbeParams.bStaticFrameDetectionEnabled     = bStaticFrameDetectionEnable && m_hmeEnabled;
1430         mbEncCurbeParams.bApdatvieSearchWindowSizeEnabled = bApdatvieSearchWindowEnable;
1431         mbEncCurbeParams.bSquareRollingIEnabled           = bSquareRollingIEnabled;
1432         CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMbEnc(
1433             &mbEncCurbeParams));
1434     }
1435 
1436     CODECHAL_DEBUG_TOOL(
1437         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1438             encFunctionType,
1439             MHW_DSH_TYPE,
1440             kernelState));
1441 
1442     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
1443         encFunctionType,
1444         kernelState));
1445     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1446         encFunctionType,
1447         MHW_ISH_TYPE,
1448         kernelState));
1449     )
1450 
1451         for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
1452         {
1453             if (m_picIdx[i].bValid)
1454             {
1455                 uint8_t index = m_picIdx[i].ucPicIdx;
1456                 refList[index]->sRefBuffer = m_userFlags.bUseRawPicForRef ?
1457                     refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer;
1458 
1459                 CodecHalGetResourceInfo(m_osInterface, &refList[index]->sRefBuffer);
1460             }
1461         }
1462 
1463     MOS_COMMAND_BUFFER cmdBuffer;
1464     MOS_ZeroMemory(&cmdBuffer, sizeof(cmdBuffer));
1465     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1466 
1467     SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
1468     sendKernelCmdsParams.EncFunctionType = encFunctionType;
1469     sendKernelCmdsParams.ucDmvPredFlag   =
1470         m_avcSliceParams->direct_spatial_mv_pred_flag;
1471     sendKernelCmdsParams.pKernelState    = kernelState;
1472     CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
1473 
1474     // Set up MB BRC Constant Data Buffer if there is QP change within a frame
1475     if (mbConstDataBufferInUse)
1476     {
1477         CODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS initMbBrcConstantDataBufferParams;
1478 
1479         MOS_ZeroMemory(&initMbBrcConstantDataBufferParams, sizeof(initMbBrcConstantDataBufferParams));
1480         initMbBrcConstantDataBufferParams.pOsInterface                = m_osInterface;
1481         initMbBrcConstantDataBufferParams.presBrcConstantDataBuffer   =
1482             &BrcBuffers.resMbBrcConstDataBuffer[m_currRecycledBufIdx];
1483         initMbBrcConstantDataBufferParams.dwMbEncBlockBasedSkipEn     = dwMbEncBlockBasedSkipEn;
1484         initMbBrcConstantDataBufferParams.pPicParams                  = m_avcPicParams[ppsIdx];
1485         initMbBrcConstantDataBufferParams.wPictureCodingType          = m_pictureCodingType;
1486         initMbBrcConstantDataBufferParams.bSkipBiasAdjustmentEnable   = m_skipBiasAdjustmentEnable;
1487         initMbBrcConstantDataBufferParams.bAdaptiveIntraScalingEnable = bAdaptiveIntraScalingEnable;
1488         initMbBrcConstantDataBufferParams.bOldModeCostEnable          = bOldModeCostEnable;
1489         initMbBrcConstantDataBufferParams.pAvcQCParams                = m_avcQCParams;
1490         initMbBrcConstantDataBufferParams.bEnableKernelTrellis        = bKernelTrellis && m_trellisQuantParams.dwTqEnabled;
1491 
1492         // Kernel controlled Trellis Quantization
1493         if (bKernelTrellis && m_trellisQuantParams.dwTqEnabled)
1494         {
1495             CODECHAL_ENCODE_CHK_STATUS_RETURN(CalcLambdaTable(
1496                 m_pictureCodingType,
1497                 &initMbBrcConstantDataBufferParams.Lambda[0][0]));
1498         }
1499 
1500         CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMbBrcConstantDataBuffer(&initMbBrcConstantDataBufferParams));
1501 
1502         //dump MbBrcLut
1503         CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1504             initMbBrcConstantDataBufferParams.presBrcConstantDataBuffer,
1505             CodechalDbgAttr::attrOutput,
1506             "MbBrcLut",
1507             16 * (CODEC_AVC_NUM_QP) * sizeof(uint32_t),
1508             0,
1509             CODECHAL_MEDIA_STATE_ENC_QUALITY)));
1510     }
1511 
1512     // Add binding table
1513     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
1514         m_stateHeapInterface,
1515         kernelState));
1516 
1517     //Add surface states
1518     CODECHAL_ENCODE_AVC_MBENC_SURFACE_PARAMS mbEncSurfaceParams;
1519     MOS_ZeroMemory(&mbEncSurfaceParams, sizeof(mbEncSurfaceParams));
1520     mbEncSurfaceParams.MediaStateType        = encFunctionType;
1521     mbEncSurfaceParams.pAvcSlcParams         = m_avcSliceParams;
1522     mbEncSurfaceParams.ppRefList             = &m_refList[0];
1523     mbEncSurfaceParams.pAvcPicIdx            = &m_picIdx[0];
1524     mbEncSurfaceParams.pCurrOriginalPic      = &m_currOriginalPic;
1525     mbEncSurfaceParams.pCurrReconstructedPic = &m_currReconstructedPic;
1526     mbEncSurfaceParams.wPictureCodingType    = m_pictureCodingType;
1527     mbEncSurfaceParams.psCurrPicSurface      = mbEncIFrameDistInUse ? m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER) : m_rawSurfaceToEnc;
1528     if (mbEncIFrameDistInUse && CodecHal_PictureIsBottomField(m_currOriginalPic))
1529     {
1530         mbEncSurfaceParams.dwCurrPicSurfaceOffset = m_scaledBottomFieldOffset;
1531     }
1532     mbEncSurfaceParams.dwMbCodeBottomFieldOffset          = (uint32_t)m_mbcodeBottomFieldOffset;
1533     mbEncSurfaceParams.dwMvBottomFieldOffset              = (uint32_t)m_mvBottomFieldOffset;
1534     mbEncSurfaceParams.ps4xMeMvDataBuffer                 = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer);
1535     mbEncSurfaceParams.ps4xMeDistortionBuffer             = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer);
1536     mbEncSurfaceParams.dwMeMvBottomFieldOffset            = m_hmeKernel->Get4xMeMvBottomFieldOffset();
1537     mbEncSurfaceParams.dwMeDistortionBottomFieldOffset    = m_hmeKernel->GetDistortionBottomFieldOffset();
1538     mbEncSurfaceParams.psMeBrcDistortionBuffer            = &BrcBuffers.sMeBrcDistortionBuffer;
1539     mbEncSurfaceParams.dwMeBrcDistortionBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset;
1540     mbEncSurfaceParams.dwRefPicSelectBottomFieldOffset    = (uint32_t)ulRefPicSelectBottomFieldOffset;
1541     mbEncSurfaceParams.dwFrameWidthInMb                   = (uint32_t)m_picWidthInMb;
1542     mbEncSurfaceParams.dwFrameFieldHeightInMb             = (uint32_t)m_frameFieldHeightInMb;
1543     mbEncSurfaceParams.dwFrameHeightInMb                  = (uint32_t)m_picHeightInMb;
1544     // Interleaved input surfaces
1545     mbEncSurfaceParams.dwVerticalLineStride       = m_verticalLineStride;
1546     mbEncSurfaceParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset;
1547     // Vertical line stride is not used for the case of scaled surfaces saved as separate fields
1548     if (!m_fieldScalingOutputInterleaved && mbEncIFrameDistInUse)
1549     {
1550         mbEncSurfaceParams.dwVerticalLineStride       = 0;
1551         mbEncSurfaceParams.dwVerticalLineStrideOffset = 0;
1552     }
1553     mbEncSurfaceParams.bHmeEnabled              = m_hmeSupported;
1554     mbEncSurfaceParams.bMbEncIFrameDistInUse    = mbEncIFrameDistInUse;
1555     mbEncSurfaceParams.presMbBrcConstDataBuffer = &BrcBuffers.resMbBrcConstDataBuffer[m_currRecycledBufIdx];
1556     mbEncSurfaceParams.psMbQpBuffer             =
1557         bMbQpDataEnabled ? &sMbQpDataSurface : &BrcBuffers.sBrcMbQpBuffer;
1558     mbEncSurfaceParams.dwMbQpBottomFieldOffset  = bMbQpDataEnabled ? 0 : BrcBuffers.dwBrcMbQpBottomFieldOffset;
1559     mbEncSurfaceParams.bUsedAsRef               =
1560         m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef;
1561     mbEncSurfaceParams.presMADDataBuffer        = &m_resMadDataBuffer[m_currMadBufferIdx];
1562     mbEncSurfaceParams.bMbQpBufferInUse         = mbQpBufferInUse;
1563     mbEncSurfaceParams.bMbSpecificDataEnabled   = bMbSpecificDataEnabled;
1564     mbEncSurfaceParams.presMbSpecificDataBuffer = &resMbSpecificDataBuffer[m_currRecycledBufIdx];
1565     mbEncSurfaceParams.bMbConstDataBufferInUse  = mbConstDataBufferInUse;
1566     mbEncSurfaceParams.bMADEnabled              = mbEncIFrameDistInUse ? false : m_madEnabled;
1567     mbEncSurfaceParams.bUseMbEncAdvKernel       = mbEncIFrameDistInUse ? false : bUseMbEncAdvKernel;
1568     mbEncSurfaceParams.presMbEncCurbeBuffer     =
1569         (mbEncIFrameDistInUse && bUseMbEncAdvKernel) ? nullptr : &BrcBuffers.resMbEncAdvancedDsh;
1570     mbEncSurfaceParams.presMbEncBRCBuffer       = &BrcBuffers.resMbEncBrcBuffer;
1571 
1572     if (bDecoupleMbEncCurbeFromBRC)
1573     {
1574         mbEncSurfaceParams.dwMbEncBRCBufferSize = m_mbencBrcBufferSize;
1575     }
1576 
1577     mbEncSurfaceParams.bUseAdvancedDsh            = bAdvancedDshInUse;
1578     mbEncSurfaceParams.bBrcEnabled                 = bBrcEnabled;
1579     mbEncSurfaceParams.bArbitraryNumMbsInSlice     = m_arbitraryNumMbsInSlice;
1580     mbEncSurfaceParams.psSliceMapSurface           = &m_sliceMapSurface[m_currRecycledBufIdx];
1581     mbEncSurfaceParams.dwSliceMapBottomFieldOffset = (uint32_t)m_sliceMapBottomFieldOffset;
1582     mbEncSurfaceParams.pMbEncBindingTable          = &MbEncBindingTable;
1583     mbEncSurfaceParams.pKernelState                = kernelState;
1584 
1585     if (m_mbStatsSupported)
1586     {
1587         mbEncSurfaceParams.bMBVProcStatsEnabled = m_flatnessCheckEnabled ||
1588                                                   m_adaptiveTransformDecisionEnabled ||
1589                                                   bMbBrcEnabled ||
1590                                                   bMbQpDataEnabled;
1591         mbEncSurfaceParams.presMBVProcStatsBuffer          = &m_resMbStatsBuffer;
1592         mbEncSurfaceParams.dwMBVProcStatsBottomFieldOffset = m_mbStatsBottomFieldOffset;
1593     }
1594     else
1595     {
1596         mbEncSurfaceParams.bFlatnessCheckEnabled            = m_flatnessCheckEnabled;
1597         mbEncSurfaceParams.psFlatnessCheckSurface           = &m_flatnessCheckSurface;
1598         mbEncSurfaceParams.dwFlatnessCheckBottomFieldOffset = (uint32_t)m_flatnessCheckBottomFieldOffset;
1599     }
1600 
1601     // Set up pFeiPicParams
1602     mbEncSurfaceParams.pFeiPicParams = m_avcFeiPicParams;
1603 
1604     mbEncSurfaceParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled;
1605     mbEncSurfaceParams.psMbDisableSkipMapSurface = psMbDisableSkipMapSurface;
1606 
1607     if (bUseWeightedSurfaceForL0 || bUseWeightedSurfaceForL1)
1608     {
1609         if (!m_wpUseCommonKernel)
1610         {
1611             mbEncSurfaceParams.pWeightedPredOutputPicSelectList = &WeightedPredOutputPicSelectList[0];
1612         }
1613         mbEncSurfaceParams.bUseWeightedSurfaceForL0 = bUseWeightedSurfaceForL0;
1614         mbEncSurfaceParams.bUseWeightedSurfaceForL1 = bUseWeightedSurfaceForL1;
1615     }
1616 
1617     // Clear the MAD buffer -- the kernel requires it to be 0 as it accumulates the result
1618     if (mbEncSurfaceParams.bMADEnabled)
1619     {
1620         // set lock flag to WRITE_ONLY
1621         MOS_LOCK_PARAMS lockFlags;
1622         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
1623         lockFlags.WriteOnly = 1;
1624 
1625         uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
1626             m_osInterface,
1627             mbEncSurfaceParams.presMADDataBuffer,
1628             &lockFlags);
1629 
1630         CODECHAL_ENCODE_CHK_NULL_RETURN(data);
1631 
1632         MOS_ZeroMemory(data, CODECHAL_MAD_BUFFER_SIZE);
1633 
1634         m_osInterface->pfnUnlockResource(
1635             m_osInterface,
1636             mbEncSurfaceParams.presMADDataBuffer);
1637 
1638         CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1639             &m_resMadDataBuffer[m_currMadBufferIdx],
1640             CodechalDbgAttr::attrOutput,
1641             "MADRead",
1642             CODECHAL_MAD_BUFFER_SIZE,
1643             0,
1644             encFunctionType)));
1645     }
1646 
1647     // static frame detection buffer
1648     mbEncSurfaceParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled;
1649     mbEncSurfaceParams.presSFDOutputBuffer = &resSFDOutputBuffer[0];
1650     if (m_pictureCodingType == P_TYPE)
1651     {
1652         mbEncSurfaceParams.presSFDCostTableBuffer = &resSFDCostTablePFrameBuffer;
1653     }
1654     else if (m_pictureCodingType == B_TYPE)
1655     {
1656         mbEncSurfaceParams.presSFDCostTableBuffer = &resSFDCostTableBFrameBuffer;
1657     }
1658 
1659     CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcMbEncSurfaces(&cmdBuffer, &mbEncSurfaceParams));
1660 
1661 
1662     uint32_t resolutionX = mbEncIFrameDistInUse ?
1663         m_downscaledWidthInMb4x : (uint32_t)m_picWidthInMb;
1664     uint32_t resolutionY = mbEncIFrameDistInUse ?
1665         m_downscaledFrameFieldHeightInMb4x : (uint32_t)m_frameFieldHeightInMb;
1666 
1667     CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
1668     MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
1669     walkerCodecParams.WalkerMode               = m_walkerMode;
1670     walkerCodecParams.bUseScoreboard           = m_useHwScoreboard;
1671     walkerCodecParams.wPictureCodingType       = m_pictureCodingType;
1672     walkerCodecParams.bMbEncIFrameDistInUse    = mbEncIFrameDistInUse;
1673     walkerCodecParams.bMbaff                   = m_mbaffEnabled;
1674     walkerCodecParams.bDirectSpatialMVPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag;
1675     walkerCodecParams.bColorbitSupported       = (m_colorbitSupported && !m_arbitraryNumMbsInSlice) ? m_cmKernelEnable : false;
1676     walkerCodecParams.dwResolutionX            = resolutionX;
1677     walkerCodecParams.dwResolutionY            = resolutionY;
1678     walkerCodecParams.dwNumSlices              = m_numSlices;
1679     walkerCodecParams.usSliceHeight            = m_sliceHeight;
1680     walkerCodecParams.bGroupIdSelectSupported  = m_groupIdSelectSupported;
1681     walkerCodecParams.ucGroupId                = m_groupId;
1682 
1683     MHW_WALKER_PARAMS walkerParams;
1684     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
1685         m_hwInterface,
1686         &walkerParams,
1687         &walkerCodecParams));
1688 
1689     HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
1690     HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());
1691 
1692     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd(
1693         &cmdBuffer,
1694         &walkerParams));
1695 
1696     CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));
1697 
1698     // Add dump for MBEnc surface state heap here
1699     CODECHAL_DEBUG_TOOL(
1700         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
1701             encFunctionType,
1702             MHW_SSH_TYPE,
1703             kernelState));
1704     )
1705 
1706     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
1707         m_stateHeapInterface,
1708         kernelState));
1709 
1710     if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
1711     {
1712         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
1713             m_stateHeapInterface));
1714         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1715     }
1716 
1717     CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1718         &cmdBuffer,
1719         encFunctionType,
1720         nullptr)));
1721     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));
1722 
1723     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1724 
1725     if ((!m_singleTaskPhaseSupported || m_lastTaskInPhase))
1726     {
1727         HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
1728         m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
1729         m_lastTaskInPhase = false;
1730     }
1731 
1732     currRefList->ucMADBufferIdx = m_currMadBufferIdx;
1733     currRefList->bMADEnabled    = m_madEnabled;
1734 
1735     return eStatus;
1736 }
1737 
SetAndPopulateVEHintParams(PMOS_COMMAND_BUFFER cmdBuffer)1738 MOS_STATUS CodechalEncodeAvcEncG12::SetAndPopulateVEHintParams(
1739     PMOS_COMMAND_BUFFER  cmdBuffer)
1740 {
1741     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1742 
1743     CODECHAL_ENCODE_FUNCTION_ENTER;
1744 
1745     if (!MOS_VE_SUPPORTED(m_osInterface))
1746     {
1747         return eStatus;
1748     }
1749 
1750     if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
1751     {
1752         MOS_VIRTUALENGINE_SET_PARAMS  vesetParams;
1753         MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
1754         vesetParams.bNeedSyncWithPrevious = true;
1755         vesetParams.bSFCInUse = false;
1756         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_SetHintParams(m_sinlgePipeVeState, &vesetParams));
1757     }
1758     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_PopulateHintParams(m_sinlgePipeVeState, cmdBuffer, true));
1759 
1760     return eStatus;
1761 }
1762 
SubmitCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer,bool bNullRendering)1763 MOS_STATUS CodechalEncodeAvcEncG12::SubmitCommandBuffer(
1764     PMOS_COMMAND_BUFFER cmdBuffer,
1765     bool             bNullRendering)
1766 {
1767     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1768 
1769     CODECHAL_ENCODE_FUNCTION_ENTER;
1770 
1771     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1772 
1773     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetAndPopulateVEHintParams(cmdBuffer));
1774     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, bNullRendering));
1775     return eStatus;
1776 }
1777 
ExecuteKernelFunctions()1778 MOS_STATUS CodechalEncodeAvcEncG12::ExecuteKernelFunctions()
1779 {
1780     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1781 
1782     CODECHAL_ENCODE_FUNCTION_ENTER;
1783 
1784     auto slcParams = m_avcSliceParams;
1785     auto slcType   = Slice_Type[slcParams->slice_type];
1786 
1787     CODECHAL_DEBUG_TOOL(
1788     //    CodecHal_DbgMapSurfaceFormatToDumpFormat(m_rawSurfaceToEnc->Format, &dumpType);
1789         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1790             m_rawSurfaceToEnc,
1791             CodechalDbgAttr::attrEncodeRawInputSurface,
1792             "SrcSurf")));
1793 
1794     CODECHAL_ENCODE_CHK_NULL_RETURN(m_cscDsState);
1795 
1796     // Scaling, BRC Init/Reset and HME are included in the same task phase
1797     m_lastEncPhase     = false;
1798     m_firstTaskInPhase = true;
1799 
1800     // BRC init/reset needs to be called before HME since it will reset the Brc Distortion surface
1801     if (bBrcEnabled && (bBrcInit || bBrcReset))
1802     {
1803         bool cscEnabled            = m_cscDsState->RequireCsc() && m_firstField;
1804         m_lastTaskInPhase = !(cscEnabled || m_scalingEnabled || m_16xMeSupported || m_hmeEnabled);
1805         CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcInitResetKernel());
1806     }
1807 
1808     UpdateSSDSliceCount();
1809 
1810     if (m_firstField)
1811     {
1812         // Csc, Downscaling, and/or 10-bit to 8-bit conversion
1813         CodechalEncodeCscDs::KernelParams cscScalingKernelParams;
1814         memset((void *)&cscScalingKernelParams, 0, sizeof(cscScalingKernelParams));
1815         cscScalingKernelParams.bLastTaskInPhaseCSC =
1816             cscScalingKernelParams.bLastTaskInPhase4xDS = !(m_16xMeSupported || m_hmeEnabled);
1817         cscScalingKernelParams.bLastTaskInPhase16xDS    = !(m_32xMeSupported || m_hmeEnabled);
1818         cscScalingKernelParams.bLastTaskInPhase32xDS    = !m_hmeEnabled;
1819         cscScalingKernelParams.inputColorSpace          = m_avcSeqParam->InputColorSpace;
1820 
1821         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->KernelFunctions(&cscScalingKernelParams));
1822     }
1823 
1824     if (m_hmeKernel && m_hmeKernel->Is4xMeEnabled())
1825     {
1826         CodechalKernelHme::CurbeParam curbeParam = {};
1827         curbeParam.subPelMode = 3;
1828         curbeParam.currOriginalPic = m_avcPicParam->CurrOriginalPic;
1829         curbeParam.qpPrimeY = m_avcPicParam->pic_init_qp_minus26 + 26 + m_avcSliceParams->slice_qp_delta;
1830         curbeParam.targetUsage = m_avcSeqParam->TargetUsage;
1831         curbeParam.maxMvLen = CodecHalAvcEncode_GetMaxMvLen(m_avcSeqParam->Level);
1832         curbeParam.numRefIdxL0Minus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1;
1833         curbeParam.numRefIdxL1Minus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1;
1834 
1835         auto slcParams = m_avcSliceParams;
1836         curbeParam.list0RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_0);
1837         curbeParam.list0RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_1);
1838         curbeParam.list0RefID2FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_2);
1839         curbeParam.list0RefID3FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_3);
1840         curbeParam.list0RefID4FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_4);
1841         curbeParam.list0RefID5FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_5);
1842         curbeParam.list0RefID6FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_6);
1843         curbeParam.list0RefID7FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_7);
1844         curbeParam.list1RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_0);
1845         curbeParam.list1RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_1);
1846 
1847         CodechalKernelHme::SurfaceParams surfaceParam = {};
1848         surfaceParam.mbaffEnabled = m_mbaffEnabled;
1849         surfaceParam.numRefIdxL0ActiveMinus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1;
1850         surfaceParam.numRefIdxL1ActiveMinus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1;
1851         surfaceParam.verticalLineStride = m_verticalLineStride;
1852         surfaceParam.verticalLineStrideOffset = m_verticalLineStrideOffset;
1853         surfaceParam.meBrcDistortionBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset;
1854         surfaceParam.refList = &m_refList[0];
1855         surfaceParam.picIdx = &m_picIdx[0];
1856         surfaceParam.currOriginalPic = &m_currOriginalPic;
1857         surfaceParam.refL0List = &(m_avcSliceParams->RefPicList[LIST_0][0]);
1858         surfaceParam.refL1List = &(m_avcSliceParams->RefPicList[LIST_1][0]);
1859         surfaceParam.meBrcDistortionBuffer = &BrcBuffers.sMeBrcDistortionBuffer;
1860 
1861         if (m_hmeKernel->Is16xMeEnabled())
1862         {
1863             m_lastTaskInPhase = false;
1864             if (m_hmeKernel->Is32xMeEnabled())
1865             {
1866                 surfaceParam.downScaledWidthInMb = m_downscaledWidthInMb32x;
1867                 surfaceParam.downScaledHeightInMb = m_downscaledFrameFieldHeightInMb32x;
1868                 surfaceParam.downScaledBottomFieldOffset = m_scaled32xBottomFieldOffset;
1869 
1870                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel32x));
1871             }
1872             surfaceParam.downScaledWidthInMb = m_downscaledWidthInMb16x;
1873             surfaceParam.downScaledHeightInMb = m_downscaledFrameFieldHeightInMb16x;
1874             surfaceParam.downScaledBottomFieldOffset = m_scaled16xBottomFieldOffset;
1875 
1876             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel16x));
1877         }
1878         surfaceParam.downScaledWidthInMb = m_downscaledWidthInMb4x;
1879         surfaceParam.downScaledHeightInMb = m_downscaledFrameFieldHeightInMb4x;
1880         surfaceParam.downScaledBottomFieldOffset = m_scaledBottomFieldOffset;
1881 
1882         m_lastTaskInPhase = true;
1883         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel4x));
1884     }
1885 
1886     // Scaling and HME are not dependent on the output from PAK
1887     if (m_waitForPak && m_semaphoreObjCount && !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse))
1888     {
1889         // Wait on PAK
1890         auto syncParams             = g_cInitSyncParams;
1891         syncParams.GpuContext       = m_renderContext;
1892         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1893         syncParams.uiSemaphoreCount = m_semaphoreObjCount;
1894 
1895         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1896         m_semaphoreObjCount = 0;  //reset
1897     }
1898 
1899     // BRC and MbEnc are included in the same task phase
1900     m_lastEncPhase     = true;
1901     m_firstTaskInPhase = true;
1902 
1903     // Initialize software scoreboard used by MBEnc kernel
1904     // Decide dependency pattern
1905     CodechalEncodeSwScoreboard::KernelParams swScoreboardKernelParames;
1906     memset((void *)&swScoreboardKernelParames, 0, sizeof(swScoreboardKernelParames));
1907 
1908     if (m_pictureCodingType == I_TYPE ||
1909         (m_pictureCodingType == B_TYPE && !m_avcSliceParams->direct_spatial_mv_pred_flag))  // I or B-temporal
1910     {
1911         swScoreboardKernelParames.surfaceIndex = dependencyWavefront45Degree;
1912         m_swScoreboardState->SetDependencyPattern(dependencyWavefront45Degree);
1913     }
1914     else  //P or B-spatial
1915     {
1916         swScoreboardKernelParames.surfaceIndex = dependencyWavefront26Degree;
1917         m_swScoreboardState->SetDependencyPattern(dependencyWavefront26Degree);
1918     }
1919 
1920     m_swScoreboardState->SetCurSwScoreboardSurfaceIndex(swScoreboardKernelParames.surfaceIndex);
1921 
1922     // Call SW scoreboard Init kernel
1923     swScoreboardKernelParames.scoreboardWidth           = m_picWidthInMb;
1924     swScoreboardKernelParames.scoreboardHeight          = m_frameFieldHeightInMb;
1925     swScoreboardKernelParames.swScoreboardSurfaceWidth  = swScoreboardKernelParames.scoreboardWidth * 4;
1926     swScoreboardKernelParames.swScoreboardSurfaceHeight = swScoreboardKernelParames.scoreboardHeight;
1927 
1928     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_swScoreboardState->Execute(&swScoreboardKernelParames));
1929 
1930     // Dump BrcDist 4X_ME buffer here because it will be overwritten in BrcFrameUpdateKernel
1931     CODECHAL_DEBUG_TOOL(
1932         if (m_hmeEnabled && bBrcDistortionBufferSupported)
1933         {
1934             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1935                 &BrcBuffers.sMeBrcDistortionBuffer.OsResource,
1936                 CodechalDbgAttr::attrOutput,
1937                 "BrcDist",
1938                 BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight,
1939                 BrcBuffers.dwMeBrcDistortionBottomFieldOffset,
1940                 CODECHAL_MEDIA_STATE_4X_ME));
1941         })
1942 
1943     if (bBrcEnabled)
1944     {
1945         if (bMbEncIFrameDistEnabled)
1946         {
1947             CodechalKernelIntraDist::CurbeParam curbeParam;
1948             curbeParam.downScaledWidthInMb4x  = m_downscaledWidthInMb4x;
1949             curbeParam.downScaledHeightInMb4x = m_downscaledFrameFieldHeightInMb4x;
1950             CodechalKernelIntraDist::SurfaceParams surfaceParam;
1951             surfaceParam.input4xDsSurface           =
1952             surfaceParam.input4xDsVmeSurface        = m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER);
1953             surfaceParam.intraDistSurface           = &BrcBuffers.sMeBrcDistortionBuffer;
1954             surfaceParam.intraDistBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset;
1955             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_intraDistKernel->Execute(curbeParam, surfaceParam));
1956         }
1957 
1958         CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcFrameUpdateKernel());
1959         if (bBrcSplitEnable && bMbBrcEnabled)
1960         {
1961             CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcMbUpdateKernel());
1962         }
1963 
1964         // Reset buffer ID used for BRC kernel performance reports
1965         m_osInterface->pfnResetPerfBufferID(m_osInterface);
1966     }
1967 
1968     bUseWeightedSurfaceForL0 = false;
1969     bUseWeightedSurfaceForL1 = false;
1970 
1971     if (bWeightedPredictionSupported &&
1972         ((((slcType == SLICE_P) || (slcType == SLICE_SP)) && (m_avcPicParam->weighted_pred_flag)) ||
1973             (((slcType == SLICE_B)) && (m_avcPicParam->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE))))
1974     {
1975         uint8_t idx;
1976         // Weighted Prediction to be applied for L0
1977         for (idx = 0; idx < (slcParams->num_ref_idx_l0_active_minus1 + 1); idx++)
1978         {
1979             if ((slcParams->luma_weight_flag[LIST_0] & (1 << idx)) && (idx < CODEC_AVC_MAX_FORWARD_WP_FRAME))
1980             {
1981                 //Weighted Prediction for ith forward reference frame
1982                 CODECHAL_ENCODE_CHK_STATUS_RETURN(WPKernel(false, idx));
1983             }
1984         }
1985 
1986         if (((slcType == SLICE_B)) &&
1987             (m_avcPicParam->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE))
1988         {
1989             for (idx = 0; idx < (slcParams->num_ref_idx_l1_active_minus1 + 1); idx++)
1990             {
1991                 // Weighted Pred to be applied for L1
1992                 if ((slcParams->luma_weight_flag[LIST_1] & 1 << idx) && (idx < CODEC_AVC_MAX_BACKWARD_WP_FRAME))
1993                 {
1994                     //Weighted Prediction for ith backward reference frame
1995                     CODECHAL_ENCODE_CHK_STATUS_RETURN(WPKernel(false, idx));
1996                 }
1997             }
1998         }
1999     }
2000 
2001 #if (_DEBUG || _RELEASE_INTERNAL)
2002 
2003     MOS_USER_FEATURE_VALUE_WRITE_DATA userFeatureWriteData;
2004 
2005     // Weighted prediction for L0 Reporting
2006     userFeatureWriteData               = __NULL_USER_FEATURE_VALUE_WRITE_DATA__;
2007     userFeatureWriteData.Value.i32Data = bUseWeightedSurfaceForL0;
2008     userFeatureWriteData.ValueID       = __MEDIA_USER_FEATURE_VALUE_WEIGHTED_PREDICTION_L0_IN_USE_ID;
2009     MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);
2010 
2011     // Weighted prediction for L1 Reporting
2012     userFeatureWriteData               = __NULL_USER_FEATURE_VALUE_WRITE_DATA__;
2013     userFeatureWriteData.Value.i32Data = bUseWeightedSurfaceForL1;
2014     userFeatureWriteData.ValueID       = __MEDIA_USER_FEATURE_VALUE_WEIGHTED_PREDICTION_L1_IN_USE_ID;
2015     MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1, m_osInterface->pOsContext);
2016 
2017 #endif  // _DEBUG || _RELEASE_INTERNAL
2018 
2019     m_lastTaskInPhase = true;
2020     CODECHAL_ENCODE_CHK_STATUS_RETURN(MbEncKernel(false));
2021 
2022     // Reset buffer ID used for MbEnc kernel performance reports
2023     m_osInterface->pfnResetPerfBufferID(m_osInterface);
2024 
2025     if (!Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
2026     {
2027         auto syncParams             = g_cInitSyncParams;
2028         syncParams.GpuContext       = m_renderContext;
2029         syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse;
2030 
2031         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
2032     }
2033 
2034     if (m_madEnabled)
2035     {
2036         m_currMadBufferIdx = (m_currMadBufferIdx + 1) % CODECHAL_ENCODE_MAX_NUM_MAD_BUFFERS;
2037     }
2038 
2039     // Reset after BRC Init has been processed
2040     bBrcInit = false;
2041 
2042     m_setRequestedEUSlices = false;
2043 
2044     CODECHAL_DEBUG_TOOL(KernelDebugDumps());
2045 
2046     if (bBrcEnabled)
2047     {
2048         bMbEncCurbeSetInBrcUpdate = false;
2049     }
2050 
2051     return eStatus;
2052 }
2053 
GenericEncodePictureLevel(PCODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS params)2054 MOS_STATUS CodechalEncodeAvcEncG12::GenericEncodePictureLevel(PCODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS params)
2055 {
2056     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2057 
2058     CODECHAL_ENCODE_FUNCTION_ENTER;
2059 
2060     auto trellisQuantParams = &m_trellisQuantParams;
2061 
2062     PerfTagSetting perfTag;
2063     perfTag.Value = 0;
2064     perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
2065     perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE;
2066     perfTag.PictureCodingType = m_pictureCodingType;
2067     m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
2068 
2069     MOS_COMMAND_BUFFER cmdBuffer;
2070     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
2071 
2072     MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
2073     MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
2074     forceWakeupParams.bMFXPowerWellControl = true;
2075     forceWakeupParams.bMFXPowerWellControlMask = true;
2076     forceWakeupParams.bHEVCPowerWellControl = false;
2077     forceWakeupParams.bHEVCPowerWellControlMask = true;
2078     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
2079         &cmdBuffer,
2080         &forceWakeupParams));
2081 
2082     // set MFX_PIPE_MODE_SELECT values
2083     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
2084     pipeModeSelectParams.Mode = m_mode;
2085     pipeModeSelectParams.bStreamOutEnabled = (m_currPass != m_numPasses);// Disable Stream Out for final pass; its important for multiple passes, because , next pass will take the qp from stream out
2086 
2087     pipeModeSelectParams.bDeblockerStreamOutEnable = params->bDeblockerStreamOutEnable;
2088     pipeModeSelectParams.bPostDeblockOutEnable = params->bPostDeblockOutEnable;
2089     pipeModeSelectParams.bPreDeblockOutEnable = params->bPreDeblockOutEnable;
2090     pipeModeSelectParams.bDynamicSliceEnable = m_avcSeqParam->EnableSliceLevelRateCtrl;
2091 
2092     // set MFX_PIPE_BUF_ADDR_STATE values
2093     MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
2094     pipeBufAddrParams.Mode = m_mode;
2095     pipeBufAddrParams.psPreDeblockSurface = params->psPreDeblockSurface;
2096     pipeBufAddrParams.psPostDeblockSurface = params->psPostDeblockSurface;
2097     pipeBufAddrParams.psRawSurface = m_rawSurfaceToPak;
2098     pipeBufAddrParams.presStreamOutBuffer = &m_resStreamOutBuffer[m_currRecycledBufIdx];
2099     pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resDeblockingFilterRowStoreScratchBuffer;
2100     pipeBufAddrParams.presMfdIntraRowStoreScratchBuffer = &m_intraRowStoreScratchBuffer;
2101     pipeBufAddrParams.presMacroblockIldbStreamOutBuffer1 = params->presMacroblockIldbStreamOutBuffer1;
2102     pipeBufAddrParams.presMacroblockIldbStreamOutBuffer2 = params->presMacroblockIldbStreamOutBuffer2;
2103 
2104     CODECHAL_DEBUG_TOOL(
2105     // PAK Input Raw Surface
2106     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
2107         m_rawSurfaceToPak,
2108         CodechalDbgAttr::attrEncodeRawInputSurface,
2109         "PAK_Input_SrcSurf"));
2110     )
2111 
2112         auto firstValidFrame = &m_reconSurface.OsResource;
2113 
2114     // Setting invalid entries to nullptr
2115     for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
2116     {
2117         pipeBufAddrParams.presReferences[i] = nullptr;
2118     }
2119 
2120     uint8_t firstValidFrameId = CODEC_AVC_MAX_NUM_REF_FRAME;
2121 
2122     for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
2123     {
2124         if (m_picIdx[i].bValid)
2125         {
2126             uint8_t picIdx = m_picIdx[i].ucPicIdx;
2127             uint8_t frameStoreId = m_refList[picIdx]->ucFrameId;
2128 
2129             CodecHalGetResourceInfo(
2130                 m_osInterface,
2131                 &(m_refList[picIdx]->sRefReconBuffer));
2132             pipeBufAddrParams.presReferences[frameStoreId] =
2133                 &(m_refList[picIdx]->sRefReconBuffer.OsResource);
2134 
2135             if (picIdx < firstValidFrameId)
2136             {
2137                 firstValidFrameId = picIdx;
2138                 firstValidFrame = pipeBufAddrParams.presReferences[picIdx];
2139             }
2140 
2141             CODECHAL_DEBUG_TOOL(
2142                 CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
2143                 MOS_SURFACE refSurface;
2144 
2145                 MOS_ZeroMemory(&refSurface, sizeof(refSurface));
2146                 refSurface.Format     = Format_NV12;
2147                 refSurface.OsResource = *(pipeBufAddrParams.presReferences[frameStoreId]);
2148                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
2149                     m_osInterface,
2150                     &refSurface));
2151 
2152                 m_debugInterface->m_refIndex = frameStoreId;
2153                 std::string refSurfName      = "RefSurf" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex));
2154                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
2155                     &refSurface,
2156                     CodechalDbgAttr::attrReferenceSurfaces,
2157                     refSurfName.data()));)
2158         }
2159     }
2160 
2161     for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
2162     {
2163         // error concealment for the unset reference addresses
2164         if (!pipeBufAddrParams.presReferences[i])
2165         {
2166             pipeBufAddrParams.presReferences[i] = firstValidFrame;
2167         }
2168     }
2169 
2170     if (m_sliceSizeStreamoutSupported)
2171     {
2172         pipeBufAddrParams.presSliceSizeStreamOutBuffer = &m_pakSliceSizeStreamoutBuffer;
2173     }
2174 
2175     // set MFX_IND_OBJ_BASE_ADDR_STATE values
2176     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
2177     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
2178     indObjBaseAddrParams.Mode = CODECHAL_ENCODE_MODE_AVC;
2179 
2180     indObjBaseAddrParams.presMvObjectBuffer = &m_resMvDataSurface;
2181     indObjBaseAddrParams.dwMvObjectOffset = m_mvBottomFieldOffset;
2182     indObjBaseAddrParams.dwMvObjectSize = m_mvDataSize;
2183     indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer;
2184     indObjBaseAddrParams.dwPakBaseObjectSize = m_bitstreamUpperBound;
2185 
2186     // set MFX_BSP_BUF_BASE_ADDR_STATE values
2187     MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
2188     MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
2189     bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resMPCRowStoreScratchBuffer;
2190 
2191     MHW_VDBOX_QM_PARAMS qmParams;
2192     qmParams.Standard = CODECHAL_AVC;
2193     qmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists;
2194 
2195     MHW_VDBOX_QM_PARAMS fqmParams;
2196     fqmParams.Standard = CODECHAL_AVC;
2197     fqmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists;
2198 
2199     // Add AVC Direct Mode command
2200     MHW_VDBOX_AVC_DIRECTMODE_PARAMS directmodeParams;
2201     MOS_ZeroMemory(&directmodeParams, sizeof(directmodeParams));
2202     directmodeParams.CurrPic = m_avcPicParam->CurrReconstructedPic;
2203     directmodeParams.isEncode = true;
2204     directmodeParams.uiUsedForReferenceFlags = 0xFFFFFFFF;
2205     directmodeParams.pAvcPicIdx = &(m_picIdx[0]);
2206     directmodeParams.avcRefList = (void**)m_refList;
2207     directmodeParams.bPicIdRemappingInUse = false;
2208     directmodeParams.bDisableDmvBuffers = true;
2209 
2210     // PAK cmd buffer header insertion for 1) non STF 2) STF (except VDEnc BRC case inserted in HuC cmd buffer)
2211     if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
2212     {
2213         bool requestFrameTracking = false;
2214 
2215         m_hwInterface->m_numRequestedEuSlices = ((m_frameHeight * m_frameWidth) >= m_ssdResolutionThreshold &&
2216             m_targetUsage <= m_ssdTargetUsageThreshold) ?
2217             m_sliceShutdownRequestState : m_sliceShutdownDefaultState;
2218 
2219         // Send command buffer header at the beginning (OS dependent)
2220         // frame tracking tag is only added in the last command buffer header
2221         requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase;
2222         CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
2223 
2224         m_hwInterface->m_numRequestedEuSlices = CODECHAL_SLICE_SHUTDOWN_DEFAULT;
2225     }
2226 
2227     if (m_currPass)
2228     {
2229         MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams;
2230         // Insert conditional batch buffer end
2231         MOS_ZeroMemory(
2232             &miConditionalBatchBufferEndParams,
2233             sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS));
2234 
2235         miConditionalBatchBufferEndParams.presSemaphoreBuffer =
2236             &m_encodeStatusBuf.resStatusBuffer;
2237         miConditionalBatchBufferEndParams.dwOffset =
2238             (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
2239             m_encodeStatusBuf.dwImageStatusMaskOffset +
2240             (sizeof(uint32_t) * 2);
2241 
2242         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
2243             &cmdBuffer,
2244             &miConditionalBatchBufferEndParams));
2245     }
2246 
2247     if (!m_currPass && m_osInterface->bTagResourceSync)
2248     {
2249         // This is a short term WA to solve the sync tag issue: the sync tag write for PAK is inserted at the end of 2nd pass PAK BB
2250         // which may be skipped in multi-pass PAK enabled case. The idea here is to insert the previous frame's tag at the beginning
2251         // of the BB and keep the current frame's tag at the end of the BB. There will be a delay for tag update but it should be fine
2252         // as long as Dec/VP/Enc won't depend on this PAK so soon.
2253         MHW_MI_STORE_DATA_PARAMS                        params;
2254         PMOS_RESOURCE                                   globalGpuContextSyncTagBuffer = nullptr;
2255         uint32_t                                        value;
2256 
2257         CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource(
2258             m_osInterface,
2259             globalGpuContextSyncTagBuffer));
2260         CODECHAL_ENCODE_CHK_NULL_RETURN(globalGpuContextSyncTagBuffer);
2261 
2262         value = m_osInterface->pfnGetGpuStatusTag(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
2263         params.pOsResource = globalGpuContextSyncTagBuffer;
2264         params.dwResourceOffset = m_osInterface->pfnGetGpuStatusTagOffset(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
2265         params.dwValue = (value > 0) ? (value - 1) : 0;
2266         CODECHAL_HW_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &params));
2267     }
2268 
2269     CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
2270 
2271     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
2272 
2273     // set MFX_SURFACE_STATE values
2274     // Ref surface
2275     MHW_VDBOX_SURFACE_PARAMS reconSurfaceParams;
2276     MOS_ZeroMemory(&reconSurfaceParams, sizeof(reconSurfaceParams));
2277     reconSurfaceParams.Mode = m_mode;
2278     reconSurfaceParams.ucSurfaceStateId = CODECHAL_MFX_REF_SURFACE_ID;
2279     reconSurfaceParams.psSurface = &m_reconSurface;
2280 #ifdef _MMC_SUPPORTED
2281     CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
2282     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceState(&reconSurfaceParams));
2283 #endif
2284     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &reconSurfaceParams));
2285 
2286     // Src surface
2287     MHW_VDBOX_SURFACE_PARAMS surfaceParams;
2288     MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
2289     surfaceParams.Mode = m_mode;
2290     surfaceParams.ucSurfaceStateId = CODECHAL_MFX_SRC_SURFACE_ID;
2291     surfaceParams.psSurface = m_rawSurfaceToPak;
2292     surfaceParams.bDisplayFormatSwizzle = m_avcPicParam->bDisplayFormatSwizzle;
2293 #ifdef _MMC_SUPPORTED
2294     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceState(&surfaceParams));
2295 #endif
2296     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
2297 #ifdef _MMC_SUPPORTED
2298     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetPipeBufAddr(&pipeBufAddrParams));
2299 #endif
2300     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
2301 
2302     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
2303 
2304     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
2305 
2306     if (params->bBrcEnabled && m_avcSeqParam->RateControlMethod != RATECONTROL_ICQ)
2307     {
2308         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
2309             &cmdBuffer,
2310             params->pImgStateBatchBuffer));
2311     }
2312     else
2313     {
2314         //Set MFX_AVC_IMG_STATE command
2315         MHW_VDBOX_AVC_IMG_PARAMS imageStateParams;
2316         imageStateParams.currPass = m_currPass;
2317         imageStateParams.pEncodeAvcPicParams = m_avcPicParam;
2318         imageStateParams.pEncodeAvcSeqParams = m_avcSeqParam;
2319         imageStateParams.pEncodeAvcSliceParams = m_avcSliceParams;
2320         if (CodecHalIsFeiEncode(m_codecFunction) && m_avcFeiPicParams && m_avcFeiPicParams->dwMaxFrameSize)
2321         {
2322             imageStateParams.pDeltaQp = m_avcFeiPicParams->pDeltaQp;
2323             imageStateParams.dwMaxFrameSize = m_avcFeiPicParams->dwMaxFrameSize;
2324         }
2325         imageStateParams.wPicWidthInMb = m_picWidthInMb;
2326         imageStateParams.wPicHeightInMb = m_picHeightInMb;
2327         imageStateParams.ppRefList = &(m_refList[0]);
2328         imageStateParams.dwTqEnabled = trellisQuantParams->dwTqEnabled;
2329         imageStateParams.dwTqRounding = trellisQuantParams->dwTqRounding;
2330         imageStateParams.ucKernelMode = m_kernelMode;
2331         imageStateParams.wSlcHeightInMb = m_sliceHeight;
2332         imageStateParams.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level);
2333         imageStateParams.bSliceSizeStreamOutEnabled = m_sliceSizeStreamoutSupported;
2334 
2335         if (m_currPass && (m_currPass == m_numPasses))
2336         {
2337             // Enable IPCM pass, excluding VDENC BRC case
2338             imageStateParams.bIPCMPass = true;
2339         }
2340 
2341         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgCmd(&cmdBuffer, nullptr, &imageStateParams));
2342 
2343         CODECHAL_DEBUG_TOOL(
2344             CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam(
2345                 &cmdBuffer,
2346                 nullptr));
2347         )
2348     }
2349 
2350     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(&cmdBuffer, &qmParams));
2351 
2352     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxFqmCmd(&cmdBuffer, &fqmParams));
2353 
2354     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcDirectmodeCmd(&cmdBuffer, &directmodeParams));
2355 
2356     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
2357 
2358     return eStatus;
2359 }
2360 
SceneChangeReport(PMOS_COMMAND_BUFFER cmdBuffer,PCODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS params)2361 MOS_STATUS CodechalEncodeAvcEncG12::SceneChangeReport(PMOS_COMMAND_BUFFER    cmdBuffer, PCODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS params)
2362 {
2363 
2364     MHW_MI_COPY_MEM_MEM_PARAMS                      copyMemMemParams;
2365     uint32_t offset = (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize)
2366         + (sizeof(uint32_t) * 2) + m_encodeStatusBuf.dwSceneChangedOffset;
2367 
2368     MOS_ZeroMemory(&copyMemMemParams, sizeof(copyMemMemParams));
2369     copyMemMemParams.presSrc = params->presBrcHistoryBuffer;
2370     copyMemMemParams.dwSrcOffset = brcHistoryBufferOffsetSceneChanged;
2371     copyMemMemParams.presDst = &m_encodeStatusBuf.resStatusBuffer;
2372     copyMemMemParams.dwDstOffset = offset;
2373     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd(
2374         cmdBuffer,
2375         &copyMemMemParams));
2376 
2377     return MOS_STATUS_SUCCESS;
2378 }
2379 
InitializeState()2380 MOS_STATUS CodechalEncodeAvcEncG12::InitializeState()
2381 {
2382     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2383     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcEnc::InitializeState());
2384 
2385     m_brcHistoryBufferSize  = m_initBrcHistoryBufferSize;
2386     m_mbencBrcBufferSize    = m_initMbencBrcBufferSize;
2387     m_forceBrcMbStatsEnabled = true;
2388     m_useHwScoreboard        = false;
2389 
2390     dwBrcConstantSurfaceWidth  = m_brcConstantsurfaceWidth;
2391     dwBrcConstantSurfaceHeight = m_brcConstantsurfaceHeight;
2392 
2393     // create intra distortion kernel
2394     m_intraDistKernel = MOS_New(CodechalKernelIntraDist, this);
2395     CODECHAL_ENCODE_CHK_NULL_RETURN(m_intraDistKernel);
2396     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_intraDistKernel->Initialize(
2397         GetCommonKernelHeaderAndSizeG12,
2398         m_kernelBase,
2399         m_kuidCommon));
2400 
2401     // Create SW scoreboard init kernel state
2402     CODECHAL_ENCODE_CHK_NULL_RETURN(m_swScoreboardState = MOS_New(CodechalEncodeSwScoreboardG12, this));
2403     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_swScoreboardState->InitKernelState());
2404 
2405     if (MOS_VE_SUPPORTED(m_osInterface))
2406     {
2407         m_sinlgePipeVeState = (PCODECHAL_ENCODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_ENCODE_SINGLEPIPE_VIRTUALENGINE_STATE));
2408         CODECHAL_ENCODE_CHK_NULL_RETURN(m_sinlgePipeVeState);
2409         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_InitInterface(m_hwInterface, m_sinlgePipeVeState));
2410     }
2411 
2412     return eStatus;
2413 }
2414 
InitMmcState()2415 MOS_STATUS CodechalEncodeAvcEncG12::InitMmcState()
2416 {
2417     CODECHAL_ENCODE_FUNCTION_ENTER;
2418 #ifdef _MMC_SUPPORTED
2419     m_mmcState = MOS_New(CodechalMmcEncodeAvcG12, m_hwInterface, this);
2420     CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
2421 #endif
2422     return MOS_STATUS_SUCCESS;
2423 }
2424 
InitKernelStateBrc()2425 MOS_STATUS CodechalEncodeAvcEncG12::InitKernelStateBrc()
2426 {
2427     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2428 
2429     CODECHAL_ENCODE_FUNCTION_ENTER;
2430 
2431     uint8_t* kernelBinary;
2432     uint32_t kernelSize;
2433 
2434     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, m_kuid, &kernelBinary, &kernelSize));
2435 
2436     CODECHAL_KERNEL_HEADER currKrnHeader;
2437     for (uint32_t krnStateIdx = 0; krnStateIdx < CODECHAL_ENCODE_BRC_IDX_NUM; krnStateIdx++)
2438     {
2439         auto kernelStatePtr = &BrcKernelStates[krnStateIdx];
2440         CODECHAL_ENCODE_CHK_STATUS_RETURN(GetKernelHeaderAndSize(
2441             kernelBinary,
2442             ENC_BRC,
2443             krnStateIdx,
2444             (void*)&currKrnHeader,
2445             &kernelSize));
2446 
2447         kernelStatePtr->KernelParams.iBTCount     = m_brcBTCounts[krnStateIdx];
2448         kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads;
2449         kernelStatePtr->KernelParams.iCurbeLength = m_brcCurbeSize[krnStateIdx];
2450         kernelStatePtr->KernelParams.iBlockWidth  = CODECHAL_MACROBLOCK_WIDTH;
2451         kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
2452         kernelStatePtr->KernelParams.iIdCount     = 1;
2453 
2454         kernelStatePtr->dwCurbeOffset        = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
2455         kernelStatePtr->KernelParams.pBinary = kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
2456         kernelStatePtr->KernelParams.iSize   = kernelSize;
2457 
2458         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
2459             m_stateHeapInterface,
2460             kernelStatePtr->KernelParams.iBTCount,
2461             &kernelStatePtr->dwSshSize,
2462             &kernelStatePtr->dwBindingTableSize));
2463 
2464         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr));
2465     }
2466 
2467     // Until a better way can be found, maintain old binding table structures
2468     auto bindingTable                                 = &BrcUpdateBindingTable;
2469     bindingTable->dwFrameBrcHistoryBuffer             = frameBrcUpdateHistory;
2470     bindingTable->dwFrameBrcPakStatisticsOutputBuffer = frameBrcUpdatePakStatisticsOutput;
2471     bindingTable->dwFrameBrcImageStateReadBuffer      = frameBrcUpdateImageStateRead;
2472     bindingTable->dwFrameBrcImageStateWriteBuffer     = frameBrcUpdateImageStateWrite;
2473 
2474     bindingTable->dwFrameBrcMbEncCurbeWriteData = frameBrcUpdateMbencCurbeWrite;
2475     bindingTable->dwFrameBrcDistortionBuffer    = frameBrcUpdateDistortion;
2476     bindingTable->dwFrameBrcConstantData        = frameBrcUpdateConstantData;
2477     bindingTable->dwFrameBrcMbStatBuffer        = frameBrcUpdateMbStat;
2478     bindingTable->dwFrameBrcMvDataBuffer        = frameBrcUpdateMvStat;
2479 
2480     bindingTable->dwMbBrcHistoryBuffer = mbBrcUpdateHistory;
2481     bindingTable->dwMbBrcMbQpBuffer    = mbBrcUpdateMbQp;
2482     bindingTable->dwMbBrcROISurface    = mbBrcUpdateRoi;
2483     bindingTable->dwMbBrcMbStatBuffer  = mbBrcUpdateMbStat;
2484 
2485     return eStatus;
2486 }
2487 
GetTrellisQuantization(PCODECHAL_ENCODE_AVC_TQ_INPUT_PARAMS params,PCODECHAL_ENCODE_AVC_TQ_PARAMS trellisQuantParams)2488 MOS_STATUS CodechalEncodeAvcEncG12::GetTrellisQuantization(
2489     PCODECHAL_ENCODE_AVC_TQ_INPUT_PARAMS params,
2490     PCODECHAL_ENCODE_AVC_TQ_PARAMS       trellisQuantParams)
2491 {
2492     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2493 
2494     CODECHAL_ENCODE_FUNCTION_ENTER;
2495 
2496     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2497     CODECHAL_ENCODE_CHK_NULL_RETURN(trellisQuantParams);
2498 
2499     trellisQuantParams->dwTqEnabled = TrellisQuantizationEnable[params->ucTargetUsage];
2500     trellisQuantParams->dwTqRounding =
2501         trellisQuantParams->dwTqEnabled ? trellisQuantizationRounding[params->ucTargetUsage] : 0;
2502 
2503     // If AdaptiveTrellisQuantization is enabled then disable trellis quantization for
2504     // B-frames with QP > 26 only in CQP mode
2505     if (trellisQuantParams->dwTqEnabled && EnableAdaptiveTrellisQuantization[params->ucTargetUsage] &&
2506         params->wPictureCodingType == B_TYPE && !params->bBrcEnabled && params->ucQP > 26)
2507     {
2508         trellisQuantParams->dwTqEnabled  = 0;
2509         trellisQuantParams->dwTqRounding = 0;
2510     }
2511     return eStatus;
2512 }
2513 
GetMbEncKernelStateIdx(CodechalEncodeIdOffsetParams * params,uint32_t * kernelOffset)2514 MOS_STATUS CodechalEncodeAvcEncG12::GetMbEncKernelStateIdx(CodechalEncodeIdOffsetParams* params, uint32_t* kernelOffset)
2515 {
2516     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2517 
2518     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2519     CODECHAL_ENCODE_CHK_NULL_RETURN(kernelOffset);
2520 
2521     *kernelOffset = mbencIOffset;
2522 
2523     if (params->EncFunctionType == CODECHAL_MEDIA_STATE_ENC_ADV)
2524     {
2525         *kernelOffset += m_mbencNumTargetUsages * mbencFrameTypeNum;
2526     }
2527     else
2528     {
2529         if (params->EncFunctionType == CODECHAL_MEDIA_STATE_ENC_NORMAL)
2530         {
2531             *kernelOffset += mbencFrameTypeNum;
2532         }
2533         else if (params->EncFunctionType == CODECHAL_MEDIA_STATE_ENC_PERFORMANCE)
2534         {
2535             *kernelOffset += mbencFrameTypeNum * 2;
2536         }
2537     }
2538 
2539     if (params->wPictureCodingType == P_TYPE)
2540     {
2541         *kernelOffset += mbencPOffset;
2542     }
2543     else if (params->wPictureCodingType == B_TYPE)
2544     {
2545         *kernelOffset += mbencBOffset;
2546     }
2547 
2548     return eStatus;
2549 }
2550 
InitKernelStateMbEnc()2551 MOS_STATUS CodechalEncodeAvcEncG12::InitKernelStateMbEnc()
2552 {
2553     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2554 
2555     CODECHAL_ENCODE_FUNCTION_ENTER;
2556 
2557     dwNumMbEncEncKrnStates = m_mbencNumTargetUsages * mbencFrameTypeNum;
2558     dwNumMbEncEncKrnStates += mbencFrameTypeNum;
2559     pMbEncKernelStates = MOS_NewArray(MHW_KERNEL_STATE, dwNumMbEncEncKrnStates);
2560     CODECHAL_ENCODE_CHK_NULL_RETURN(pMbEncKernelStates);
2561 
2562     auto kernelStatePtr = pMbEncKernelStates;
2563 
2564     uint8_t* kernelBinary;
2565     uint32_t kernelSize;
2566 
2567     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, m_kuid, &kernelBinary, &kernelSize));
2568     CODECHAL_KERNEL_HEADER currKrnHeader;
2569 
2570     for (uint32_t krnStateIdx = 0; krnStateIdx < dwNumMbEncEncKrnStates; krnStateIdx++)
2571     {
2572         bool kernelState = (krnStateIdx >= m_mbencNumTargetUsages * mbencFrameTypeNum);
2573 
2574         CODECHAL_ENCODE_CHK_STATUS_RETURN(GetKernelHeaderAndSize(
2575             kernelBinary,
2576             (kernelState ? ENC_MBENC_ADV : ENC_MBENC),
2577             (kernelState ? krnStateIdx - m_mbencNumTargetUsages * mbencFrameTypeNum : krnStateIdx),
2578             &currKrnHeader,
2579             &kernelSize));
2580 
2581         kernelStatePtr->KernelParams.iBTCount     = mbencNumSurfaces;
2582         kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads;
2583         kernelStatePtr->KernelParams.iCurbeLength = sizeof(CodechalEncodeAvcEncG12::MbencCurbe);
2584         kernelStatePtr->KernelParams.iBlockWidth  = CODECHAL_MACROBLOCK_WIDTH;
2585         kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
2586         kernelStatePtr->KernelParams.iIdCount     = 1;
2587 
2588         kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
2589         kernelStatePtr->KernelParams.pBinary =
2590             kernelBinary +
2591             (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
2592         kernelStatePtr->KernelParams.iSize = kernelSize;
2593 
2594         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
2595             m_stateHeapInterface,
2596             kernelStatePtr->KernelParams.iBTCount,
2597             &kernelStatePtr->dwSshSize,
2598             &kernelStatePtr->dwBindingTableSize));
2599 
2600         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr));
2601 
2602         kernelStatePtr++;
2603     }
2604 
2605     // Until a better way can be found, maintain old binding table structures
2606     auto bindingTable = &MbEncBindingTable;
2607 
2608     bindingTable->dwAvcMBEncMfcAvcPakObj   = mbencMfcAvcPakObj;
2609     bindingTable->dwAvcMBEncIndMVData      = mbencIndMvData;
2610     bindingTable->dwAvcMBEncBRCDist        = mbencBrcDistortion;
2611     bindingTable->dwAvcMBEncCurrY          = mbencCurrY;
2612     bindingTable->dwAvcMBEncCurrUV         = mbencCurrUv;
2613     bindingTable->dwAvcMBEncMbSpecificData = mbencMbSpecificData;
2614 
2615     bindingTable->dwAvcMBEncRefPicSelectL0           = mbencRefpicselectL0;
2616     bindingTable->dwAvcMBEncMVDataFromME             = mbencMvDataFromMe;
2617     bindingTable->dwAvcMBEncMEDist                   = mbenc4xMeDistortion;
2618     bindingTable->dwAvcMBEncSliceMapData             = mbencSlicemapData;
2619     bindingTable->dwAvcMBEncBwdRefMBData             = mbencFwdMbData;
2620     bindingTable->dwAvcMBEncBwdRefMVData             = mbencFwdMvData;
2621     bindingTable->dwAvcMBEncMbBrcConstData           = mbencMbbrcConstData;
2622     bindingTable->dwAvcMBEncMBStats                  = mbencMbStats;
2623     bindingTable->dwAvcMBEncMADData                  = mbencMadData;
2624     bindingTable->dwAvcMBEncMbNonSkipMap             = mbencForceNonskipMbMap;
2625     bindingTable->dwAvcMBEncAdv                      = mbEncAdv;
2626     bindingTable->dwAvcMbEncBRCCurbeData             = mbencBrcCurbeData;
2627     bindingTable->dwAvcMBEncStaticDetectionCostTable = mbencSfdCostTable;
2628 
2629     // Frame
2630     bindingTable->dwAvcMBEncMbQpFrame       = mbencMbqp;
2631     bindingTable->dwAvcMBEncCurrPicFrame[0] = mbencVmeInterPredCurrPicIdx0;
2632     bindingTable->dwAvcMBEncFwdPicFrame[0]  = mbencVmeInterPredFwdPicIDX0;
2633     bindingTable->dwAvcMBEncBwdPicFrame[0]  = mbencVmeInterPredBwdPicIDX00;
2634     bindingTable->dwAvcMBEncFwdPicFrame[1]  = mbencVmeInterPredFwdPicIDX1;
2635     bindingTable->dwAvcMBEncBwdPicFrame[1]  = mbencVmeInterPredBwdPicIDX10;
2636     bindingTable->dwAvcMBEncFwdPicFrame[2]  = mbencVmeInterPredFwdPicIDX2;
2637     bindingTable->dwAvcMBEncFwdPicFrame[3]  = mbencVmeInterPredFwdPicIDX3;
2638     bindingTable->dwAvcMBEncFwdPicFrame[4]  = mbencVmeInterPredFwdPicIDX4;
2639     bindingTable->dwAvcMBEncFwdPicFrame[5]  = mbencVmeInterPredFwdPicIDX5;
2640     bindingTable->dwAvcMBEncFwdPicFrame[6]  = mbencVmeInterPredFwdPicIDX6;
2641     bindingTable->dwAvcMBEncFwdPicFrame[7]  = mbencVmeInterPredFwdPicIDX7;
2642     bindingTable->dwAvcMBEncCurrPicFrame[1] = mbencVmeInterPredCurrPicIdx1;
2643     bindingTable->dwAvcMBEncBwdPicFrame[2]  = mbencVmeInterPredBwdPicIDX01;
2644     bindingTable->dwAvcMBEncBwdPicFrame[3]  = mbencVmeInterPredBwdPicIDX11;
2645 
2646     // Field
2647     bindingTable->dwAvcMBEncMbQpField         = mbencMbqp;
2648     bindingTable->dwAvcMBEncFieldCurrPic[0]   = mbencVmeInterPredCurrPicIdx0;
2649     bindingTable->dwAvcMBEncFwdPicTopField[0] = mbencVmeInterPredFwdPicIDX0;
2650     bindingTable->dwAvcMBEncBwdPicTopField[0] = mbencVmeInterPredBwdPicIDX00;
2651     bindingTable->dwAvcMBEncFwdPicBotField[0] = mbencVmeInterPredFwdPicIDX0;
2652     bindingTable->dwAvcMBEncBwdPicBotField[0] = mbencVmeInterPredBwdPicIDX00;
2653     bindingTable->dwAvcMBEncFwdPicTopField[1] = mbencVmeInterPredFwdPicIDX1;
2654     bindingTable->dwAvcMBEncBwdPicTopField[1] = mbencVmeInterPredBwdPicIDX10;
2655     bindingTable->dwAvcMBEncFwdPicBotField[1] = mbencVmeInterPredFwdPicIDX1;
2656     bindingTable->dwAvcMBEncBwdPicBotField[1] = mbencVmeInterPredBwdPicIDX10;
2657     bindingTable->dwAvcMBEncFwdPicTopField[2] = mbencVmeInterPredFwdPicIDX2;
2658     bindingTable->dwAvcMBEncFwdPicBotField[2] = mbencVmeInterPredFwdPicIDX2;
2659     bindingTable->dwAvcMBEncFwdPicTopField[3] = mbencVmeInterPredFwdPicIDX3;
2660     bindingTable->dwAvcMBEncFwdPicBotField[3] = mbencVmeInterPredFwdPicIDX3;
2661     bindingTable->dwAvcMBEncFwdPicTopField[4] = mbencVmeInterPredFwdPicIDX4;
2662     bindingTable->dwAvcMBEncFwdPicBotField[4] = mbencVmeInterPredFwdPicIDX4;
2663     bindingTable->dwAvcMBEncFwdPicTopField[5] = mbencVmeInterPredFwdPicIDX5;
2664     bindingTable->dwAvcMBEncFwdPicBotField[5] = mbencVmeInterPredFwdPicIDX5;
2665     bindingTable->dwAvcMBEncFwdPicTopField[6] = mbencVmeInterPredFwdPicIDX6;
2666     bindingTable->dwAvcMBEncFwdPicBotField[6] = mbencVmeInterPredFwdPicIDX6;
2667     bindingTable->dwAvcMBEncFwdPicTopField[7] = mbencVmeInterPredFwdPicIDX7;
2668     bindingTable->dwAvcMBEncFwdPicBotField[7] = mbencVmeInterPredFwdPicIDX7;
2669     bindingTable->dwAvcMBEncFieldCurrPic[1]   = mbencVmeInterPredCurrPicIdx1;
2670     bindingTable->dwAvcMBEncBwdPicTopField[2] = mbencVmeInterPredBwdPicIDX01;
2671     bindingTable->dwAvcMBEncBwdPicBotField[2] = mbencVmeInterPredBwdPicIDX01;
2672     bindingTable->dwAvcMBEncBwdPicTopField[3] = mbencVmeInterPredBwdPicIDX11;
2673     bindingTable->dwAvcMBEncBwdPicBotField[3] = mbencVmeInterPredBwdPicIDX11;
2674 
2675     return eStatus;
2676 }
2677 
InitMbBrcConstantDataBuffer(PCODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS params)2678 MOS_STATUS CodechalEncodeAvcEncG12::InitMbBrcConstantDataBuffer(PCODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS params)
2679 {
2680     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2681 
2682     CODECHAL_ENCODE_FUNCTION_ENTER;
2683 
2684     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2685     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pOsInterface);
2686     CODECHAL_ENCODE_CHK_NULL_RETURN(params->presBrcConstantDataBuffer);
2687 
2688     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcEnc::InitMbBrcConstantDataBuffer(params));
2689 
2690     if (params->wPictureCodingType == I_TYPE)
2691     {
2692         MOS_LOCK_PARAMS lockFlags;
2693         memset(&lockFlags, 0, sizeof(MOS_LOCK_PARAMS));
2694         lockFlags.WriteOnly = 1;
2695 
2696         uint32_t *dataPtr = (uint32_t *)params->pOsInterface->pfnLockResource(
2697             params->pOsInterface,
2698             params->presBrcConstantDataBuffer,
2699             &lockFlags);
2700         if (dataPtr == nullptr)
2701         {
2702             eStatus = MOS_STATUS_UNKNOWN;
2703             return eStatus;
2704         }
2705 
2706         // Update MbBrcConstantDataBuffer with high texture cost
2707         for (uint8_t qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
2708         {
2709             // Writing to DW13 in each sub-array of 16 DWs
2710             *(dataPtr + 13) = (uint32_t)m_intraModeCostForHighTextureMB[qp];
2711             // 16 DWs per QP value
2712             dataPtr += 16;
2713         }
2714 
2715         params->pOsInterface->pfnUnlockResource(
2716             params->pOsInterface,
2717             params->presBrcConstantDataBuffer);
2718     }
2719 
2720     return eStatus;
2721 }
2722 
InitKernelStateWP()2723 MOS_STATUS CodechalEncodeAvcEncG12::InitKernelStateWP()
2724 {
2725     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2726 
2727     CODECHAL_ENCODE_FUNCTION_ENTER;
2728 
2729     pWPKernelState = MOS_New(MHW_KERNEL_STATE);
2730     CODECHAL_ENCODE_CHK_NULL_RETURN(pWPKernelState);
2731 
2732     auto kernelStatePtr = pWPKernelState;
2733 
2734     uint8_t* kernelBinary;
2735     uint32_t kernelSize;
2736 
2737     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, m_kuid, &kernelBinary, &kernelSize));
2738 
2739     CODECHAL_KERNEL_HEADER currKrnHeader;
2740     CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnGetKernelHeaderAndSize(
2741         kernelBinary,
2742         ENC_WP,
2743         0,
2744         &currKrnHeader,
2745         &kernelSize));
2746     kernelStatePtr->KernelParams.iBTCount          = wpNumSurfaces;
2747     kernelStatePtr->KernelParams.iThreadCount      = m_renderEngineInterface->GetHwCaps()->dwMaxThreads;
2748     kernelStatePtr->KernelParams.iCurbeLength      = sizeof(CodechalEncodeAvcEncG12::WpCurbe);
2749     kernelStatePtr->KernelParams.iBlockWidth       = CODECHAL_MACROBLOCK_WIDTH;
2750     kernelStatePtr->KernelParams.iBlockHeight      = CODECHAL_MACROBLOCK_HEIGHT;
2751     kernelStatePtr->KernelParams.iIdCount          = 1;
2752     kernelStatePtr->KernelParams.iInlineDataLength = 0;
2753 
2754     kernelStatePtr->dwCurbeOffset        = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
2755     kernelStatePtr->KernelParams.pBinary = kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
2756     kernelStatePtr->KernelParams.iSize   = kernelSize;
2757     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
2758         m_stateHeapInterface,
2759         kernelStatePtr->KernelParams.iBTCount,
2760         &kernelStatePtr->dwSshSize,
2761         &kernelStatePtr->dwBindingTableSize));
2762 
2763     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr));
2764 
2765     return eStatus;
2766 }
2767 
InitBrcConstantBuffer(PCODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS params)2768 MOS_STATUS CodechalEncodeAvcEncG12::InitBrcConstantBuffer(PCODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS params)
2769 {
2770     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2771 
2772     CODECHAL_ENCODE_FUNCTION_ENTER;
2773 
2774     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2775     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pOsInterface);
2776     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams);
2777 
2778     uint8_t tableIdx               = params->wPictureCodingType - 1;
2779 
2780     if (tableIdx >= 3)
2781     {
2782         CODECHAL_ENCODE_ASSERTMESSAGE("Invalid input parameter.");
2783         return MOS_STATUS_INVALID_PARAMETER;
2784     }
2785 
2786     MOS_LOCK_PARAMS lockFlags;
2787     memset(&lockFlags, 0, sizeof(MOS_LOCK_PARAMS));
2788     lockFlags.WriteOnly = 1;
2789     auto dataPtr         = (uint8_t*)params->pOsInterface->pfnLockResource(
2790         params->pOsInterface,
2791         &params->sBrcConstantDataBuffer.OsResource,
2792         &lockFlags);
2793     CODECHAL_ENCODE_CHK_NULL_RETURN(dataPtr);
2794 
2795     memset(dataPtr, 0, params->sBrcConstantDataBuffer.dwWidth * params->sBrcConstantDataBuffer.dwHeight);
2796 
2797     // Fill surface with QP Adjustment table, Distortion threshold table, MaxFrame threshold table, Distortion QP Adjustment Table
2798     eStatus = MOS_SecureMemcpy(
2799         dataPtr,
2800         sizeof(m_QPAdjustmentDistThresholdMaxFrameThresholdIPB),
2801         (void*)m_QPAdjustmentDistThresholdMaxFrameThresholdIPB,
2802         sizeof(m_QPAdjustmentDistThresholdMaxFrameThresholdIPB));
2803     if (eStatus != MOS_STATUS_SUCCESS)
2804     {
2805         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2806         return eStatus;
2807     }
2808 
2809     dataPtr += sizeof(m_QPAdjustmentDistThresholdMaxFrameThresholdIPB);
2810 
2811     bool    blockBasedSkipEn        = params->dwMbEncBlockBasedSkipEn ? true : false;
2812     bool    transform_8x8_mode_flag = params->pPicParams->transform_8x8_mode_flag ? true : false;
2813 
2814     // Fill surface with Skip Threshold Table
2815     switch (params->wPictureCodingType)
2816     {
2817     case P_TYPE:
2818         eStatus = MOS_SecureMemcpy(
2819             dataPtr,
2820             m_brcConstantsurfaceEarlySkipTableSize,
2821             (void*)&SkipVal_P_Common[blockBasedSkipEn][transform_8x8_mode_flag][0],
2822             m_brcConstantsurfaceEarlySkipTableSize);
2823         if (eStatus != MOS_STATUS_SUCCESS)
2824         {
2825             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2826             return eStatus;
2827         }
2828         break;
2829     case B_TYPE:
2830         eStatus = MOS_SecureMemcpy(
2831             dataPtr,
2832             m_brcConstantsurfaceEarlySkipTableSize,
2833             (void*)&SkipVal_B_Common[blockBasedSkipEn][transform_8x8_mode_flag][0],
2834             m_brcConstantsurfaceEarlySkipTableSize);
2835         if (eStatus != MOS_STATUS_SUCCESS)
2836         {
2837             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2838             return eStatus;
2839         }
2840         break;
2841     default:
2842         // do nothing for I TYPE
2843         break;
2844     }
2845 
2846     if ((params->wPictureCodingType != I_TYPE) && (params->pAvcQCParams != nullptr) && (params->pAvcQCParams->NonFTQSkipThresholdLUTInput))
2847     {
2848         for (uint8_t qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
2849         {
2850             *(dataPtr + 1 + (qp * 2)) = (uint8_t)CalcSkipVal((params->dwMbEncBlockBasedSkipEn ? true : false),
2851                                                                             (params->pPicParams->transform_8x8_mode_flag ? true : false),
2852                                                                             params->pAvcQCParams->NonFTQSkipThresholdLUT[qp]);
2853         }
2854     }
2855 
2856     dataPtr += m_brcConstantsurfaceEarlySkipTableSize;
2857 
2858     // Fill surface with QP list
2859 
2860     // Initialize to -1 (0xff)
2861     memset(dataPtr, 0xff, m_brcConstantsurfaceQpList0);
2862     memset(dataPtr + m_brcConstantsurfaceQpList0 + m_brcConstantsurfaceQpList0Reserved,
2863            0xff, m_brcConstantsurfaceQpList1);
2864 
2865     switch (params->wPictureCodingType)
2866     {
2867     case B_TYPE:
2868         dataPtr += (m_brcConstantsurfaceQpList0 + m_brcConstantsurfaceQpList0Reserved);
2869 
2870         for (uint8_t refIdx = 0; refIdx <= params->pAvcSlcParams->num_ref_idx_l1_active_minus1; refIdx++)
2871         {
2872             CODEC_PICTURE refPic = params->pAvcSlcParams->RefPicList[LIST_1][refIdx];
2873             if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid)
2874             {
2875                 *(dataPtr + refIdx) = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx;
2876             }
2877         }
2878         dataPtr -= (m_brcConstantsurfaceQpList0 + m_brcConstantsurfaceQpList0Reserved);
2879     // break statement omitted intentionally
2880     case P_TYPE:
2881         for (uint8_t refIdx = 0; refIdx <= params->pAvcSlcParams->num_ref_idx_l0_active_minus1; refIdx++)
2882         {
2883             CODEC_PICTURE refPic = params->pAvcSlcParams->RefPicList[LIST_0][refIdx];
2884             if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid)
2885             {
2886                 *(dataPtr + refIdx) = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx;
2887             }
2888         }
2889         break;
2890     default:
2891         // do nothing for I type
2892         break;
2893     }
2894 
2895     dataPtr += (m_brcConstantsurfaceQpList0 + m_brcConstantsurfaceQpList0Reserved +
2896                 m_brcConstantsurfaceQpList1 + m_brcConstantsurfaceQpList1Reserved);
2897 
2898     // Fill surface with Mode cost and MV cost
2899     eStatus = MOS_SecureMemcpy(
2900         dataPtr,
2901         m_brcConstantsurfaceModeMvCostSize,
2902         (void*)ModeMvCost_Cm[tableIdx],
2903         m_brcConstantsurfaceModeMvCostSize);
2904     if (eStatus != MOS_STATUS_SUCCESS)
2905     {
2906         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2907         return eStatus;
2908     }
2909 
2910     // If old mode cost is used the update the table
2911     if (params->wPictureCodingType == I_TYPE && params->bOldModeCostEnable)
2912     {
2913         auto dataTemp = (uint32_t *)dataPtr;
2914         for (uint8_t qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
2915         {
2916             // Writing to DW0 in each sub-array of 16 DWs
2917             *dataTemp = (uint32_t)OldIntraModeCost_Cm_Common[qp];
2918             dataTemp += 16;
2919         }
2920     }
2921 
2922     if (params->pAvcQCParams)
2923     {
2924         for (uint8_t qp = 0; qp < CODEC_AVC_NUM_QP; qp++)
2925         {
2926             if (params->pAvcQCParams->FTQSkipThresholdLUTInput)
2927             {
2928                 // clang-format off
2929                 *(dataPtr + (qp * 32) + 24) =
2930                 *(dataPtr + (qp * 32) + 25) =
2931                 *(dataPtr + (qp * 32) + 27) =
2932                 *(dataPtr + (qp * 32) + 28) =
2933                 *(dataPtr + (qp * 32) + 29) =
2934                 *(dataPtr + (qp * 32) + 30) =
2935                 *(dataPtr + (qp * 32) + 31) = params->pAvcQCParams->FTQSkipThresholdLUT[qp];
2936                 // clang-format on
2937             }
2938         }
2939     }
2940 
2941     dataPtr += m_brcConstantsurfaceModeMvCostSize;
2942 
2943     // Fill surface with Refcost
2944     eStatus = MOS_SecureMemcpy(
2945         dataPtr,
2946         m_brcConstantsurfaceRefcostSize,
2947         (void*)&m_refCostMultiRefQp[tableIdx][0],
2948         m_brcConstantsurfaceRefcostSize);
2949     if (eStatus != MOS_STATUS_SUCCESS)
2950     {
2951         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2952         return eStatus;
2953     }
2954     dataPtr += m_brcConstantsurfaceRefcostSize;
2955 
2956     //Fill surface with Intra cost scaling Factor
2957     if (params->bAdaptiveIntraScalingEnable)
2958     {
2959         eStatus = MOS_SecureMemcpy(
2960             dataPtr,
2961             m_brcConstantsurfaceIntracostScalingFactor,
2962             (void*)&AdaptiveIntraScalingFactor_Cm_Common[0],
2963             m_brcConstantsurfaceIntracostScalingFactor);
2964         if (eStatus != MOS_STATUS_SUCCESS)
2965         {
2966             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2967             return eStatus;
2968         }
2969     }
2970     else
2971     {
2972         eStatus = MOS_SecureMemcpy(
2973             dataPtr,
2974             m_brcConstantsurfaceIntracostScalingFactor,
2975             (void*)&IntraScalingFactor_Cm_Common[0],
2976             m_brcConstantsurfaceIntracostScalingFactor);
2977         if (eStatus != MOS_STATUS_SUCCESS)
2978         {
2979             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2980             return eStatus;
2981         }
2982     }
2983 
2984     dataPtr += m_brcConstantsurfaceIntracostScalingFactor;
2985 
2986     eStatus = MOS_SecureMemcpy(
2987         dataPtr,
2988         m_brcConstantsurfaceLambdaSize,
2989         (void*)&m_lambdaData[0],
2990         m_brcConstantsurfaceLambdaSize);
2991     if (eStatus != MOS_STATUS_SUCCESS)
2992     {
2993         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2994         return eStatus;
2995     }
2996 
2997     dataPtr += m_brcConstantsurfaceLambdaSize;
2998 
2999     eStatus = MOS_SecureMemcpy(
3000         dataPtr,
3001         m_brcConstantsurfaceFtq25Size,
3002         (void*)&m_ftQ25[0],
3003         m_brcConstantsurfaceFtq25Size);
3004     if (eStatus != MOS_STATUS_SUCCESS)
3005     {
3006         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
3007         return eStatus;
3008     }
3009 
3010     params->pOsInterface->pfnUnlockResource(
3011         params->pOsInterface,
3012         &params->sBrcConstantDataBuffer.OsResource);
3013 
3014     return eStatus;
3015 }
3016 
SetCurbeAvcMbEnc(PCODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS params)3017 MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcMbEnc(PCODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS params)
3018 {
3019     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3020 
3021     CODECHAL_ENCODE_FUNCTION_ENTER;
3022 
3023     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
3024     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams);
3025     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
3026     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSlcParams);
3027 
3028     auto picParams = params->pPicParams;
3029     auto seqParams = params->pSeqParams;
3030     auto slcParams = params->pSlcParams;
3031 
3032     CODECHAL_ENCODE_ASSERT(seqParams->TargetUsage < NUM_TARGET_USAGE_MODES);
3033 
3034     uint8_t meMethod = (m_pictureCodingType == B_TYPE) ? m_bMeMethodGeneric[seqParams->TargetUsage] : m_meMethodGeneric[seqParams->TargetUsage];
3035     // set sliceQP to MAX_SLICE_QP for  MbEnc kernel, we can use it to verify whether QP is changed or not
3036     uint8_t sliceQP      = (params->bUseMbEncAdvKernel && params->bBrcEnabled) ? CODECHAL_ENCODE_AVC_MAX_SLICE_QP : picParams->pic_init_qp_minus26 + 26 + slcParams->slice_qp_delta;
3037     bool    framePicture = CodecHal_PictureIsFrame(picParams->CurrOriginalPic);
3038     bool    bottomField  = CodecHal_PictureIsBottomField(picParams->CurrOriginalPic);
3039 
3040     CodechalEncodeAvcEncG12::MbencCurbe::MBEncCurbeInitType curbeInitType;
3041     if (params->bMbEncIFrameDistEnabled)
3042     {
3043         curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeIDist;
3044     }
3045     else
3046     {
3047         switch (m_pictureCodingType)
3048         {
3049         case I_TYPE:
3050             if (framePicture)
3051             {
3052                 curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeIFrame;
3053             }
3054             else
3055             {
3056                 curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeIField;
3057             }
3058             break;
3059 
3060         case P_TYPE:
3061             if (framePicture)
3062             {
3063                 curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typePFrame;
3064             }
3065             else
3066             {
3067                 curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typePField;
3068             }
3069             break;
3070         case B_TYPE:
3071             if (framePicture)
3072             {
3073                 curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeBFrame;
3074             }
3075             else
3076             {
3077                 curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeBField;
3078             }
3079             break;
3080         default:
3081             CODECHAL_ENCODE_ASSERTMESSAGE("Invalid picture coding type.");
3082             eStatus = MOS_STATUS_UNKNOWN;
3083             return eStatus;
3084         }
3085     }
3086 
3087     CodechalEncodeAvcEncG12::MbencCurbe cmd;
3088     cmd.SetDefaultMbencCurbe(curbeInitType);
3089     // r1
3090     cmd.m_curbe.DW0.m_adaptiveEn =
3091         cmd.m_curbe.DW37.m_adaptiveEn = EnableAdaptiveSearch[seqParams->TargetUsage];
3092     cmd.m_curbe.DW0.m_t8x8FlagForInterEn =
3093         cmd.m_curbe.DW37.m_t8x8FlagForInterEn = picParams->transform_8x8_mode_flag;
3094     cmd.m_curbe.DW2.m_lenSP                   = MaxLenSP[seqParams->TargetUsage];
3095 
3096     cmd.m_curbe.DW1.m_extendedMvCostRange = bExtendedMvCostRange;
3097     cmd.m_curbe.DW36.m_mbInputEnable = bMbSpecificDataEnabled;
3098 
3099     cmd.m_curbe.DW38.m_lenSP = 0;  // MBZ
3100     cmd.m_curbe.DW3.m_srcAccess =
3101         cmd.m_curbe.DW3.m_refAccess = framePicture ? 0 : 1;
3102     if (m_pictureCodingType != I_TYPE && bFTQEnable)
3103     {
3104         if (m_pictureCodingType == P_TYPE)
3105         {
3106             cmd.m_curbe.DW3.m_fTEnable = FTQBasedSkip[seqParams->TargetUsage] & 0x01;
3107         }
3108         else  // B_TYPE
3109         {
3110             cmd.m_curbe.DW3.m_fTEnable = (FTQBasedSkip[seqParams->TargetUsage] >> 1) & 0x01;
3111         }
3112     }
3113     else
3114     {
3115         cmd.m_curbe.DW3.m_fTEnable = 0;
3116     }
3117     if (picParams->UserFlags.bDisableSubMBPartition)
3118     {
3119         cmd.m_curbe.DW3.m_subMbPartMask = CODECHAL_ENCODE_AVC_DISABLE_4X4_SUB_MB_PARTITION | CODECHAL_ENCODE_AVC_DISABLE_4X8_SUB_MB_PARTITION | CODECHAL_ENCODE_AVC_DISABLE_8X4_SUB_MB_PARTITION;
3120     }
3121     cmd.m_curbe.DW2.m_picWidth        = params->wPicWidthInMb;
3122     cmd.m_curbe.DW4.m_picHeightMinus1 = params->wFieldFrameHeightInMb - 1;
3123     cmd.m_curbe.DW4.m_fieldParityFlag = cmd.m_curbe.DW7.m_srcFieldPolarity = bottomField ? 1 : 0;
3124     cmd.m_curbe.DW4.m_enableFBRBypass                                              = bFBRBypassEnable;
3125     cmd.m_curbe.DW4.m_enableIntraCostScalingForStaticFrame                         = params->bStaticFrameDetectionEnabled;
3126     cmd.m_curbe.DW4.m_bCurFldIDR                                                   = framePicture ? 0 : (picParams->bIdrPic || m_firstFieldIdrPic);
3127     cmd.m_curbe.DW4.m_constrainedIntraPredFlag                                     = picParams->constrained_intra_pred_flag;
3128     cmd.m_curbe.DW4.m_hmeEnable                                                    = m_hmeEnabled;
3129     cmd.m_curbe.DW4.m_pictureType                                                  = m_pictureCodingType - 1;
3130     cmd.m_curbe.DW4.m_useActualRefQPValue                                          = m_hmeEnabled ? (m_multiRefDisableQPCheck[seqParams->TargetUsage] == 0) : false;
3131     cmd.m_curbe.DW5.m_sliceMbHeight                                                = params->usSliceHeight;
3132     cmd.m_curbe.DW7.m_intraPartMask                                                = picParams->transform_8x8_mode_flag ? 0 : 0x2;  // Disable 8x8 if flag is not set
3133 
3134     // r2
3135     if (params->bMbEncIFrameDistEnabled)
3136     {
3137         cmd.m_curbe.DW6.m_batchBufferEnd = 0;
3138     }
3139     else
3140     {
3141         uint8_t tableIdx = m_pictureCodingType - 1;
3142         eStatus          = MOS_SecureMemcpy(&(cmd.m_curbe.ModeMvCost), 8 * sizeof(uint32_t), ModeMvCost_Cm[tableIdx][sliceQP], 8 * sizeof(uint32_t));
3143         if (eStatus != MOS_STATUS_SUCCESS)
3144         {
3145             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
3146             return eStatus;
3147         }
3148 
3149         if (m_pictureCodingType == I_TYPE && bOldModeCostEnable)
3150         {
3151             // Old intra mode cost needs to be used if bOldModeCostEnable is 1
3152             cmd.m_curbe.ModeMvCost.DW8.m_value = OldIntraModeCost_Cm_Common[sliceQP];
3153         }
3154         else if (m_skipBiasAdjustmentEnable)
3155         {
3156             // Load different MvCost for P picture when SkipBiasAdjustment is enabled
3157             // No need to check for P picture as the flag is only enabled for P picture
3158             cmd.m_curbe.ModeMvCost.DW11.m_value = MvCost_PSkipAdjustment_Cm_Common[sliceQP];
3159         }
3160     }
3161 
3162     uint8_t tableIdx;
3163     // r3 & r4
3164     if (params->bMbEncIFrameDistEnabled)
3165     {
3166         cmd.m_curbe.SPDelta.DW31.m_intraComputeType = 1;
3167     }
3168     else
3169     {
3170         tableIdx = (m_pictureCodingType == B_TYPE) ? 1 : 0;
3171         eStatus  = MOS_SecureMemcpy(&(cmd.m_curbe.SPDelta), 16 * sizeof(uint32_t), m_encodeSearchPath[tableIdx][meMethod], 16 * sizeof(uint32_t));
3172         if (eStatus != MOS_STATUS_SUCCESS)
3173         {
3174             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
3175             return eStatus;
3176         }
3177     }
3178 
3179     // r5
3180     if (m_pictureCodingType == P_TYPE)
3181     {
3182         cmd.m_curbe.DW32.m_skipVal = SkipVal_P_Common
3183             [cmd.m_curbe.DW3.m_blockBasedSkipEnable]
3184             [picParams->transform_8x8_mode_flag]
3185             [sliceQP];
3186     }
3187     else if (m_pictureCodingType == B_TYPE)
3188     {
3189         cmd.m_curbe.DW32.m_skipVal = SkipVal_B_Common
3190             [cmd.m_curbe.DW3.m_blockBasedSkipEnable]
3191             [picParams->transform_8x8_mode_flag]
3192             [sliceQP];
3193     }
3194 
3195     cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeY = sliceQP;
3196     // m_qpPrimeCb and m_qpPrimeCr are not used by Kernel. Following settings are for CModel matching.
3197     cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeCb        = sliceQP;
3198     cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeCr        = sliceQP;
3199     cmd.m_curbe.ModeMvCost.DW13.m_targetSizeInWord = 0xff;  // hardcoded for BRC disabled
3200 
3201     if (bMultiPredEnable && (m_pictureCodingType != I_TYPE))
3202     {
3203         switch (m_multiPred[seqParams->TargetUsage])
3204         {
3205         case 0:  // Disable multipred for both P & B picture types
3206             cmd.m_curbe.DW32.m_multiPredL0Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3207             cmd.m_curbe.DW32.m_multiPredL1Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3208             break;
3209 
3210         case 1:  // Enable multipred for P pictures only
3211             cmd.m_curbe.DW32.m_multiPredL0Disable = (m_pictureCodingType == P_TYPE) ? CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE : CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3212             cmd.m_curbe.DW32.m_multiPredL1Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3213             break;
3214 
3215         case 2:  // Enable multipred for B pictures only
3216             cmd.m_curbe.DW32.m_multiPredL0Disable = (m_pictureCodingType == B_TYPE) ? CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE : CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3217             cmd.m_curbe.DW32.m_multiPredL1Disable = (m_pictureCodingType == B_TYPE) ? CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE : CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3218             break;
3219 
3220         case 3:  // Enable multipred for both P & B picture types
3221             cmd.m_curbe.DW32.m_multiPredL0Disable = CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE;
3222             cmd.m_curbe.DW32.m_multiPredL1Disable = (m_pictureCodingType == B_TYPE) ? CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE : CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3223             break;
3224         }
3225     }
3226     else
3227     {
3228         cmd.m_curbe.DW32.m_multiPredL0Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3229         cmd.m_curbe.DW32.m_multiPredL1Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3230     }
3231 
3232     if (!framePicture)
3233     {
3234         if (m_pictureCodingType != I_TYPE)
3235         {
3236             cmd.m_curbe.DW34.m_list0RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_0);
3237             cmd.m_curbe.DW34.m_list0RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_1);
3238             cmd.m_curbe.DW34.m_list0RefID2FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_2);
3239             cmd.m_curbe.DW34.m_list0RefID3FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_3);
3240             cmd.m_curbe.DW34.m_list0RefID4FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_4);
3241             cmd.m_curbe.DW34.m_list0RefID5FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_5);
3242             cmd.m_curbe.DW34.m_list0RefID6FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_6);
3243             cmd.m_curbe.DW34.m_list0RefID7FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_7);
3244         }
3245         if (m_pictureCodingType == B_TYPE)
3246         {
3247             cmd.m_curbe.DW34.m_list1RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_0);
3248             cmd.m_curbe.DW34.m_list1RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_1);
3249         }
3250     }
3251 
3252     if (m_adaptiveTransformDecisionEnabled)
3253     {
3254         if (m_pictureCodingType != I_TYPE)
3255         {
3256             cmd.m_curbe.DW34.m_enableAdaptiveTxDecision = true;
3257         }
3258         cmd.m_curbe.DW60.m_txDecisonThreshold = m_adaptiveTxDecisionThreshold;
3259     }
3260 
3261     if (m_adaptiveTransformDecisionEnabled || m_flatnessCheckEnabled)
3262     {
3263         cmd.m_curbe.DW60.m_mbTextureThreshold = m_mbTextureThreshold;
3264     }
3265 
3266     if (m_pictureCodingType == B_TYPE)
3267     {
3268         cmd.m_curbe.DW34.m_list1RefID0FrameFieldFlag = GetRefPicFieldFlag(params, LIST_1, CODECHAL_ENCODE_REF_ID_0);
3269         cmd.m_curbe.DW34.m_list1RefID1FrameFieldFlag = GetRefPicFieldFlag(params, LIST_1, CODECHAL_ENCODE_REF_ID_1);
3270         cmd.m_curbe.DW34.m_bDirectMode               = slcParams->direct_spatial_mv_pred_flag;
3271     }
3272 
3273     cmd.m_curbe.DW34.m_enablePerMBStaticCheck          = params->bStaticFrameDetectionEnabled;
3274     cmd.m_curbe.DW34.m_enableAdaptiveSearchWindowSize  = params->bApdatvieSearchWindowSizeEnabled;
3275     cmd.m_curbe.DW34.m_removeIntraRefreshOverlap       = picParams->bDisableRollingIntraRefreshOverlap;
3276     cmd.m_curbe.DW34.m_bOriginalBff                    = framePicture ? 0 : ((m_firstField && (bottomField)) || (!m_firstField && (!bottomField)));
3277     cmd.m_curbe.DW34.m_enableMBFlatnessChkOptimization = m_flatnessCheckEnabled;
3278     cmd.m_curbe.DW34.m_roiEnableFlag                   = params->bRoiEnabled;
3279     cmd.m_curbe.DW34.m_madEnableFlag                   = m_madEnabled;
3280     cmd.m_curbe.DW34.m_mbBrcEnable                     = bMbBrcEnabled || bMbQpDataEnabled;
3281     cmd.m_curbe.DW34.m_arbitraryNumMbsPerSlice         = m_arbitraryNumMbsInSlice;
3282     cmd.m_curbe.DW34.m_tqEnable                        = m_trellisQuantParams.dwTqEnabled;  //Enabled for KBL
3283     cmd.m_curbe.DW34.m_forceNonSkipMbEnable            = params->bMbDisableSkipMapEnabled;
3284     if (params->pAvcQCParams && !cmd.m_curbe.DW34.m_forceNonSkipMbEnable)  // ignore DisableEncSkipCheck if Mb Disable Skip Map is available
3285     {
3286         cmd.m_curbe.DW34.m_disableEncSkipCheck = params->pAvcQCParams->skipCheckDisable;
3287         }
3288         cmd.m_curbe.DW34.m_cqpFlag                    = !bBrcEnabled;  // 1 - Rate Control is CQP, 0 - Rate Control is BRC
3289         cmd.m_curbe.DW36.m_checkAllFractionalEnable   = bCAFEnable;
3290         cmd.m_curbe.DW38.m_refThreshold               = m_refThreshold;
3291         cmd.m_curbe.DW39.m_hmeRefWindowsCombThreshold = (m_pictureCodingType == B_TYPE) ? HMEBCombineLen[seqParams->TargetUsage] : HMECombineLen[seqParams->TargetUsage];
3292 
3293         // Default:2 used for MBBRC (MB QP Surface width and height are 4x downscaled picture in MB unit * 4  bytes)
3294         // 0 used for MBQP data surface (MB QP Surface width and height are same as the input picture size in MB unit * 1bytes)
3295         // BRC use split kernel, MB QP surface is same size as input picture
3296         cmd.m_curbe.DW47.m_mbQpReadFactor = (bMbBrcEnabled || bMbQpDataEnabled) ? 0 : 2;
3297 
3298         // Those fields are not really used for I_dist kernel
3299         if (params->bMbEncIFrameDistEnabled)
3300         {
3301             cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeY        = 0;
3302             cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeCb       = 0;
3303             cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeCr       = 0;
3304             cmd.m_curbe.DW33.m_intra16x16NonDCPredPenalty = 0;
3305             cmd.m_curbe.DW33.m_intra4x4NonDCPredPenalty   = 0;
3306             cmd.m_curbe.DW33.m_intra8x8NonDCPredPenalty   = 0;
3307     }
3308 
3309     //r6
3310     if (cmd.m_curbe.DW4.m_useActualRefQPValue)
3311     {
3312         cmd.m_curbe.DW44.m_actualQPValueForRefID0List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_0);
3313         cmd.m_curbe.DW44.m_actualQPValueForRefID1List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_1);
3314         cmd.m_curbe.DW44.m_actualQPValueForRefID2List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_2);
3315         cmd.m_curbe.DW44.m_actualQPValueForRefID3List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_3);
3316         cmd.m_curbe.DW45.m_actualQPValueForRefID4List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_4);
3317         cmd.m_curbe.DW45.m_actualQPValueForRefID5List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_5);
3318         cmd.m_curbe.DW45.m_actualQPValueForRefID6List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_6);
3319         cmd.m_curbe.DW45.m_actualQPValueForRefID7List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_7);
3320         cmd.m_curbe.DW46.m_actualQPValueForRefID0List1 = AVCGetQPValueFromRefList(params, LIST_1, CODECHAL_ENCODE_REF_ID_0);
3321         cmd.m_curbe.DW46.m_actualQPValueForRefID1List1 = AVCGetQPValueFromRefList(params, LIST_1, CODECHAL_ENCODE_REF_ID_1);
3322     }
3323 
3324     tableIdx           = m_pictureCodingType - 1;
3325     cmd.m_curbe.DW46.m_refCost = m_refCostMultiRefQp[tableIdx][sliceQP];
3326 
3327     // Picture Coding Type dependent parameters
3328     if (m_pictureCodingType == I_TYPE)
3329     {
3330         cmd.m_curbe.DW0.m_skipModeEn                  = 0;
3331         cmd.m_curbe.DW37.m_skipModeEn                 = 0;
3332         cmd.m_curbe.DW36.m_hmeCombineOverlap          = 0;
3333         cmd.m_curbe.DW47.m_intraCostSF                = 16;  // This is not used but recommended to set this to 16 by Kernel team
3334         cmd.m_curbe.DW34.m_enableDirectBiasAdjustment = 0;
3335     }
3336     else if (m_pictureCodingType == P_TYPE)
3337     {
3338         cmd.m_curbe.DW1.m_maxNumMVs                   = GetMaxMvsPer2Mb(seqParams->Level) / 2;
3339         cmd.m_curbe.DW3.m_bmeDisableFBR               = 1;
3340         cmd.m_curbe.DW5.m_refWidth                    = SearchX[seqParams->TargetUsage];
3341         cmd.m_curbe.DW5.m_refHeight                   = SearchY[seqParams->TargetUsage];
3342         cmd.m_curbe.DW7.m_nonSkipZMvAdded             = 1;
3343         cmd.m_curbe.DW7.m_nonSkipModeAdded            = 1;
3344         cmd.m_curbe.DW7.m_skipCenterMask              = 1;
3345         cmd.m_curbe.DW47.m_intraCostSF                = bAdaptiveIntraScalingEnable ? AdaptiveIntraScalingFactor_Cm_Common[sliceQP] : IntraScalingFactor_Cm_Common[sliceQP];
3346         cmd.m_curbe.DW47.m_maxVmvR                    = (framePicture) ? CodecHalAvcEncode_GetMaxMvLen(seqParams->Level) * 4 : (CodecHalAvcEncode_GetMaxMvLen(seqParams->Level) >> 1) * 4;
3347         cmd.m_curbe.DW36.m_hmeCombineOverlap          = 1;
3348         cmd.m_curbe.DW36.m_numRefIdxL0MinusOne        = bMultiPredEnable ? slcParams->num_ref_idx_l0_active_minus1 : 0;
3349         cmd.m_curbe.DW39.m_refWidth                   = SearchX[seqParams->TargetUsage];
3350         cmd.m_curbe.DW39.m_refHeight                  = SearchY[seqParams->TargetUsage];
3351         cmd.m_curbe.DW34.m_enableDirectBiasAdjustment = 0;
3352         if (params->pAvcQCParams)
3353         {
3354             cmd.m_curbe.DW34.m_enableGlobalMotionBiasAdjustment = params->pAvcQCParams->globalMotionBiasAdjustmentEnable;
3355         }
3356     }
3357     else
3358     {
3359         // B_TYPE
3360         cmd.m_curbe.DW1.m_maxNumMVs      = GetMaxMvsPer2Mb(seqParams->Level) / 2;
3361         cmd.m_curbe.DW1.m_biWeight       = m_biWeight;
3362         cmd.m_curbe.DW3.m_searchCtrl     = 7;
3363         cmd.m_curbe.DW3.m_skipType       = 1;
3364         cmd.m_curbe.DW5.m_refWidth       = BSearchX[seqParams->TargetUsage];
3365         cmd.m_curbe.DW5.m_refHeight      = BSearchY[seqParams->TargetUsage];
3366         cmd.m_curbe.DW7.m_skipCenterMask = 0xFF;
3367         cmd.m_curbe.DW47.m_intraCostSF =
3368             bAdaptiveIntraScalingEnable ? AdaptiveIntraScalingFactor_Cm_Common[sliceQP] : IntraScalingFactor_Cm_Common[sliceQP];
3369         cmd.m_curbe.DW47.m_maxVmvR           = (framePicture) ? CodecHalAvcEncode_GetMaxMvLen(seqParams->Level) * 4 : (CodecHalAvcEncode_GetMaxMvLen(seqParams->Level) >> 1) * 4;
3370         cmd.m_curbe.DW36.m_hmeCombineOverlap = 1;
3371         // Checking if the forward frame (List 1 index 0) is a short term reference
3372         {
3373             auto codecHalPic = params->pSlcParams->RefPicList[LIST_1][0];
3374             if (codecHalPic.PicFlags != PICTURE_INVALID &&
3375                 codecHalPic.FrameIdx != CODECHAL_ENCODE_AVC_INVALID_PIC_ID &&
3376                 params->pPicIdx[codecHalPic.FrameIdx].bValid)
3377             {
3378                 // Although its name is FWD, it actually means the future frame or the backward reference frame
3379                 cmd.m_curbe.DW36.m_isFwdFrameShortTermRef = CodecHal_PictureIsShortTermRef(params->pPicParams->RefFrameList[codecHalPic.FrameIdx]);
3380             }
3381             else
3382             {
3383                 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid backward reference frame.");
3384                 eStatus = MOS_STATUS_INVALID_PARAMETER;
3385                 return eStatus;
3386             }
3387         }
3388         cmd.m_curbe.DW36.m_numRefIdxL0MinusOne        = bMultiPredEnable ? slcParams->num_ref_idx_l0_active_minus1 : 0;
3389         cmd.m_curbe.DW36.m_numRefIdxL1MinusOne        = bMultiPredEnable ? slcParams->num_ref_idx_l1_active_minus1 : 0;
3390         cmd.m_curbe.DW39.m_refWidth                   = BSearchX[seqParams->TargetUsage];
3391         cmd.m_curbe.DW39.m_refHeight                  = BSearchY[seqParams->TargetUsage];
3392         cmd.m_curbe.DW40.m_distScaleFactorRefID0List0 = m_distScaleFactorList0[0];
3393         cmd.m_curbe.DW40.m_distScaleFactorRefID1List0 = m_distScaleFactorList0[1];
3394         cmd.m_curbe.DW41.m_distScaleFactorRefID2List0 = m_distScaleFactorList0[2];
3395         cmd.m_curbe.DW41.m_distScaleFactorRefID3List0 = m_distScaleFactorList0[3];
3396         cmd.m_curbe.DW42.m_distScaleFactorRefID4List0 = m_distScaleFactorList0[4];
3397         cmd.m_curbe.DW42.m_distScaleFactorRefID5List0 = m_distScaleFactorList0[5];
3398         cmd.m_curbe.DW43.m_distScaleFactorRefID6List0 = m_distScaleFactorList0[6];
3399         cmd.m_curbe.DW43.m_distScaleFactorRefID7List0 = m_distScaleFactorList0[7];
3400         if (params->pAvcQCParams)
3401         {
3402             cmd.m_curbe.DW34.m_enableDirectBiasAdjustment = params->pAvcQCParams->directBiasAdjustmentEnable;
3403             if (cmd.m_curbe.DW34.m_enableDirectBiasAdjustment)
3404             {
3405                 cmd.m_curbe.DW7.m_nonSkipModeAdded = 1;
3406                 cmd.m_curbe.DW7.m_nonSkipZMvAdded  = 1;
3407             }
3408 
3409             cmd.m_curbe.DW34.m_enableGlobalMotionBiasAdjustment = params->pAvcQCParams->globalMotionBiasAdjustmentEnable;
3410         }
3411     }
3412 
3413     *params->pdwBlockBasedSkipEn = cmd.m_curbe.DW3.m_blockBasedSkipEnable;
3414 
3415     if (picParams->EnableRollingIntraRefresh)
3416     {
3417         cmd.m_curbe.DW34.m_IntraRefreshEn = picParams->EnableRollingIntraRefresh;
3418 
3419         /* Multiple predictor should be completely disabled for the RollingI feature. This does not lead to much quality drop for P frames especially for TU as 1 */
3420         cmd.m_curbe.DW32.m_multiPredL0Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE;
3421 
3422         /* Pass the same IntraRefreshUnit to the kernel w/o the adjustment by -1, so as to have an overlap of one MB row or column of Intra macroblocks
3423         across one P frame to another P frame, as needed by the RollingI algo */
3424         if (ROLLING_I_SQUARE == picParams->EnableRollingIntraRefresh && RATECONTROL_CQP != seqParams->RateControlMethod)
3425         {
3426             /*BRC update kernel updates these CURBE to MBEnc*/
3427             cmd.m_curbe.DW4.m_enableIntraRefresh = false;
3428             cmd.m_curbe.DW34.m_IntraRefreshEn    = ROLLING_I_DISABLED;
3429             cmd.m_curbe.DW48.m_IntraRefreshMBx   = 0; /* MB column number */
3430             cmd.m_curbe.DW61.m_IntraRefreshMBy   = 0; /* MB row number */
3431         }
3432         else
3433         {
3434             cmd.m_curbe.DW4.m_enableIntraRefresh = true;
3435             cmd.m_curbe.DW34.m_IntraRefreshEn    = picParams->EnableRollingIntraRefresh;
3436             cmd.m_curbe.DW48.m_IntraRefreshMBx   = picParams->IntraRefreshMBx; /* MB column number */
3437             cmd.m_curbe.DW61.m_IntraRefreshMBy   = picParams->IntraRefreshMBy; /* MB row number */
3438         }
3439         cmd.m_curbe.DW48.m_IntraRefreshUnitInMBMinus1 = picParams->IntraRefreshUnitinMB;
3440         cmd.m_curbe.DW48.m_IntraRefreshQPDelta        = picParams->IntraRefreshQPDelta;
3441     }
3442     else
3443     {
3444         cmd.m_curbe.DW34.m_IntraRefreshEn = 0;
3445     }
3446 
3447     if (params->bRoiEnabled)
3448     {
3449         cmd.m_curbe.DW49.m_roi1XLeft   = picParams->ROI[0].Left;
3450         cmd.m_curbe.DW49.m_roi1YTop    = picParams->ROI[0].Top;
3451         cmd.m_curbe.DW50.m_roi1XRight  = picParams->ROI[0].Right;
3452         cmd.m_curbe.DW50.m_roi1YBottom = picParams->ROI[0].Bottom;
3453 
3454         cmd.m_curbe.DW51.m_roi2XLeft   = picParams->ROI[1].Left;
3455         cmd.m_curbe.DW51.m_roi2YTop    = picParams->ROI[1].Top;
3456         cmd.m_curbe.DW52.m_roi2XRight  = picParams->ROI[1].Right;
3457         cmd.m_curbe.DW52.m_roi2YBottom = picParams->ROI[1].Bottom;
3458 
3459         cmd.m_curbe.DW53.m_roi3XLeft   = picParams->ROI[2].Left;
3460         cmd.m_curbe.DW53.m_roi3YTop    = picParams->ROI[2].Top;
3461         cmd.m_curbe.DW54.m_roi3XRight  = picParams->ROI[2].Right;
3462         cmd.m_curbe.DW54.m_roi3YBottom = picParams->ROI[2].Bottom;
3463 
3464         cmd.m_curbe.DW55.m_roi4XLeft   = picParams->ROI[3].Left;
3465         cmd.m_curbe.DW55.m_roi4YTop    = picParams->ROI[3].Top;
3466         cmd.m_curbe.DW56.m_roi4XRight  = picParams->ROI[3].Right;
3467         cmd.m_curbe.DW56.m_roi4YBottom = picParams->ROI[3].Bottom;
3468 
3469         if (bBrcEnabled == false)
3470         {
3471             uint16_t numROI                                                 = picParams->NumROI;
3472             int8_t   priorityLevelOrDQp[CODECHAL_ENCODE_AVC_MAX_ROI_NUMBER] = {0};
3473 
3474             // cqp case
3475             for (unsigned int i = 0; i < numROI; i += 1)
3476             {
3477                 int8_t dQpRoi = picParams->ROI[i].PriorityLevelOrDQp;
3478 
3479                 // clip qp roi in order to have (qp + qpY) in range [0, 51]
3480                 priorityLevelOrDQp[i] = (int8_t)CodecHal_Clip3(-sliceQP, CODECHAL_ENCODE_AVC_MAX_SLICE_QP - sliceQP, dQpRoi);
3481             }
3482 
3483             cmd.m_curbe.DW57.m_roi1dQpPrimeY = priorityLevelOrDQp[0];
3484             cmd.m_curbe.DW57.m_roi2dQpPrimeY = priorityLevelOrDQp[1];
3485             cmd.m_curbe.DW57.m_roi3dQpPrimeY = priorityLevelOrDQp[2];
3486             cmd.m_curbe.DW57.m_roi4dQpPrimeY = priorityLevelOrDQp[3];
3487         }
3488         else
3489         {
3490             // kernel does not support BRC case
3491             cmd.m_curbe.DW34.m_roiEnableFlag = 0;
3492         }
3493     }
3494     else if (params->bDirtyRoiEnabled)
3495     {
3496         // enable Dirty Rect flag
3497         cmd.m_curbe.DW4.m_enableDirtyRect = true;
3498 
3499         cmd.m_curbe.DW49.m_roi1XLeft   = params->pPicParams->DirtyROI[0].Left;
3500         cmd.m_curbe.DW49.m_roi1YTop    = params->pPicParams->DirtyROI[0].Top;
3501         cmd.m_curbe.DW50.m_roi1XRight  = params->pPicParams->DirtyROI[0].Right;
3502         cmd.m_curbe.DW50.m_roi1YBottom = params->pPicParams->DirtyROI[0].Bottom;
3503 
3504         cmd.m_curbe.DW51.m_roi2XLeft   = params->pPicParams->DirtyROI[1].Left;
3505         cmd.m_curbe.DW51.m_roi2YTop    = params->pPicParams->DirtyROI[1].Top;
3506         cmd.m_curbe.DW52.m_roi2XRight  = params->pPicParams->DirtyROI[1].Right;
3507         cmd.m_curbe.DW52.m_roi2YBottom = params->pPicParams->DirtyROI[1].Bottom;
3508 
3509         cmd.m_curbe.DW53.m_roi3XLeft   = params->pPicParams->DirtyROI[2].Left;
3510         cmd.m_curbe.DW53.m_roi3YTop    = params->pPicParams->DirtyROI[2].Top;
3511         cmd.m_curbe.DW54.m_roi3XRight  = params->pPicParams->DirtyROI[2].Right;
3512         cmd.m_curbe.DW54.m_roi3YBottom = params->pPicParams->DirtyROI[2].Bottom;
3513 
3514         cmd.m_curbe.DW55.m_roi4XLeft   = params->pPicParams->DirtyROI[3].Left;
3515         cmd.m_curbe.DW55.m_roi4YTop    = params->pPicParams->DirtyROI[3].Top;
3516         cmd.m_curbe.DW56.m_roi4XRight  = params->pPicParams->DirtyROI[3].Right;
3517         cmd.m_curbe.DW56.m_roi4YBottom = params->pPicParams->DirtyROI[3].Bottom;
3518     }
3519 
3520     if (m_trellisQuantParams.dwTqEnabled)
3521     {
3522         // Lambda values for TQ
3523         if (m_pictureCodingType == I_TYPE)
3524         {
3525             cmd.m_curbe.DW58.m_value = TQ_LAMBDA_I_FRAME[sliceQP][0];
3526             cmd.m_curbe.DW59.m_value = TQ_LAMBDA_I_FRAME[sliceQP][1];
3527         }
3528         else if (m_pictureCodingType == P_TYPE)
3529         {
3530             cmd.m_curbe.DW58.m_value = TQ_LAMBDA_P_FRAME[sliceQP][0];
3531             cmd.m_curbe.DW59.m_value = TQ_LAMBDA_P_FRAME[sliceQP][1];
3532         }
3533         else
3534         {
3535             cmd.m_curbe.DW58.m_value = TQ_LAMBDA_B_FRAME[sliceQP][0];
3536             cmd.m_curbe.DW59.m_value = TQ_LAMBDA_B_FRAME[sliceQP][1];
3537         }
3538 
3539         MHW_VDBOX_AVC_SLICE_STATE sliceState;
3540         MOS_ZeroMemory(&sliceState, sizeof(sliceState));
3541         sliceState.pEncodeAvcSeqParams   = seqParams;
3542         sliceState.pEncodeAvcPicParams   = picParams;
3543         sliceState.pEncodeAvcSliceParams = slcParams;
3544 
3545         // check if Lambda is greater than max value
3546         CODECHAL_ENCODE_CHK_STATUS_RETURN(GetInterRounding(&sliceState));
3547 
3548         if (cmd.m_curbe.DW58.m_lambda8x8Inter > m_maxLambda)
3549         {
3550             cmd.m_curbe.DW58.m_lambda8x8Inter = 0xf000 + sliceState.dwRoundingValue;
3551         }
3552 
3553         if (cmd.m_curbe.DW58.m_lambda8x8Intra > m_maxLambda)
3554         {
3555             cmd.m_curbe.DW58.m_lambda8x8Intra = 0xf000 + m_defaultTrellisQuantIntraRounding;
3556         }
3557 
3558         // check if Lambda is greater than max value
3559         if (cmd.m_curbe.DW59.m_lambdaInter > m_maxLambda)
3560         {
3561             cmd.m_curbe.DW59.m_lambdaInter = 0xf000 + sliceState.dwRoundingValue;
3562         }
3563 
3564         if (cmd.m_curbe.DW59.m_lambdaIntra > m_maxLambda)
3565         {
3566             cmd.m_curbe.DW59.m_lambdaIntra = 0xf000 + m_defaultTrellisQuantIntraRounding;
3567         }
3568     }
3569 
3570     //IPCM QP and threshold
3571     cmd.m_curbe.DW62.m_IPCMQP0 = m_IPCMThresholdTable[0].QP;
3572     cmd.m_curbe.DW62.m_IPCMQP1 = m_IPCMThresholdTable[1].QP;
3573     cmd.m_curbe.DW62.m_IPCMQP2 = m_IPCMThresholdTable[2].QP;
3574     cmd.m_curbe.DW62.m_IPCMQP3 = m_IPCMThresholdTable[3].QP;
3575     cmd.m_curbe.DW63.m_IPCMQP4 = m_IPCMThresholdTable[4].QP;
3576 
3577     cmd.m_curbe.DW63.m_IPCMThresh0 = m_IPCMThresholdTable[0].Threshold;
3578     cmd.m_curbe.DW64.m_IPCMThresh1 = m_IPCMThresholdTable[1].Threshold;
3579     cmd.m_curbe.DW64.m_IPCMThresh2 = m_IPCMThresholdTable[2].Threshold;
3580     cmd.m_curbe.DW65.m_IPCMThresh3 = m_IPCMThresholdTable[3].Threshold;
3581     cmd.m_curbe.DW65.m_IPCMThresh4 = m_IPCMThresholdTable[4].Threshold;
3582 
3583     cmd.m_curbe.DW66.m_mbDataSurfIndex               = mbencMfcAvcPakObj;
3584     cmd.m_curbe.DW67.m_mvDataSurfIndex               = mbencIndMvData;
3585     cmd.m_curbe.DW68.m_IDistSurfIndex                = mbencBrcDistortion;
3586     cmd.m_curbe.DW69.m_srcYSurfIndex                 = mbencCurrY;
3587     cmd.m_curbe.DW70.m_mbSpecificDataSurfIndex       = mbencMbSpecificData;
3588     cmd.m_curbe.DW71.m_auxVmeOutSurfIndex            = mbencAuxVmeOut;
3589     cmd.m_curbe.DW72.m_currRefPicSelSurfIndex        = mbencRefpicselectL0;
3590     cmd.m_curbe.DW73.m_hmeMVPredFwdBwdSurfIndex      = mbencMvDataFromMe;
3591     cmd.m_curbe.DW74.m_hmeDistSurfIndex              = mbenc4xMeDistortion;
3592     cmd.m_curbe.DW75.m_sliceMapSurfIndex             = mbencSlicemapData;
3593     cmd.m_curbe.DW76.m_fwdFrmMBDataSurfIndex         = mbencFwdMbData;
3594     cmd.m_curbe.DW77.m_fwdFrmMVSurfIndex             = mbencFwdMvData;
3595     cmd.m_curbe.DW78.m_mbQPBuffer                    = mbencMbqp;
3596     cmd.m_curbe.DW79.m_mbBRCLut                      = mbencMbbrcConstData;
3597     cmd.m_curbe.DW80.m_vmeInterPredictionSurfIndex   = mbencVmeInterPredCurrPicIdx0;
3598     cmd.m_curbe.DW81.m_vmeInterPredictionMRSurfIndex = mbencVmeInterPredCurrPicIdx1;
3599     cmd.m_curbe.DW82.m_mbStatsSurfIndex              = mbencMbStats;
3600     cmd.m_curbe.DW83.m_madSurfIndex                  = mbencMadData;
3601     cmd.m_curbe.DW84.m_brcCurbeSurfIndex             = mbencBrcCurbeData;
3602     cmd.m_curbe.DW85.m_forceNonSkipMBmapSurface      = mbencForceNonskipMbMap;
3603     cmd.m_curbe.DW86.m_reservedIndex                 = mbEncAdv;
3604     cmd.m_curbe.DW87.m_staticDetectionCostTableIndex = mbencSfdCostTable;
3605     cmd.m_curbe.DW88.m_swScoreboardIndex             = mbencSwScoreboard;
3606 
3607     CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
3608         &cmd,
3609         params->pKernelState->dwCurbeOffset,
3610         sizeof(cmd)));
3611 
3612     CODECHAL_DEBUG_TOOL(
3613         CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateEncParam(
3614             meMethod,
3615             &cmd));
3616     )
3617 
3618     return eStatus;
3619 }
3620 
SetCurbeAvcWP(PCODECHAL_ENCODE_AVC_WP_CURBE_PARAMS params)3621 MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcWP(PCODECHAL_ENCODE_AVC_WP_CURBE_PARAMS params)
3622 {
3623     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3624     int16_t      weight;
3625 
3626     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
3627 
3628     auto slcParams   = m_avcSliceParams;
3629     auto seqParams   = m_avcSeqParam;
3630     auto kernelState = pWPKernelState;
3631     CODECHAL_ENCODE_ASSERT(seqParams->TargetUsage < NUM_TARGET_USAGE_MODES);
3632 
3633     CodechalEncodeAvcEncG12::WpCurbe cmd;
3634 
3635     /* Weights[i][j][k][m] is interpreted as:
3636 
3637     i refers to reference picture list 0 or 1;
3638     j refers to reference list entry 0-31;
3639     k refers to data for the luma (Y) component when it is 0, the Cb chroma component when it is 1 and the Cr chroma component when it is 2;
3640     m refers to weight when it is 0 and offset when it is 1
3641     */
3642     weight = slcParams->Weights[params->RefPicListIdx][params->WPIdx][0][0];
3643         cmd.m_wpCurbeCmd.DW0.m_defaultWeight = (weight << 6) >> (slcParams->luma_log2_weight_denom);
3644         cmd.m_wpCurbeCmd.DW0.m_defaultOffset = slcParams->Weights[params->RefPicListIdx][0][0][1];
3645 
3646         cmd.m_wpCurbeCmd.DW49.m_inputSurface  = wpInputRefSurface;
3647         cmd.m_wpCurbeCmd.DW50.m_outputSurface = wpOutputScaledSurface;
3648 
3649         CODECHAL_ENCODE_CHK_STATUS_RETURN(kernelState->m_dshRegion.AddData(
3650             &cmd,
3651             kernelState->dwCurbeOffset,
3652             sizeof(cmd)));
3653 
3654         return eStatus;
3655 }
3656 
SetCurbeAvcBrcInitReset(PCODECHAL_ENCODE_AVC_BRC_INIT_RESET_CURBE_PARAMS params)3657 MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcBrcInitReset(PCODECHAL_ENCODE_AVC_BRC_INIT_RESET_CURBE_PARAMS params)
3658 {
3659     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3660 
3661     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
3662 
3663     auto     seqParams = m_avcSeqParam;
3664     auto     vuiParams = m_avcVuiParams;
3665     uint32_t profileLevelMaxFrame;
3666     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_GetProfileLevelMaxFrameSize(
3667         seqParams,
3668         this,
3669         (uint32_t*)&profileLevelMaxFrame));
3670 
3671     BrcInitResetCurbe curbe;
3672     curbe.m_brcInitResetCurbeCmd.m_dw0.m_profileLevelMaxFrame = profileLevelMaxFrame;
3673     curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits    = seqParams->InitVBVBufferFullnessInBit;
3674     curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits        = seqParams->VBVBufferSizeInBit;
3675     curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate       = seqParams->TargetBitRate;
3676     curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate           = seqParams->MaxBitRate;
3677     curbe.m_brcInitResetCurbeCmd.m_dw8.m_gopP =
3678         (seqParams->GopRefDist) ? ((seqParams->GopPicSize - 1) / seqParams->GopRefDist) : 0;
3679     curbe.m_brcInitResetCurbeCmd.m_dw9.m_gopB                = seqParams->GopPicSize - 1 - curbe.m_brcInitResetCurbeCmd.m_dw8.m_gopP;
3680     curbe.m_brcInitResetCurbeCmd.m_dw9.m_frameWidthInBytes   = m_frameWidth;
3681     curbe.m_brcInitResetCurbeCmd.m_dw10.m_frameHeightInBytes = m_frameHeight;
3682     curbe.m_brcInitResetCurbeCmd.m_dw12.m_noSlices           = m_numSlices;
3683 
3684     curbe.m_brcInitResetCurbeCmd.m_dw32.m_surfaceIndexHistorybuffer    = CODECHAL_ENCODE_AVC_BRC_INIT_RESET_HISTORY;
3685     curbe.m_brcInitResetCurbeCmd.m_dw33.m_surfaceIndexDistortionbuffer = CODECHAL_ENCODE_AVC_BRC_INIT_RESET_DISTORTION;
3686 
3687     // if VUI present, VUI data has high priority
3688     if (seqParams->vui_parameters_present_flag && seqParams->RateControlMethod != RATECONTROL_AVBR)
3689     {
3690         curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate =
3691             ((vuiParams->bit_rate_value_minus1[0] + 1) << (6 + vuiParams->bit_rate_scale));
3692 
3693         if (seqParams->RateControlMethod == RATECONTROL_CBR)
3694         {
3695             curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate = curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate;
3696         }
3697     }
3698 
3699     curbe.m_brcInitResetCurbeCmd.m_dw6.m_frameRateM = seqParams->FramesPer100Sec;
3700     curbe.m_brcInitResetCurbeCmd.m_dw7.m_frameRateD = 100;
3701     curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag    = (CodecHal_PictureIsFrame(m_currOriginalPic)) ? 0 : CODECHAL_ENCODE_BRCINIT_FIELD_PIC;
3702     // MBBRC should be skipped when BRC ROI is on
3703     curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag |= (bMbBrcEnabled && !bBrcRoiEnabled) ? 0 : CODECHAL_ENCODE_BRCINIT_DISABLE_MBBRC;
3704 
3705     if (seqParams->RateControlMethod == RATECONTROL_CBR)
3706     {
3707         curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate = curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate;
3708         curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag    = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISCBR;
3709     }
3710     else if (seqParams->RateControlMethod == RATECONTROL_VBR)
3711     {
3712         if (curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate < curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate)
3713         {
3714             curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate = curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate;  // Use max bit rate for HRD compliance
3715         }
3716         curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISVBR;
3717     }
3718     else if (seqParams->RateControlMethod == RATECONTROL_AVBR)
3719     {
3720         curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISAVBR;
3721         // For AVBR, max bitrate = target bitrate,
3722         curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate = curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate;
3723     }
3724     else if (seqParams->RateControlMethod == RATECONTROL_ICQ)
3725     {
3726         curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISICQ;
3727         curbe.m_brcInitResetCurbeCmd.m_dw23.m_aCQP   = seqParams->ICQQualityFactor;
3728     }
3729     else if (seqParams->RateControlMethod == RATECONTROL_VCM)
3730     {
3731         curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISVCM;
3732     }
3733     else if (seqParams->RateControlMethod == RATECONTROL_QVBR)
3734     {
3735         if (curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate < curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate)
3736         {
3737             curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate = curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate;  // Use max bit rate for HRD compliance
3738         }
3739         curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISQVBR;
3740         // use ICQQualityFactor to determine the larger Qp for each MB
3741         curbe.m_brcInitResetCurbeCmd.m_dw23.m_aCQP = seqParams->ICQQualityFactor;
3742     }
3743 
3744     curbe.m_brcInitResetCurbeCmd.m_dw10.m_avbrAccuracy    = usAVBRAccuracy;
3745     curbe.m_brcInitResetCurbeCmd.m_dw11.m_avbrConvergence = usAVBRConvergence;
3746 
3747     // Set dynamic thresholds
3748     double inputBitsPerFrame =
3749         ((double)(curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate) * (double)(curbe.m_brcInitResetCurbeCmd.m_dw7.m_frameRateD) /
3750             (double)(curbe.m_brcInitResetCurbeCmd.m_dw6.m_frameRateM));
3751     if (CodecHal_PictureIsField(m_currOriginalPic))
3752     {
3753         inputBitsPerFrame *= 0.5;
3754     }
3755 
3756     if (curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits == 0)
3757     {
3758         curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits = (uint32_t)inputBitsPerFrame * 4;
3759     }
3760 
3761     if (curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits == 0)
3762     {
3763         curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = 7 * curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits / 8;
3764     }
3765     if (curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits < (uint32_t)(inputBitsPerFrame * 2))
3766     {
3767         curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = (uint32_t)(inputBitsPerFrame * 2);
3768     }
3769     if (curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits > curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits)
3770     {
3771         curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits;
3772     }
3773 
3774     if (seqParams->RateControlMethod == RATECONTROL_AVBR)
3775     {
3776         // For AVBR, Buffer size =  2*Bitrate, InitVBV = 0.75 * BufferSize
3777         curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits     = 2 * seqParams->TargetBitRate;
3778         curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = (uint32_t)(0.75 * curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits);
3779     }
3780 
3781     double bpsRatio = inputBitsPerFrame / ((double)(curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits) / 30);
3782     bpsRatio        = (bpsRatio < 0.1) ? 0.1 : (bpsRatio > 3.5) ? 3.5 : bpsRatio;
3783 
3784     curbe.m_brcInitResetCurbeCmd.m_dw16.m_deviationThreshold0ForPandB = (uint32_t)(-50 * pow(0.90, bpsRatio));
3785     curbe.m_brcInitResetCurbeCmd.m_dw16.m_deviationThreshold1ForPandB = (uint32_t)(-50 * pow(0.66, bpsRatio));
3786     curbe.m_brcInitResetCurbeCmd.m_dw16.m_deviationThreshold2ForPandB = (uint32_t)(-50 * pow(0.46, bpsRatio));
3787     curbe.m_brcInitResetCurbeCmd.m_dw16.m_deviationThreshold3ForPandB = (uint32_t)(-50 * pow(0.3, bpsRatio));
3788     curbe.m_brcInitResetCurbeCmd.m_dw17.m_deviationThreshold4ForPandB = (uint32_t)(50 * pow(0.3, bpsRatio));
3789     curbe.m_brcInitResetCurbeCmd.m_dw17.m_deviationThreshold5ForPandB = (uint32_t)(50 * pow(0.46, bpsRatio));
3790     curbe.m_brcInitResetCurbeCmd.m_dw17.m_deviationThreshold6ForPandB = (uint32_t)(50 * pow(0.7, bpsRatio));
3791     curbe.m_brcInitResetCurbeCmd.m_dw17.m_deviationThreshold7ForPandB = (uint32_t)(50 * pow(0.9, bpsRatio));
3792     curbe.m_brcInitResetCurbeCmd.m_dw18.m_deviationThreshold0ForVBR   = (uint32_t)(-50 * pow(0.9, bpsRatio));
3793     curbe.m_brcInitResetCurbeCmd.m_dw18.m_deviationThreshold1ForVBR   = (uint32_t)(-50 * pow(0.7, bpsRatio));
3794     curbe.m_brcInitResetCurbeCmd.m_dw18.m_deviationThreshold2ForVBR   = (uint32_t)(-50 * pow(0.5, bpsRatio));
3795     curbe.m_brcInitResetCurbeCmd.m_dw18.m_deviationThreshold3ForVBR   = (uint32_t)(-50 * pow(0.3, bpsRatio));
3796     curbe.m_brcInitResetCurbeCmd.m_dw19.m_deviationThreshold4ForVBR   = (uint32_t)(100 * pow(0.4, bpsRatio));
3797     curbe.m_brcInitResetCurbeCmd.m_dw19.m_deviationThreshold5ForVBR   = (uint32_t)(100 * pow(0.5, bpsRatio));
3798     curbe.m_brcInitResetCurbeCmd.m_dw19.m_deviationThreshold6ForVBR   = (uint32_t)(100 * pow(0.75, bpsRatio));
3799     curbe.m_brcInitResetCurbeCmd.m_dw19.m_deviationThreshold7ForVBR   = (uint32_t)(100 * pow(0.9, bpsRatio));
3800     curbe.m_brcInitResetCurbeCmd.m_dw20.m_deviationThreshold0ForI     = (uint32_t)(-50 * pow(0.8, bpsRatio));
3801     curbe.m_brcInitResetCurbeCmd.m_dw20.m_deviationThreshold1ForI     = (uint32_t)(-50 * pow(0.6, bpsRatio));
3802     curbe.m_brcInitResetCurbeCmd.m_dw20.m_deviationThreshold2ForI     = (uint32_t)(-50 * pow(0.34, bpsRatio));
3803     curbe.m_brcInitResetCurbeCmd.m_dw20.m_deviationThreshold3ForI     = (uint32_t)(-50 * pow(0.2, bpsRatio));
3804     curbe.m_brcInitResetCurbeCmd.m_dw21.m_deviationThreshold4ForI     = (uint32_t)(50 * pow(0.2, bpsRatio));
3805     curbe.m_brcInitResetCurbeCmd.m_dw21.m_deviationThreshold5ForI     = (uint32_t)(50 * pow(0.4, bpsRatio));
3806     curbe.m_brcInitResetCurbeCmd.m_dw21.m_deviationThreshold6ForI     = (uint32_t)(50 * pow(0.66, bpsRatio));
3807     curbe.m_brcInitResetCurbeCmd.m_dw21.m_deviationThreshold7ForI     = (uint32_t)(50 * pow(0.9, bpsRatio));
3808 
3809     curbe.m_brcInitResetCurbeCmd.m_dw22.m_slidingWindowSize = dwSlidingWindowSize;
3810 
3811     if (bBrcInit)
3812     {
3813         *params->pdBrcInitCurrentTargetBufFullInBits = curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits;
3814     }
3815 
3816     *params->pdwBrcInitResetBufSizeInBits    = curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits;
3817     *params->pdBrcInitResetInputBitsPerFrame = inputBitsPerFrame;
3818 
3819     CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
3820         &curbe.m_brcInitResetCurbeCmd,
3821         params->pKernelState->dwCurbeOffset,
3822         sizeof(curbe.m_brcInitResetCurbeCmd)));
3823 
3824     CODECHAL_DEBUG_TOOL(
3825         CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateBrcInitParam(
3826             &curbe.m_brcInitResetCurbeCmd));
3827     )
3828 
3829     return eStatus;
3830 }
3831 
SetCurbeAvcFrameBrcUpdate(PCODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS params)3832 MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcFrameBrcUpdate(PCODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS params)
3833 {
3834     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3835 
3836     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
3837     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);
3838 
3839     CodechalEncodeAvcEncG12::FrameBrcUpdateCurbe cmd;
3840     cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_targetSizeFlag = 0;
3841     if (*params->pdBrcInitCurrentTargetBufFullInBits > (double)dwBrcInitResetBufSizeInBits)
3842     {
3843         *params->pdBrcInitCurrentTargetBufFullInBits -= (double)dwBrcInitResetBufSizeInBits;
3844         cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_targetSizeFlag = 1;
3845     }
3846 
3847     // skipped frame handling
3848     if (params->dwNumSkipFrames)
3849     {
3850         // pass num/size of skipped frames to update BRC
3851         cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_numSkipFrames  = params->dwNumSkipFrames;
3852         cmd.m_frameBrcUpdateCurbeCmd.m_dw7.m_sizeSkipFrames = params->dwSizeSkipFrames;
3853 
3854         // account for skipped frame in calculating CurrentTargetBufFullInBits
3855         *params->pdBrcInitCurrentTargetBufFullInBits += dBrcInitResetInputBitsPerFrame * params->dwNumSkipFrames;
3856     }
3857 
3858     cmd.m_frameBrcUpdateCurbeCmd.m_dw0.m_targetSize       = (uint32_t)(*params->pdBrcInitCurrentTargetBufFullInBits);
3859     cmd.m_frameBrcUpdateCurbeCmd.m_dw1.m_frameNumber      = m_storeData - 1;
3860     cmd.m_frameBrcUpdateCurbeCmd.m_dw2.m_sizeofPicHeaders = m_headerBytesInserted << 3;  // kernel uses how many bits instead of bytes
3861     cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_currFrameType =
3862         ((m_pictureCodingType - 2) < 0) ? 2 : (m_pictureCodingType - 2);
3863     cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_brcFlag =
3864         (CodecHal_PictureIsTopField(m_currOriginalPic)) ? brcUpdateIsField : ((CodecHal_PictureIsBottomField(m_currOriginalPic)) ? (brcUpdateIsField | brcUpdateIsBottomField) : 0);
3865     cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_brcFlag |= (m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef) ? brcUpdateIsReference : 0;
3866 
3867     if (bMultiRefQpEnabled)
3868     {
3869         cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_brcFlag |= brcUpdateIsActualQp;
3870         cmd.m_frameBrcUpdateCurbeCmd.m_dw14.m_qpIndexOfCurPic = m_currOriginalPic.FrameIdx;
3871     }
3872 
3873     auto seqParams = m_avcSeqParam;
3874     auto picParams = m_avcPicParam;
3875     auto slcParams = m_avcSliceParams;
3876 
3877     cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_brcFlag |= seqParams->bAutoMaxPBFrameSizeForSceneChange ? brcUpdateAutoPbFrameSize : 0;
3878     cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_maxNumPAKs           = m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses();
3879     cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_minimumQP            = params->ucMinQP;
3880     cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_maximumQP            = params->ucMaxQP;
3881     cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_enableForceToSkip    = (bForceToSkipEnable && !m_avcPicParam->bDisableFrameSkip);
3882     cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_enableSlidingWindow  = (seqParams->FrameSizeTolerance == EFRAMESIZETOL_LOW);
3883     cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_enableExtremLowDelay = (seqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW);
3884     cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_disableVarCompute    = bBRCVarCompuBypass;
3885 
3886     *params->pdBrcInitCurrentTargetBufFullInBits += dBrcInitResetInputBitsPerFrame;
3887 
3888     if (seqParams->RateControlMethod == RATECONTROL_AVBR)
3889     {
3890         cmd.m_frameBrcUpdateCurbeCmd.m_dw3.m_startGAdjFrame0       = (uint32_t)((10 * usAVBRConvergence) / (double)150);
3891         cmd.m_frameBrcUpdateCurbeCmd.m_dw3.m_startGAdjFrame1       = (uint32_t)((50 * usAVBRConvergence) / (double)150);
3892         cmd.m_frameBrcUpdateCurbeCmd.m_dw4.m_startGAdjFrame2       = (uint32_t)((100 * usAVBRConvergence) / (double)150);
3893         cmd.m_frameBrcUpdateCurbeCmd.m_dw4.m_startGAdjFrame3       = (uint32_t)((150 * usAVBRConvergence) / (double)150);
3894         cmd.m_frameBrcUpdateCurbeCmd.m_dw11.m_gRateRatioThreshold0 = (uint32_t)((100 - (usAVBRAccuracy / (double)30) * (100 - 40)));
3895         cmd.m_frameBrcUpdateCurbeCmd.m_dw11.m_gRateRatioThreshold1 = (uint32_t)((100 - (usAVBRAccuracy / (double)30) * (100 - 75)));
3896         cmd.m_frameBrcUpdateCurbeCmd.m_dw12.m_gRateRatioThreshold2 = (uint32_t)((100 - (usAVBRAccuracy / (double)30) * (100 - 97)));
3897         cmd.m_frameBrcUpdateCurbeCmd.m_dw12.m_gRateRatioThreshold3 = (uint32_t)((100 + (usAVBRAccuracy / (double)30) * (103 - 100)));
3898         cmd.m_frameBrcUpdateCurbeCmd.m_dw12.m_gRateRatioThreshold4 = (uint32_t)((100 + (usAVBRAccuracy / (double)30) * (125 - 100)));
3899         cmd.m_frameBrcUpdateCurbeCmd.m_dw12.m_gRateRatioThreshold5 = (uint32_t)((100 + (usAVBRAccuracy / (double)30) * (160 - 100)));
3900     }
3901 
3902     cmd.m_frameBrcUpdateCurbeCmd.m_dw15.m_enableROI = params->ucEnableROI;
3903 
3904     MHW_VDBOX_AVC_SLICE_STATE sliceState;
3905     MOS_ZeroMemory(&sliceState, sizeof(sliceState));
3906     sliceState.pEncodeAvcSeqParams   = seqParams;
3907     sliceState.pEncodeAvcPicParams   = picParams;
3908     sliceState.pEncodeAvcSliceParams = slcParams;
3909 
3910     CODECHAL_ENCODE_CHK_STATUS_RETURN(GetInterRounding(&sliceState));
3911 
3912     cmd.m_frameBrcUpdateCurbeCmd.m_dw15.m_roundingIntra = 5;
3913     cmd.m_frameBrcUpdateCurbeCmd.m_dw15.m_roundingInter = sliceState.dwRoundingValue;
3914 
3915     uint32_t profileLevelMaxFrame;
3916     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_GetProfileLevelMaxFrameSize(
3917         seqParams,
3918         this,
3919         (uint32_t*)&profileLevelMaxFrame));
3920 
3921     cmd.m_frameBrcUpdateCurbeCmd.m_dw19.m_userMaxFrame = profileLevelMaxFrame;
3922 
3923     cmd.m_frameBrcUpdateCurbeCmd.m_dw24.m_surfaceIndexBRCHistorybuffer                  = frameBrcUpdateHistory;
3924     cmd.m_frameBrcUpdateCurbeCmd.m_dw25.m_surfaceIndexPreciousPAKStatisticsOutputbuffer = frameBrcUpdatePakStatisticsOutput;
3925     cmd.m_frameBrcUpdateCurbeCmd.m_dw26.m_surfaceIndexAVCIMGStateInputbuffer            = frameBrcUpdateImageStateRead;
3926     cmd.m_frameBrcUpdateCurbeCmd.m_dw27.m_surfaceIndexAVCIMGStateOutputbuffer           = frameBrcUpdateImageStateWrite;
3927     cmd.m_frameBrcUpdateCurbeCmd.m_dw28.m_surfaceIndexAVC_Encbuffer                     = frameBrcUpdateMbencCurbeWrite;
3928     cmd.m_frameBrcUpdateCurbeCmd.m_dw29.m_surfaceIndexAVCDistortionbuffer               = frameBrcUpdateDistortion;
3929     cmd.m_frameBrcUpdateCurbeCmd.m_dw30.m_surfaceIndexBRCConstdatabuffer                = frameBrcUpdateConstantData;
3930     cmd.m_frameBrcUpdateCurbeCmd.m_dw31.m_surfaceIndexMBStatsbuffer                     = frameBrcUpdateMbStat;
3931     cmd.m_frameBrcUpdateCurbeCmd.m_dw32.m_surfaceIndexMotionVectorbuffer                = frameBrcUpdateMvStat;
3932     auto pStateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface;
3933     CODECHAL_ENCODE_CHK_NULL_RETURN(pStateHeapInterface);
3934 
3935     CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
3936         &cmd.m_frameBrcUpdateCurbeCmd,
3937         params->pKernelState->dwCurbeOffset,
3938         sizeof(cmd.m_frameBrcUpdateCurbeCmd)));
3939 
3940     CODECHAL_DEBUG_TOOL(
3941         CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateBrcUpdateParam(
3942             &cmd.m_frameBrcUpdateCurbeCmd));
3943     )
3944 
3945     return eStatus;
3946 }
3947 
SetCurbeAvcMbBrcUpdate(PCODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS params)3948 MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcMbBrcUpdate(PCODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS params)
3949 {
3950     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3951 
3952     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
3953     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);
3954 
3955     CodechalEncodeAvcEncG12::MbBrcUpdateCurbe curbe;
3956 
3957     // BRC curbe requires: 2 for I-frame, 0 for P-frame, 1 for B-frame
3958     curbe.m_mbBrcUpdateCurbeCmd.DW0.m_currFrameType = (m_pictureCodingType + 1) % 3;
3959     if (params->ucEnableROI)
3960     {
3961         if (bROIValueInDeltaQP)
3962         {
3963             curbe.m_mbBrcUpdateCurbeCmd.DW0.m_enableROI = 2;  // 1-Enabled ROI priority, 2-Enable ROI QP Delta,  0- disabled
3964             curbe.m_mbBrcUpdateCurbeCmd.DW0.m_roiRatio  = 0;
3965         }
3966         else
3967         {
3968             curbe.m_mbBrcUpdateCurbeCmd.DW0.m_enableROI = 1;  // 1-Enabled ROI priority, 2-Enable ROI QP Delta,  0- disabled
3969 
3970             uint32_t roiSize  = 0;
3971             uint32_t roiRatio = 0;
3972 
3973             for (uint32_t i = 0; i < m_avcPicParam->NumROI; ++i)
3974             {
3975                 CODECHAL_ENCODE_VERBOSEMESSAGE("ROI[%d] = {%d, %d, %d, %d} {%d}, size = %d",
3976                     i,
3977                     m_avcPicParam->ROI[i].Left,
3978                     m_avcPicParam->ROI[i].Top,
3979                     m_avcPicParam->ROI[i].Bottom,
3980                     m_avcPicParam->ROI[i].Right,
3981                     m_avcPicParam->ROI[i].PriorityLevelOrDQp,
3982                     (CODECHAL_MACROBLOCK_HEIGHT * MOS_ABS(m_avcPicParam->ROI[i].Top -
3983                                                           m_avcPicParam->ROI[i].Bottom)) *
3984                         (CODECHAL_MACROBLOCK_WIDTH * MOS_ABS(m_avcPicParam->ROI[i].Right - m_avcPicParam->ROI[i].Left)));
3985                 roiSize += (CODECHAL_MACROBLOCK_HEIGHT * MOS_ABS(m_avcPicParam->ROI[i].Top - m_avcPicParam->ROI[i].Bottom)) *
3986                            (CODECHAL_MACROBLOCK_WIDTH * MOS_ABS(m_avcPicParam->ROI[i].Right - m_avcPicParam->ROI[i].Left));
3987             }
3988 
3989             if (roiSize)
3990             {
3991                 uint32_t numMBs = m_picWidthInMb * m_picHeightInMb;
3992                 roiRatio        = 2 * (numMBs * 256 / roiSize - 1);
3993                 roiRatio        = MOS_MIN(51, roiRatio);  // clip QP from 0-51
3994             }
3995             CODECHAL_ENCODE_VERBOSEMESSAGE("m_roiRatio = %d", roiRatio);
3996             curbe.m_mbBrcUpdateCurbeCmd.DW0.m_roiRatio = roiRatio;
3997         }
3998     }
3999     else
4000     {
4001         curbe.m_mbBrcUpdateCurbeCmd.DW0.m_roiRatio = 0;
4002     }
4003 
4004     curbe.m_mbBrcUpdateCurbeCmd.DW8.m_historyBufferIndex        = mbBrcUpdateHistory;
4005     curbe.m_mbBrcUpdateCurbeCmd.DW9.m_mbqpBufferIndex           = mbBrcUpdateMbQp;
4006     curbe.m_mbBrcUpdateCurbeCmd.DW10.m_roiBufferIndex           = mbBrcUpdateRoi;
4007     curbe.m_mbBrcUpdateCurbeCmd.DW11.m_mbStatisticalBufferIndex = mbBrcUpdateMbStat;
4008     auto pStateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface;
4009     CODECHAL_ENCODE_CHK_NULL_RETURN(pStateHeapInterface);
4010 
4011     CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
4012         &curbe,
4013         params->pKernelState->dwCurbeOffset,
4014         sizeof(curbe)));
4015 
4016     return eStatus;
4017 }
4018 
UserFeatureKeyReport()4019 MOS_STATUS CodechalEncodeAvcEncG12::UserFeatureKeyReport()
4020 {
4021     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4022 
4023     CODECHAL_ENCODE_FUNCTION_ENTER;
4024 
4025     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcEnc::UserFeatureKeyReport());
4026 
4027 #if (_DEBUG || _RELEASE_INTERNAL)
4028 
4029     // VE2.0 Reporting
4030     CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENABLE_ENCODE_VE_CTXSCHEDULING_ID, MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface), m_osInterface->pOsContext);
4031 
4032 #endif // _DEBUG || _RELEASE_INTERNAL
4033     return eStatus;
4034 }
4035 
SendAvcMbEncSurfaces(PMOS_COMMAND_BUFFER cmdBuffer,PCODECHAL_ENCODE_AVC_MBENC_SURFACE_PARAMS params)4036 MOS_STATUS CodechalEncodeAvcEncG12::SendAvcMbEncSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_MBENC_SURFACE_PARAMS params)
4037 {
4038     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4039 
4040     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4041     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
4042     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSlcParams);
4043     CODECHAL_ENCODE_CHK_NULL_RETURN(params->ppRefList);
4044     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pCurrOriginalPic);
4045     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pCurrReconstructedPic);
4046     CODECHAL_ENCODE_CHK_NULL_RETURN(params->psCurrPicSurface);
4047     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcPicIdx);
4048     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pMbEncBindingTable);
4049     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);
4050 
4051     bool currFieldPicture = CodecHal_PictureIsField(*(params->pCurrOriginalPic)) ? 1 : 0;
4052     bool currBottomField = CodecHal_PictureIsBottomField(*(params->pCurrOriginalPic)) ? 1 : 0;
4053     uint32_t refMbCodeBottomFieldOffset =
4054         params->dwFrameFieldHeightInMb * params->dwFrameWidthInMb * 64;
4055     uint32_t refMvBottomFieldOffset =
4056         MOS_ALIGN_CEIL(params->dwFrameFieldHeightInMb * params->dwFrameWidthInMb * (32 * 4), 0x1000);
4057 
4058     uint8_t vdirection, refVDirection;
4059     if (params->bMbEncIFrameDistInUse)
4060     {
4061         vdirection = CODECHAL_VDIRECTION_FRAME;
4062     }
4063     else
4064     {
4065         vdirection = (CodecHal_PictureIsFrame(*(params->pCurrOriginalPic))) ? CODECHAL_VDIRECTION_FRAME : (currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD;
4066     }
4067 
4068     // PAK Obj command buffer
4069     uint32_t size                = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * 16 * 4;  // 11DW + 5DW padding
4070     auto     kernelState         = params->pKernelState;
4071     auto     mbEncBindingTable   = params->pMbEncBindingTable;
4072     auto     currPicRefListEntry = params->ppRefList[params->pCurrReconstructedPic->FrameIdx];
4073     auto     mbCodeBuffer        = &currPicRefListEntry->resRefMbCodeBuffer;
4074     auto     mvDataBuffer        = &currPicRefListEntry->resRefMvDataBuffer;
4075 
4076     CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
4077     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4078     surfaceCodecParams.presBuffer            = mbCodeBuffer;
4079     surfaceCodecParams.dwSize                = size;
4080     surfaceCodecParams.dwOffset              = params->dwMbCodeBottomFieldOffset;
4081     surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncMfcAvcPakObj;
4082     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PAK_OBJECT_ENCODE].Value;
4083     surfaceCodecParams.bRenderTarget         = true;
4084     surfaceCodecParams.bIsWritable           = true;
4085     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4086         m_hwInterface,
4087         cmdBuffer,
4088         &surfaceCodecParams,
4089         kernelState));
4090 
4091     // MV data buffer
4092     size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * 32 * 4;
4093     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4094     surfaceCodecParams.presBuffer            = mvDataBuffer;
4095     surfaceCodecParams.dwSize                = size;
4096     surfaceCodecParams.dwOffset              = params->dwMvBottomFieldOffset;
4097     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
4098     surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncIndMVData;
4099     surfaceCodecParams.bRenderTarget         = true;
4100     surfaceCodecParams.bIsWritable           = true;
4101     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4102         m_hwInterface,
4103         cmdBuffer,
4104         &surfaceCodecParams,
4105         kernelState));
4106 
4107     // Current Picture Y
4108     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4109     surfaceCodecParams.bIs2DSurface               = true;
4110     surfaceCodecParams.bMediaBlockRW              = true;  // Use media block RW for DP 2D surface access
4111     surfaceCodecParams.bUseUVPlane                = true;
4112     surfaceCodecParams.psSurface                  = params->psCurrPicSurface;
4113     surfaceCodecParams.dwOffset                   = params->dwCurrPicSurfaceOffset;
4114     surfaceCodecParams.dwCacheabilityControl      = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
4115     surfaceCodecParams.dwBindingTableOffset       = mbEncBindingTable->dwAvcMBEncCurrY;
4116     surfaceCodecParams.dwUVBindingTableOffset     = mbEncBindingTable->dwAvcMBEncCurrUV;
4117     surfaceCodecParams.dwVerticalLineStride       = params->dwVerticalLineStride;
4118     surfaceCodecParams.dwVerticalLineStrideOffset = params->dwVerticalLineStrideOffset;
4119 #ifdef _MMC_SUPPORTED
4120     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4121 #endif
4122     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4123         m_hwInterface,
4124         cmdBuffer,
4125         &surfaceCodecParams,
4126         kernelState));
4127 
4128     // AVC_ME MV data buffer
4129     if (params->bHmeEnabled)
4130     {
4131         CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps4xMeMvDataBuffer);
4132 
4133         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4134         surfaceCodecParams.bIs2DSurface          = true;
4135         surfaceCodecParams.bMediaBlockRW         = true;
4136         surfaceCodecParams.psSurface             = params->ps4xMeMvDataBuffer;
4137         surfaceCodecParams.dwOffset              = params->dwMeMvBottomFieldOffset;
4138         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
4139         surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncMVDataFromME;
4140         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4141             m_hwInterface,
4142             cmdBuffer,
4143             &surfaceCodecParams,
4144             kernelState));
4145 
4146         CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps4xMeDistortionBuffer);
4147 
4148         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4149         surfaceCodecParams.bIs2DSurface          = true;
4150         surfaceCodecParams.bMediaBlockRW         = true;
4151         surfaceCodecParams.psSurface             = params->ps4xMeDistortionBuffer;
4152         surfaceCodecParams.dwOffset              = params->dwMeDistortionBottomFieldOffset;
4153         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
4154         surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncMEDist;
4155         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4156             m_hwInterface,
4157             cmdBuffer,
4158             &surfaceCodecParams,
4159             kernelState));
4160     }
4161 
4162     if (params->bMbConstDataBufferInUse)
4163     {
4164         // 16 DWs per QP value
4165         size = 16 * 52 * sizeof(uint32_t);
4166 
4167         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4168         surfaceCodecParams.presBuffer            = params->presMbBrcConstDataBuffer;
4169         surfaceCodecParams.dwSize                = size;
4170         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MB_BRC_CONST_ENCODE].Value;
4171         surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncMbBrcConstData;
4172         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4173             m_hwInterface,
4174             cmdBuffer,
4175             &surfaceCodecParams,
4176             kernelState));
4177     }
4178 
4179     if (params->bMbQpBufferInUse)
4180     {
4181         // AVC MB BRC QP buffer
4182         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4183         surfaceCodecParams.bIs2DSurface          = true;
4184         surfaceCodecParams.bMediaBlockRW         = true;
4185         surfaceCodecParams.psSurface             = params->psMbQpBuffer;
4186         surfaceCodecParams.dwOffset              = params->dwMbQpBottomFieldOffset;
4187         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_MB_QP_ENCODE].Value;
4188         surfaceCodecParams.dwBindingTableOffset  = currFieldPicture ? mbEncBindingTable->dwAvcMBEncMbQpField : mbEncBindingTable->dwAvcMBEncMbQpFrame;
4189         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4190             m_hwInterface,
4191             cmdBuffer,
4192             &surfaceCodecParams,
4193             kernelState));
4194     }
4195 
4196     if (params->bMbSpecificDataEnabled)
4197     {
4198         size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * sizeof(CODECHAL_ENCODE_AVC_MB_SPECIFIC_PARAMS);
4199         CODECHAL_ENCODE_VERBOSEMESSAGE("Send MB specific surface, size = %d", size);
4200         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4201         surfaceCodecParams.dwSize = size;
4202         surfaceCodecParams.presBuffer = params->presMbSpecificDataBuffer;
4203         surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMbSpecificData;
4204         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4205             m_hwInterface,
4206             cmdBuffer,
4207             &surfaceCodecParams,
4208             kernelState));
4209     }
4210 
4211     // Current Picture Y - VME
4212     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4213     surfaceCodecParams.bUseAdvState          = true;
4214     surfaceCodecParams.psSurface             = params->psCurrPicSurface;
4215     surfaceCodecParams.dwOffset              = params->dwCurrPicSurfaceOffset;
4216     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
4217     surfaceCodecParams.dwBindingTableOffset  = currFieldPicture ? mbEncBindingTable->dwAvcMBEncFieldCurrPic[0] : mbEncBindingTable->dwAvcMBEncCurrPicFrame[0];
4218     surfaceCodecParams.ucVDirection          = vdirection;
4219 #ifdef _MMC_SUPPORTED
4220     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4221 #endif
4222     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4223         m_hwInterface,
4224         cmdBuffer,
4225         &surfaceCodecParams,
4226         kernelState));
4227 
4228     surfaceCodecParams.dwBindingTableOffset = currFieldPicture ? mbEncBindingTable->dwAvcMBEncFieldCurrPic[1] : mbEncBindingTable->dwAvcMBEncCurrPicFrame[1];
4229     surfaceCodecParams.ucVDirection         = vdirection;
4230     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4231         m_hwInterface,
4232         cmdBuffer,
4233         &surfaceCodecParams,
4234         kernelState));
4235 
4236     // Setup references 1...n
4237     // LIST 0 references
4238     uint8_t refIdx;
4239     for (refIdx = 0; refIdx <= params->pAvcSlcParams->num_ref_idx_l0_active_minus1; refIdx++)
4240     {
4241         auto     refPic = params->pAvcSlcParams->RefPicList[LIST_0][refIdx];
4242         uint32_t refMbCodeBottomFieldOffsetUsed;
4243         uint32_t refMvBottomFieldOffsetUsed;
4244         uint32_t refBindingTableOffset;
4245         if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid)
4246         {
4247             uint8_t refPicIdx      = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx;
4248             bool    refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false;
4249             // Program the surface based on current picture's field/frame mode
4250             if (currFieldPicture)  // if current picture is field
4251             {
4252                 if (refBottomField)
4253                 {
4254                     refVDirection       = CODECHAL_VDIRECTION_BOT_FIELD;
4255                     refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicBotField[refIdx];
4256                 }
4257                 else
4258                 {
4259                     refVDirection       = CODECHAL_VDIRECTION_TOP_FIELD;
4260                     refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicTopField[refIdx];
4261                 }
4262             }
4263             else  // if current picture is frame
4264             {
4265                 refVDirection       = CODECHAL_VDIRECTION_FRAME;
4266                 refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicFrame[refIdx];
4267             }
4268 
4269             // Picture Y VME
4270             memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4271             surfaceCodecParams.bUseAdvState = true;
4272             if ((0 == refIdx) && (params->bUseWeightedSurfaceForL0))
4273             {
4274                 surfaceCodecParams.psSurface = &params->pWeightedPredOutputPicSelectList[CODEC_AVC_WP_OUTPUT_L0_START + refIdx].sBuffer;
4275             }
4276             else
4277             {
4278                 surfaceCodecParams.psSurface = &params->ppRefList[refPicIdx]->sRefBuffer;
4279             }
4280             surfaceCodecParams.dwWidthInUse  = params->dwFrameWidthInMb * 16;
4281             surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16;
4282 
4283             surfaceCodecParams.dwBindingTableOffset  = refBindingTableOffset;
4284             surfaceCodecParams.ucVDirection          = refVDirection;
4285             surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
4286 
4287 #ifdef _MMC_SUPPORTED
4288             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4289 #endif
4290             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4291                 m_hwInterface,
4292                 cmdBuffer,
4293                 &surfaceCodecParams,
4294                 kernelState));
4295         }
4296     }
4297 
4298 #if 1
4299     for (refIdx = (params->pAvcSlcParams->num_ref_idx_l0_active_minus1 + 1); refIdx < CODECHAL_ENCODE_NUM_MAX_VME_L0_REF; refIdx++)
4300     {
4301         auto     refPic = params->pAvcSlcParams->RefPicList[LIST_0][0];
4302         uint32_t refMbCodeBottomFieldOffsetUsed;
4303         uint32_t refMvBottomFieldOffsetUsed;
4304         uint32_t refBindingTableOffset;
4305         if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid)
4306         {
4307             uint8_t refPicIdx = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx;
4308             bool    refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false;
4309             // Program the surface based on current picture's field/frame mode
4310             if (currFieldPicture)  // if current picture is field
4311             {
4312                 if (refBottomField)
4313                 {
4314                     refVDirection = CODECHAL_VDIRECTION_BOT_FIELD;
4315                     refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicBotField[refIdx];
4316                 }
4317                 else
4318                 {
4319                     refVDirection = CODECHAL_VDIRECTION_TOP_FIELD;
4320                     refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicTopField[refIdx];
4321                 }
4322             }
4323             else  // if current picture is frame
4324             {
4325                 refVDirection = CODECHAL_VDIRECTION_FRAME;
4326                 refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicFrame[refIdx];
4327             }
4328 
4329             // Picture Y VME
4330             memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4331             surfaceCodecParams.bUseAdvState = true;
4332             if ((0 == refIdx) && (params->bUseWeightedSurfaceForL0))
4333             {
4334                 surfaceCodecParams.psSurface = &params->pWeightedPredOutputPicSelectList[CODEC_AVC_WP_OUTPUT_L0_START + refIdx].sBuffer;
4335             }
4336             else
4337             {
4338                 surfaceCodecParams.psSurface = &params->ppRefList[refPicIdx]->sRefBuffer;
4339             }
4340             surfaceCodecParams.dwWidthInUse = params->dwFrameWidthInMb * 16;
4341             surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16;
4342 
4343             surfaceCodecParams.dwBindingTableOffset = refBindingTableOffset;
4344             surfaceCodecParams.ucVDirection = refVDirection;
4345             surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
4346 
4347 #ifdef _MMC_SUPPORTED
4348             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4349 #endif
4350             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4351                 m_hwInterface,
4352                 cmdBuffer,
4353                 &surfaceCodecParams,
4354                 kernelState));
4355         }
4356     }
4357 
4358     if (params->pAvcSlcParams->num_ref_idx_l1_active_minus1 == 0)
4359     {
4360         for (refIdx = 0; refIdx <= MOS_MIN(params->pAvcSlcParams->num_ref_idx_l0_active_minus1, 1); refIdx++)
4361         {
4362             auto     refPic = params->pAvcSlcParams->RefPicList[LIST_0][refIdx];
4363             uint32_t refMbCodeBottomFieldOffsetUsed;
4364             uint32_t refMvBottomFieldOffsetUsed;
4365             uint32_t refBindingTableOffset;
4366             if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid)
4367             {
4368                 uint8_t refPicIdx = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx;
4369                 bool    refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false;
4370                 // Program the surface based on current picture's field/frame mode
4371                 if (currFieldPicture)  // if current picture is field
4372                 {
4373                     if (refBottomField)
4374                     {
4375                         refVDirection = CODECHAL_VDIRECTION_BOT_FIELD;
4376                         refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicBotField[refIdx];
4377                     }
4378                     else
4379                     {
4380                         refVDirection = CODECHAL_VDIRECTION_TOP_FIELD;
4381                         refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicTopField[refIdx];
4382                     }
4383                 }
4384                 else  // if current picture is frame
4385                 {
4386                     refVDirection = CODECHAL_VDIRECTION_FRAME;
4387                     refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicFrame[refIdx];
4388                 }
4389 
4390                 // Picture Y VME
4391                 memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4392                 surfaceCodecParams.bUseAdvState = true;
4393                 if ((0 == refIdx) && (params->bUseWeightedSurfaceForL0))
4394                 {
4395                     surfaceCodecParams.psSurface = &params->pWeightedPredOutputPicSelectList[CODEC_AVC_WP_OUTPUT_L0_START + refIdx].sBuffer;
4396                 }
4397                 else
4398                 {
4399                     surfaceCodecParams.psSurface = &params->ppRefList[refPicIdx]->sRefBuffer;
4400                 }
4401                 surfaceCodecParams.dwWidthInUse = params->dwFrameWidthInMb * 16;
4402                 surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16;
4403 
4404                 surfaceCodecParams.dwBindingTableOffset = refBindingTableOffset;
4405                 surfaceCodecParams.ucVDirection = refVDirection;
4406                 surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
4407 
4408 #ifdef _MMC_SUPPORTED
4409                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4410 #endif
4411                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4412                     m_hwInterface,
4413                     cmdBuffer,
4414                     &surfaceCodecParams,
4415                     kernelState));
4416             }
4417         }
4418     }
4419 #endif
4420 
4421     // Setup references 1...n
4422     // LIST 1 references
4423     uint32_t curbeSize;
4424     for (refIdx = 0; refIdx <= params->pAvcSlcParams->num_ref_idx_l1_active_minus1; refIdx++)
4425     {
4426         if (!currFieldPicture && refIdx > 0)
4427         {
4428             // Only 1 LIST 1 reference required here since only single ref is supported in frame case
4429             break;
4430         }
4431 
4432         auto     refPic = params->pAvcSlcParams->RefPicList[LIST_1][refIdx];
4433         uint32_t refMbCodeBottomFieldOffsetUsed;
4434         uint32_t refMvBottomFieldOffsetUsed;
4435         uint32_t refBindingTableOffset;
4436         bool     refBottomField;
4437         uint8_t  refPicIdx;
4438         if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid)
4439         {
4440             refPicIdx      = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx;
4441             refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
4442             // Program the surface based on current picture's field/frame mode
4443             if (currFieldPicture)  // if current picture is field
4444             {
4445                 if (refBottomField)
4446                 {
4447                     refVDirection                = CODECHAL_VDIRECTION_BOT_FIELD;
4448                     refMbCodeBottomFieldOffsetUsed = refMbCodeBottomFieldOffset;
4449                     refMvBottomFieldOffsetUsed     = refMvBottomFieldOffset;
4450                     refBindingTableOffset          = mbEncBindingTable->dwAvcMBEncBwdPicBotField[refIdx];
4451                 }
4452                 else
4453                 {
4454                     refVDirection                = CODECHAL_VDIRECTION_TOP_FIELD;
4455                     refMbCodeBottomFieldOffsetUsed = 0;
4456                     refMvBottomFieldOffsetUsed     = 0;
4457                     refBindingTableOffset          = mbEncBindingTable->dwAvcMBEncBwdPicTopField[refIdx];
4458                 }
4459             }
4460             else  // if current picture is frame
4461             {
4462                 refVDirection                = CODECHAL_VDIRECTION_FRAME;
4463                 refMbCodeBottomFieldOffsetUsed = 0;
4464                 refMvBottomFieldOffsetUsed     = 0;
4465                 refBindingTableOffset          = mbEncBindingTable->dwAvcMBEncBwdPicFrame[refIdx];
4466             }
4467 
4468             // Picture Y VME
4469             memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4470             surfaceCodecParams.bUseAdvState = true;
4471             if ((0 == refIdx) && (params->bUseWeightedSurfaceForL1))
4472             {
4473                 surfaceCodecParams.psSurface = &params->pWeightedPredOutputPicSelectList[CODEC_AVC_WP_OUTPUT_L1_START + refIdx].sBuffer;
4474             }
4475             else
4476             {
4477                 surfaceCodecParams.psSurface = &params->ppRefList[refPicIdx]->sRefBuffer;
4478             }
4479             surfaceCodecParams.dwWidthInUse  = params->dwFrameWidthInMb * 16;
4480             surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16;
4481 
4482             surfaceCodecParams.dwBindingTableOffset  = refBindingTableOffset;
4483             surfaceCodecParams.ucVDirection          = refVDirection;
4484             surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
4485 
4486 #ifdef _MMC_SUPPORTED
4487             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4488 #endif
4489             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4490                 m_hwInterface,
4491                 cmdBuffer,
4492                 &surfaceCodecParams,
4493                 kernelState));
4494 
4495             if (refIdx == 0)
4496             {
4497                 // MB data buffer
4498                 size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * 16 * 4;
4499                 memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4500                 surfaceCodecParams.dwSize                = size;
4501                 surfaceCodecParams.presBuffer            = &params->ppRefList[refPicIdx]->resRefMbCodeBuffer;
4502                 surfaceCodecParams.dwOffset              = refMbCodeBottomFieldOffsetUsed;
4503                 surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PAK_OBJECT_ENCODE].Value;
4504                 surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncBwdRefMBData;
4505                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4506                     m_hwInterface,
4507                     cmdBuffer,
4508                     &surfaceCodecParams,
4509                     kernelState));
4510 
4511                 // MV data buffer
4512                 size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * 32 * 4;
4513                 memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4514                 surfaceCodecParams.dwSize                = size;
4515                 surfaceCodecParams.presBuffer            = &params->ppRefList[refPicIdx]->resRefMvDataBuffer;
4516                 surfaceCodecParams.dwOffset              = refMvBottomFieldOffsetUsed;
4517                 surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
4518                 surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncBwdRefMVData;
4519                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4520                     m_hwInterface,
4521                     cmdBuffer,
4522                     &surfaceCodecParams,
4523                     kernelState));
4524             }
4525 
4526             if (refIdx < CODECHAL_ENCODE_NUM_MAX_VME_L1_REF)
4527             {
4528                 if (currFieldPicture)
4529                 {
4530                     // The binding table contains multiple entries for IDX0 backwards references
4531                     if (refBottomField)
4532                     {
4533                         refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicBotField[refIdx + CODECHAL_ENCODE_NUM_MAX_VME_L1_REF];
4534                     }
4535                     else
4536                     {
4537                         refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicTopField[refIdx + CODECHAL_ENCODE_NUM_MAX_VME_L1_REF];
4538                     }
4539                 }
4540                 else
4541                 {
4542                     refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicFrame[refIdx + CODECHAL_ENCODE_NUM_MAX_VME_L1_REF];
4543                 }
4544 
4545                 // Picture Y VME
4546                 memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4547                 surfaceCodecParams.bUseAdvState          = true;
4548                 surfaceCodecParams.dwWidthInUse          = params->dwFrameWidthInMb * 16;
4549                 surfaceCodecParams.dwHeightInUse         = params->dwFrameHeightInMb * 16;
4550                 surfaceCodecParams.psSurface             = &params->ppRefList[refPicIdx]->sRefBuffer;
4551                 surfaceCodecParams.dwBindingTableOffset  = refBindingTableOffset;
4552                 surfaceCodecParams.ucVDirection          = refVDirection;
4553                 surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
4554 
4555 #ifdef _MMC_SUPPORTED
4556                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4557 #endif
4558                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4559                     m_hwInterface,
4560                     cmdBuffer,
4561                     &surfaceCodecParams,
4562                     kernelState));
4563             }
4564         }
4565     }
4566 
4567     // BRC distortion data buffer for I frame
4568     if (params->bMbEncIFrameDistInUse)
4569     {
4570         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4571         surfaceCodecParams.bIs2DSurface         = true;
4572         surfaceCodecParams.bMediaBlockRW        = true;
4573         surfaceCodecParams.psSurface            = params->psMeBrcDistortionBuffer;
4574         surfaceCodecParams.dwOffset             = params->dwMeBrcDistortionBottomFieldOffset;
4575         surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncBRCDist;
4576         surfaceCodecParams.bIsWritable          = true;
4577         surfaceCodecParams.bRenderTarget        = true;
4578         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4579             m_hwInterface,
4580             cmdBuffer,
4581             &surfaceCodecParams,
4582             kernelState));
4583     }
4584 
4585     // RefPicSelect of Current Picture
4586     if (params->bUsedAsRef)
4587     {
4588         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4589         surfaceCodecParams.bIs2DSurface          = true;
4590         surfaceCodecParams.bMediaBlockRW         = true;
4591         surfaceCodecParams.psSurface             = &currPicRefListEntry->pRefPicSelectListEntry->sBuffer;
4592         surfaceCodecParams.psSurface->dwHeight   = MOS_ALIGN_CEIL(surfaceCodecParams.psSurface->dwHeight, 8);
4593         surfaceCodecParams.dwOffset              = params->dwRefPicSelectBottomFieldOffset;
4594         surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncRefPicSelectL0;
4595         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
4596         surfaceCodecParams.bRenderTarget         = true;
4597         surfaceCodecParams.bIsWritable           = true;
4598         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4599             m_hwInterface,
4600             cmdBuffer,
4601             &surfaceCodecParams,
4602             kernelState));
4603     }
4604 
4605     if (params->bMBVProcStatsEnabled)
4606     {
4607         size = params->dwFrameWidthInMb *
4608             (currFieldPicture ? params->dwFrameFieldHeightInMb : params->dwFrameHeightInMb) *
4609             16 * sizeof(uint32_t);
4610 
4611         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4612         surfaceCodecParams.dwSize               = size;
4613         surfaceCodecParams.presBuffer           = params->presMBVProcStatsBuffer;
4614         surfaceCodecParams.dwOffset             = currBottomField ? params->dwMBVProcStatsBottomFieldOffset : 0;
4615         surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMBStats;
4616         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4617             m_hwInterface,
4618             cmdBuffer,
4619             &surfaceCodecParams,
4620             kernelState));
4621     }
4622     else if (params->bFlatnessCheckEnabled)
4623     {
4624         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4625         surfaceCodecParams.bIs2DSurface          = true;
4626         surfaceCodecParams.bMediaBlockRW         = true;
4627         surfaceCodecParams.psSurface             = params->psFlatnessCheckSurface;
4628         surfaceCodecParams.dwOffset              = currBottomField ? params->dwFlatnessCheckBottomFieldOffset : 0;
4629         surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncFlatnessChk;
4630         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE].Value;
4631         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4632             m_hwInterface,
4633             cmdBuffer,
4634             &surfaceCodecParams,
4635             kernelState));
4636     }
4637 
4638     if (params->bMADEnabled)
4639     {
4640         size = CODECHAL_MAD_BUFFER_SIZE;
4641 
4642         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4643         surfaceCodecParams.bRawSurface           = true;
4644         surfaceCodecParams.dwSize                = size;
4645         surfaceCodecParams.presBuffer            = params->presMADDataBuffer;
4646         surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncMADData;
4647         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MAD_ENCODE].Value;
4648         surfaceCodecParams.bRenderTarget         = true;
4649         surfaceCodecParams.bIsWritable           = true;
4650         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4651             m_hwInterface,
4652             cmdBuffer,
4653             &surfaceCodecParams,
4654             kernelState));
4655     }
4656 
4657     if (params->dwMbEncBRCBufferSize > 0)
4658     {
4659         // MbEnc BRC buffer - write only
4660         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4661         surfaceCodecParams.presBuffer            = params->presMbEncBRCBuffer;
4662         surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(params->dwMbEncBRCBufferSize);
4663         surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMbEncBRCCurbeData;
4664         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE].Value;
4665         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4666             m_hwInterface,
4667             cmdBuffer,
4668             &surfaceCodecParams,
4669             kernelState));
4670     }
4671     else
4672     {
4673         if (params->bUseMbEncAdvKernel)
4674         {
4675             // For BRC the new BRC surface is used
4676             if (params->bUseAdvancedDsh)
4677             {
4678                 memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4679                 surfaceCodecParams.presBuffer = params->presMbEncCurbeBuffer;
4680                 curbeSize                     = MOS_ALIGN_CEIL(
4681                     params->pKernelState->KernelParams.iCurbeLength,
4682                     m_hwInterface->GetRenderInterface()->m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
4683                 surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(curbeSize);
4684                 surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMbEncBRCCurbeData;
4685                 surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE].Value;
4686                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4687                     m_hwInterface,
4688                     cmdBuffer,
4689                     &surfaceCodecParams,
4690                     kernelState));
4691             }
4692             else  // For CQP the DSH CURBE is used
4693             {
4694                 MOS_RESOURCE *dsh = nullptr;
4695                 CODECHAL_ENCODE_CHK_NULL_RETURN(dsh = params->pKernelState->m_dshRegion.GetResource());
4696 
4697                 memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4698                 surfaceCodecParams.presBuffer = dsh;
4699                 surfaceCodecParams.dwOffset =
4700                     params->pKernelState->m_dshRegion.GetOffset() +
4701                     params->pKernelState->dwCurbeOffset;
4702                 curbeSize = MOS_ALIGN_CEIL(
4703                     params->pKernelState->KernelParams.iCurbeLength,
4704                     m_hwInterface->GetRenderInterface()->m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
4705                 surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(curbeSize);
4706                 surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMbEncBRCCurbeData;
4707                 surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE].Value;
4708                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4709                     m_hwInterface,
4710                     cmdBuffer,
4711                     &surfaceCodecParams,
4712                     kernelState));
4713             }
4714         }
4715     }
4716 
4717     if (params->bArbitraryNumMbsInSlice)
4718     {
4719         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4720         surfaceCodecParams.bIs2DSurface          = true;
4721         surfaceCodecParams.bMediaBlockRW         = true;
4722         surfaceCodecParams.psSurface             = params->psSliceMapSurface;
4723         surfaceCodecParams.bRenderTarget         = false;
4724         surfaceCodecParams.bIsWritable           = false;
4725         surfaceCodecParams.dwOffset              = currBottomField ? params->dwSliceMapBottomFieldOffset : 0;
4726         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_SLICE_MAP_ENCODE].Value;
4727         surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncSliceMapData;
4728 
4729         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4730             m_hwInterface,
4731             cmdBuffer,
4732             &surfaceCodecParams,
4733             kernelState));
4734     }
4735 
4736     if (!params->bMbEncIFrameDistInUse)
4737     {
4738         if (params->bMbDisableSkipMapEnabled)
4739         {
4740             memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4741             surfaceCodecParams.bIs2DSurface          = true;
4742             surfaceCodecParams.bMediaBlockRW         = true;
4743             surfaceCodecParams.psSurface             = params->psMbDisableSkipMapSurface;
4744             surfaceCodecParams.dwOffset              = 0;
4745             surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncMbNonSkipMap;
4746             surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_MBDISABLE_SKIPMAP_CODEC].Value;
4747             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4748                 m_hwInterface,
4749                 cmdBuffer,
4750                 &surfaceCodecParams,
4751                 kernelState));
4752         }
4753 
4754         if (params->bStaticFrameDetectionEnabled)
4755         {
4756             // static frame cost table surface
4757             memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4758             surfaceCodecParams.presBuffer            = params->presSFDCostTableBuffer;
4759             surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(m_sfdCostTableBufferSize);
4760             surfaceCodecParams.dwOffset              = 0;
4761             surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
4762             surfaceCodecParams.dwBindingTableOffset  = mbEncBindingTable->dwAvcMBEncStaticDetectionCostTable;
4763             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4764                 m_hwInterface,
4765                 cmdBuffer,
4766                 &surfaceCodecParams,
4767                 kernelState));
4768         }
4769 
4770         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4771         surfaceCodecParams.bIs2DSurface = true;
4772         surfaceCodecParams.bMediaBlockRW = true;
4773         surfaceCodecParams.psSurface = m_swScoreboardState->GetCurSwScoreboardSurface();
4774         surfaceCodecParams.bRenderTarget = true;
4775         surfaceCodecParams.bIsWritable = true;
4776         surfaceCodecParams.dwOffset = 0;
4777         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_SOFTWARE_SCOREBOARD_ENCODE].Value;
4778         surfaceCodecParams.dwBindingTableOffset = mbencSwScoreboard;
4779         surfaceCodecParams.bUse32UINTSurfaceFormat = true;
4780         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4781             m_hwInterface,
4782             cmdBuffer,
4783             &surfaceCodecParams,
4784             kernelState));
4785     }
4786     return eStatus;
4787 }
4788 
SendAvcWPSurfaces(PMOS_COMMAND_BUFFER cmdBuffer,PCODECHAL_ENCODE_AVC_WP_SURFACE_PARAMS params)4789 MOS_STATUS CodechalEncodeAvcEncG12::SendAvcWPSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_WP_SURFACE_PARAMS params)
4790 {
4791     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4792 
4793     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4794     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
4795     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);
4796     CODECHAL_ENCODE_CHK_NULL_RETURN(params->psInputRefBuffer);
4797     CODECHAL_ENCODE_CHK_NULL_RETURN(params->psOutputScaledBuffer);
4798 
4799     CODECHAL_SURFACE_CODEC_PARAMS surfaceParams;
4800     memset((void *)&surfaceParams, 0, sizeof(surfaceParams));
4801     surfaceParams.bIs2DSurface               = true;
4802     surfaceParams.bMediaBlockRW              = true;
4803     surfaceParams.psSurface                  = params->psInputRefBuffer;  // Input surface
4804     surfaceParams.bIsWritable                = false;
4805     surfaceParams.bRenderTarget              = false;
4806     surfaceParams.dwBindingTableOffset       = wpInputRefSurface;
4807     surfaceParams.dwCacheabilityControl      = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_WP_DOWNSAMPLED_ENCODE].Value;
4808     surfaceParams.dwVerticalLineStride       = params->dwVerticalLineStride;
4809     surfaceParams.dwVerticalLineStrideOffset = params->dwVerticalLineStrideOffset;
4810     surfaceParams.ucVDirection               = params->ucVDirection;
4811 #ifdef _MMC_SUPPORTED
4812     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceParams));
4813 #endif
4814     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4815         m_hwInterface,
4816         cmdBuffer,
4817         &surfaceParams,
4818         params->pKernelState));
4819 
4820     memset((void *)&surfaceParams, 0, sizeof(surfaceParams));
4821     surfaceParams.bIs2DSurface               = true;
4822     surfaceParams.bMediaBlockRW              = true;
4823     surfaceParams.psSurface                  = params->psOutputScaledBuffer;  // output surface
4824     surfaceParams.bIsWritable                = true;
4825     surfaceParams.bRenderTarget              = true;
4826     surfaceParams.dwBindingTableOffset       = wpOutputScaledSurface;
4827     surfaceParams.dwCacheabilityControl      = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_WP_DOWNSAMPLED_ENCODE].Value;
4828     surfaceParams.dwVerticalLineStride       = params->dwVerticalLineStride;
4829     surfaceParams.dwVerticalLineStrideOffset = params->dwVerticalLineStrideOffset;
4830     surfaceParams.ucVDirection               = params->ucVDirection;
4831     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4832         m_hwInterface,
4833         cmdBuffer,
4834         &surfaceParams,
4835         params->pKernelState));
4836 
4837     return eStatus;
4838 }
4839 
SendAvcBrcFrameUpdateSurfaces(PMOS_COMMAND_BUFFER cmdBuffer,PCODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS params)4840 MOS_STATUS CodechalEncodeAvcEncG12::SendAvcBrcFrameUpdateSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS params)
4841 {
4842     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4843 
4844     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4845     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
4846     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBrcBuffers);
4847 
4848     // BRC history buffer
4849     CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
4850     auto                          kernelState           = params->pKernelState;
4851     auto                          brcUpdateBindingTable = params->pBrcUpdateBindingTable;
4852     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4853     surfaceCodecParams.presBuffer            = &params->pBrcBuffers->resBrcHistoryBuffer;
4854     surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(params->dwBrcHistoryBufferSize);
4855     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE].Value;
4856     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcHistoryBuffer;
4857     surfaceCodecParams.bIsWritable           = true;
4858     surfaceCodecParams.bRenderTarget         = true;
4859     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4860         m_hwInterface,
4861         cmdBuffer,
4862         &surfaceCodecParams,
4863         kernelState));
4864 
4865     // PAK Statistics buffer
4866     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4867     surfaceCodecParams.presBuffer            = &params->pBrcBuffers->resBrcPakStatisticBuffer[0];
4868     surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(params->dwBrcPakStatisticsSize);
4869     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_PAK_STATS_ENCODE].Value;
4870     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcPakStatisticsOutputBuffer;
4871     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4872         m_hwInterface,
4873         cmdBuffer,
4874         &surfaceCodecParams,
4875         kernelState));
4876 
4877     // PAK IMG_STATEs buffer - read only
4878     uint32_t size = MOS_BYTES_TO_DWORDS(BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses());
4879     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4880     surfaceCodecParams.presBuffer            = &params->pBrcBuffers->resBrcImageStatesReadBuffer[params->ucCurrRecycledBufIdx];
4881     surfaceCodecParams.dwSize                = size;
4882     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_PAK_IMAGESTATE_ENCODE].Value;
4883     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcImageStateReadBuffer;
4884     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4885         m_hwInterface,
4886         cmdBuffer,
4887         &surfaceCodecParams,
4888         kernelState));
4889 
4890     // PAK IMG_STATEs buffer - write only
4891     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4892     surfaceCodecParams.presBuffer            = &params->pBrcBuffers->resBrcImageStatesWriteBuffer;
4893     surfaceCodecParams.dwSize                = size;
4894     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_PAK_IMAGESTATE_ENCODE].Value;
4895     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcImageStateWriteBuffer;
4896     surfaceCodecParams.bIsWritable           = true;
4897     surfaceCodecParams.bRenderTarget         = true;
4898     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4899         m_hwInterface,
4900         cmdBuffer,
4901         &surfaceCodecParams,
4902         kernelState));
4903 
4904     if (params->dwMbEncBRCBufferSize > 0)
4905     {
4906         // MbEnc BRC buffer - write only
4907         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4908         surfaceCodecParams.presBuffer            = &params->pBrcBuffers->resMbEncBrcBuffer;
4909         surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(params->dwMbEncBRCBufferSize);
4910         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MBENC_BRC_ENCODE].Value;
4911         surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcMbEncCurbeWriteData;
4912         surfaceCodecParams.bIsWritable           = true;
4913         surfaceCodecParams.bRenderTarget         = true;
4914         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4915             m_hwInterface,
4916             cmdBuffer,
4917             &surfaceCodecParams,
4918             kernelState));
4919     }
4920     else
4921     {
4922         PMHW_KERNEL_STATE mbEncKernelState;
4923         CODECHAL_ENCODE_CHK_NULL_RETURN(mbEncKernelState = params->pBrcBuffers->pMbEncKernelStateInUse);
4924 
4925         MOS_RESOURCE *dsh = nullptr;
4926         CODECHAL_ENCODE_CHK_NULL_RETURN(dsh = mbEncKernelState->m_dshRegion.GetResource());
4927 
4928         // BRC ENC CURBE Buffer - read only
4929         size = MOS_ALIGN_CEIL(
4930             mbEncKernelState->KernelParams.iCurbeLength,
4931             m_renderEngineInterface->m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
4932         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4933         surfaceCodecParams.presBuffer = dsh;
4934         surfaceCodecParams.dwOffset =
4935             mbEncKernelState->m_dshRegion.GetOffset() +
4936             mbEncKernelState->dwCurbeOffset;
4937         surfaceCodecParams.dwSize               = MOS_BYTES_TO_DWORDS(size);
4938         surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcMbEncCurbeReadBuffer;
4939         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4940             m_hwInterface,
4941             cmdBuffer,
4942             &surfaceCodecParams,
4943             kernelState));
4944 
4945         // BRC ENC CURBE Buffer - write only
4946         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4947         if (params->bUseAdvancedDsh)
4948         {
4949             surfaceCodecParams.presBuffer = params->presMbEncCurbeBuffer;
4950         }
4951         else
4952         {
4953             surfaceCodecParams.presBuffer = dsh;
4954             surfaceCodecParams.dwOffset =
4955                 mbEncKernelState->m_dshRegion.GetOffset() +
4956                 mbEncKernelState->dwCurbeOffset;
4957         }
4958         surfaceCodecParams.dwSize               = MOS_BYTES_TO_DWORDS(size);
4959         surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcMbEncCurbeWriteData;
4960         surfaceCodecParams.bRenderTarget        = true;
4961         surfaceCodecParams.bIsWritable          = true;
4962         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4963             m_hwInterface,
4964             cmdBuffer,
4965             &surfaceCodecParams,
4966             kernelState));
4967     }
4968 
4969     // AVC_ME BRC Distortion data buffer - input/output
4970     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4971     surfaceCodecParams.bIs2DSurface          = true;
4972     surfaceCodecParams.bMediaBlockRW         = true;
4973     surfaceCodecParams.psSurface             = &params->pBrcBuffers->sMeBrcDistortionBuffer;
4974     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value;
4975     surfaceCodecParams.dwOffset              = params->pBrcBuffers->dwMeBrcDistortionBottomFieldOffset;
4976     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcDistortionBuffer;
4977     surfaceCodecParams.bRenderTarget         = true;
4978     surfaceCodecParams.bIsWritable           = true;
4979     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4980         m_hwInterface,
4981         cmdBuffer,
4982         &surfaceCodecParams,
4983         kernelState));
4984 
4985     // BRC Constant Data Surface
4986     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4987     surfaceCodecParams.bIs2DSurface          = true;
4988     surfaceCodecParams.bMediaBlockRW         = true;
4989     surfaceCodecParams.psSurface             = &params->pBrcBuffers->sBrcConstantDataBuffer[params->ucCurrRecycledBufIdx];
4990     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_CONSTANT_DATA_ENCODE].Value;
4991     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcConstantData;
4992     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4993         m_hwInterface,
4994         cmdBuffer,
4995         &surfaceCodecParams,
4996         kernelState));
4997 
4998     // MBStat buffer - input
4999     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5000     surfaceCodecParams.presBuffer            = params->presMbStatBuffer;
5001     surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(m_hwInterface->m_avcMbStatBufferSize);
5002     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_MB_STATS_ENCODE].Value;
5003     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcMbStatBuffer;
5004     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5005         m_hwInterface,
5006         cmdBuffer,
5007         &surfaceCodecParams,
5008         kernelState));
5009 
5010     // MV data buffer
5011     if (params->psMvDataBuffer)
5012     {
5013         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5014         surfaceCodecParams.bIs2DSurface          = true;
5015         surfaceCodecParams.bMediaBlockRW         = true;
5016         surfaceCodecParams.psSurface             = params->psMvDataBuffer;
5017         surfaceCodecParams.dwOffset              = params->dwMvBottomFieldOffset;
5018         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
5019         surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwFrameBrcMvDataBuffer;
5020         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5021             m_hwInterface,
5022             cmdBuffer,
5023             &surfaceCodecParams,
5024             kernelState));
5025     }
5026 
5027     return eStatus;
5028 }
5029 
SendAvcBrcMbUpdateSurfaces(PMOS_COMMAND_BUFFER cmdBuffer,PCODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS params)5030 MOS_STATUS CodechalEncodeAvcEncG12::SendAvcBrcMbUpdateSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS params)
5031 {
5032     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5033 
5034     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
5035     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
5036     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBrcBuffers);
5037 
5038     // BRC history buffer
5039     auto                          kernelState           = params->pKernelState;
5040     auto                          brcUpdateBindingTable = params->pBrcUpdateBindingTable;
5041     CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
5042     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5043     surfaceCodecParams.presBuffer            = &params->pBrcBuffers->resBrcHistoryBuffer;
5044     surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(params->dwBrcHistoryBufferSize);
5045     surfaceCodecParams.bIsWritable           = true;
5046     surfaceCodecParams.bRenderTarget         = true;
5047     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE].Value;
5048     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwMbBrcHistoryBuffer;
5049     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5050         m_hwInterface,
5051         cmdBuffer,
5052         &surfaceCodecParams,
5053         kernelState));
5054 
5055     // AVC MB QP data buffer
5056     if (params->bMbBrcEnabled)
5057     {
5058         params->pBrcBuffers->sBrcMbQpBuffer.dwHeight = MOS_ALIGN_CEIL((params->dwDownscaledFrameFieldHeightInMb4x << 2), 8);
5059 
5060         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5061         surfaceCodecParams.bIs2DSurface          = true;
5062         surfaceCodecParams.bMediaBlockRW         = true;
5063         surfaceCodecParams.bIsWritable           = true;
5064         surfaceCodecParams.bRenderTarget         = true;
5065         surfaceCodecParams.psSurface             = &params->pBrcBuffers->sBrcMbQpBuffer;
5066         surfaceCodecParams.dwOffset              = params->pBrcBuffers->dwBrcMbQpBottomFieldOffset;
5067         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_MB_QP_ENCODE].Value;
5068         surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwMbBrcMbQpBuffer;
5069         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5070             m_hwInterface,
5071             cmdBuffer,
5072             &surfaceCodecParams,
5073             kernelState));
5074     }
5075 
5076     // BRC ROI feature
5077     if (params->bBrcRoiEnabled)
5078     {
5079         params->psRoiSurface->dwHeight = MOS_ALIGN_CEIL((params->dwDownscaledFrameFieldHeightInMb4x << 2), 8);
5080 
5081         memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5082         surfaceCodecParams.bIs2DSurface          = true;
5083         surfaceCodecParams.bMediaBlockRW         = true;
5084         surfaceCodecParams.bIsWritable           = false;
5085         surfaceCodecParams.bRenderTarget         = true;
5086         surfaceCodecParams.psSurface             = params->psRoiSurface;
5087         surfaceCodecParams.dwOffset              = 0;
5088         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ROI_ENCODE].Value;
5089         surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwMbBrcROISurface;
5090         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5091             m_hwInterface,
5092             cmdBuffer,
5093             &surfaceCodecParams,
5094             kernelState));
5095     }
5096 
5097     // MBStat buffer
5098     memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5099     surfaceCodecParams.presBuffer            = params->presMbStatBuffer;
5100     surfaceCodecParams.dwSize                = MOS_BYTES_TO_DWORDS(m_hwInterface->m_avcMbStatBufferSize);
5101     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_MB_STATS_ENCODE].Value;
5102     surfaceCodecParams.dwBindingTableOffset  = brcUpdateBindingTable->dwMbBrcMbStatBuffer;
5103     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5104         m_hwInterface,
5105         cmdBuffer,
5106         &surfaceCodecParams,
5107         kernelState));
5108 
5109     return eStatus;
5110 }
5111 
SetGpuCtxCreatOption()5112 MOS_STATUS CodechalEncodeAvcEncG12::SetGpuCtxCreatOption()
5113 {
5114     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5115 
5116     CODECHAL_ENCODE_FUNCTION_ENTER;
5117 
5118     if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
5119     {
5120         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::SetGpuCtxCreatOption());
5121     }
5122     else
5123     {
5124         m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
5125         CODECHAL_ENCODE_CHK_NULL_RETURN(m_gpuCtxCreatOpt);
5126 
5127         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
5128             m_sinlgePipeVeState,
5129             (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt));
5130     }
5131 
5132     return eStatus;
5133 }
5134 
SetupROISurface()5135 MOS_STATUS CodechalEncodeAvcEncG12::SetupROISurface()
5136 {
5137     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5138 
5139     CODECHAL_ENCODE_FUNCTION_ENTER;
5140 
5141     MOS_LOCK_PARAMS readOnly;
5142     memset(&readOnly, 0, sizeof(readOnly));
5143     readOnly.ReadOnly = 1;
5144     uint32_t * dataPtr = (uint32_t *)m_osInterface->pfnLockResource(m_osInterface, &BrcBuffers.sBrcRoiSurface.OsResource, &readOnly);
5145     if (!dataPtr)
5146     {
5147         eStatus = MOS_STATUS_INVALID_HANDLE;
5148         return eStatus;
5149     }
5150 
5151     uint32_t bufferWidthInByte  = BrcBuffers.sBrcRoiSurface.dwPitch;
5152     uint32_t bufferHeightInByte = MOS_ALIGN_CEIL((m_downscaledHeightInMb4x << 2), 8);
5153     uint32_t numMBs = m_picWidthInMb * m_picHeightInMb;
5154     for (uint32_t uMB = 0; uMB <= numMBs; uMB++)
5155     {
5156         int32_t curMbY = uMB / m_picWidthInMb;
5157         int32_t curMbX = uMB - curMbY * m_picWidthInMb;
5158 
5159         uint32_t outdata = 0;
5160         for (int32_t roiIdx = (m_avcPicParam->NumROI - 1); roiIdx >= 0; roiIdx--)
5161         {
5162             int32_t qpLevel;
5163             if (bROIValueInDeltaQP)
5164             {
5165                 qpLevel = -m_avcPicParam->ROI[roiIdx].PriorityLevelOrDQp;
5166             }
5167             else
5168             {
5169                 // QP Level sent to ROI surface is (priority * 6)
5170                 qpLevel = m_avcPicParam->ROI[roiIdx].PriorityLevelOrDQp * 6;
5171             }
5172 
5173             if (qpLevel == 0)
5174             {
5175                 continue;
5176             }
5177 
5178             if ((curMbX >= (int32_t)m_avcPicParam->ROI[roiIdx].Left) && (curMbX < (int32_t)m_avcPicParam->ROI[roiIdx].Right) &&
5179                 (curMbY >= (int32_t)m_avcPicParam->ROI[roiIdx].Top) && (curMbY < (int32_t)m_avcPicParam->ROI[roiIdx].Bottom))
5180             {
5181                 outdata = 15 | ((qpLevel & 0xFF) << 8);
5182             }
5183             else if (bROISmoothEnabled)
5184             {
5185                 if ((curMbX >= (int32_t)m_avcPicParam->ROI[roiIdx].Left - 1) && (curMbX < (int32_t)m_avcPicParam->ROI[roiIdx].Right + 1) &&
5186                     (curMbY >= (int32_t)m_avcPicParam->ROI[roiIdx].Top - 1) && (curMbY < (int32_t)m_avcPicParam->ROI[roiIdx].Bottom + 1))
5187                 {
5188                     outdata = 14 | ((qpLevel & 0xFF) << 8);
5189                 }
5190                 else if ((curMbX >= (int32_t)m_avcPicParam->ROI[roiIdx].Left - 2) && (curMbX < (int32_t)m_avcPicParam->ROI[roiIdx].Right + 2) &&
5191                     (curMbY >= (int32_t)m_avcPicParam->ROI[roiIdx].Top - 2) && (curMbY < (int32_t)m_avcPicParam->ROI[roiIdx].Bottom + 2))
5192                 {
5193                     outdata = 13 | ((qpLevel & 0xFF) << 8);
5194                 }
5195                 else if ((curMbX >= (int32_t)m_avcPicParam->ROI[roiIdx].Left - 3) && (curMbX < (int32_t)m_avcPicParam->ROI[roiIdx].Right + 3) &&
5196                     (curMbY >= (int32_t)m_avcPicParam->ROI[roiIdx].Top - 3) && (curMbY < (int32_t)m_avcPicParam->ROI[roiIdx].Bottom + 3))
5197                 {
5198                     outdata = 12 | ((qpLevel & 0xFF) << 8);
5199                 }
5200             }
5201         }
5202         dataPtr[(curMbY * (bufferWidthInByte >> 2)) + curMbX] = outdata;
5203     }
5204 
5205     m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.sBrcRoiSurface.OsResource);
5206 
5207     uint32_t bufferSize = bufferWidthInByte * bufferHeightInByte;
5208     CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5209         &BrcBuffers.sBrcRoiSurface.OsResource,
5210         CodechalDbgAttr::attrInput,
5211         "ROI",
5212         bufferSize,
5213         0,
5214         CODECHAL_MEDIA_STATE_MB_BRC_UPDATE)));
5215     return eStatus;
5216 }
5217 
SendPrologWithFrameTracking(PMOS_COMMAND_BUFFER cmdBuffer,bool frameTracking,MHW_MI_MMIOREGISTERS * mmioRegister)5218 MOS_STATUS CodechalEncodeAvcEncG12::SendPrologWithFrameTracking(
5219     PMOS_COMMAND_BUFFER         cmdBuffer,
5220     bool                        frameTracking,
5221     MHW_MI_MMIOREGISTERS       *mmioRegister)
5222 {
5223     if (MOS_VE_SUPPORTED(m_osInterface) && cmdBuffer->Attributes.pAttriVe)
5224     {
5225         PMOS_CMD_BUF_ATTRI_VE attriExt =
5226                 (PMOS_CMD_BUF_ATTRI_VE)(cmdBuffer->Attributes.pAttriVe);
5227         attriExt->bUseVirtualEngineHint = true;
5228         attriExt->VEngineHintParams.NeedSyncWithPrevious = 1;
5229     }
5230 
5231     return CodechalEncodeAvcEnc::SendPrologWithFrameTracking(cmdBuffer, frameTracking, mmioRegister);
5232 }
5233 
ResizeOnResChange()5234 void CodechalEncodeAvcEncG12::ResizeOnResChange()
5235 {
5236     CODECHAL_ENCODE_FUNCTION_ENTER;
5237 
5238     CodechalEncoderState::ResizeOnResChange();
5239 
5240     // need to re-allocate surfaces according to resolution
5241     m_swScoreboardState->ReleaseResources();
5242 }
5243 
InitKernelStateMe()5244 MOS_STATUS CodechalEncodeAvcEncG12::InitKernelStateMe()
5245 {
5246     m_hmeKernel = MOS_New(CodechalKernelHmeG12, this);
5247     CODECHAL_ENCODE_CHK_NULL_RETURN(m_hmeKernel);
5248     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Initialize(
5249         GetCommonKernelHeaderAndSizeG12,
5250         m_kernelBase,
5251         m_kuidCommon));
5252     return MOS_STATUS_SUCCESS;
5253 }
5254 
UpdateCmdBufAttribute(PMOS_COMMAND_BUFFER cmdBuffer,bool renderEngineInUse)5255 MOS_STATUS CodechalEncodeAvcEncG12::UpdateCmdBufAttribute(
5256     PMOS_COMMAND_BUFFER cmdBuffer,
5257     bool                renderEngineInUse)
5258 {
5259     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5260 
5261     // should not be there. Will remove it in the next change
5262     CODECHAL_ENCODE_FUNCTION_ENTER;
5263     if (MOS_VE_SUPPORTED(m_osInterface) && cmdBuffer->Attributes.pAttriVe)
5264     {
5265         PMOS_CMD_BUF_ATTRI_VE attriExt =
5266             (PMOS_CMD_BUF_ATTRI_VE)(cmdBuffer->Attributes.pAttriVe);
5267 
5268         memset((void *)attriExt, 0, sizeof(MOS_CMD_BUF_ATTRI_VE));
5269         attriExt->bUseVirtualEngineHint =
5270             attriExt->VEngineHintParams.NeedSyncWithPrevious = !renderEngineInUse;
5271     }
5272 
5273     return eStatus;
5274 }
5275 
AddMediaVfeCmd(PMOS_COMMAND_BUFFER cmdBuffer,SendKernelCmdsParams * params)5276 MOS_STATUS CodechalEncodeAvcEncG12::AddMediaVfeCmd(
5277     PMOS_COMMAND_BUFFER cmdBuffer,
5278     SendKernelCmdsParams *params)
5279 {
5280     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
5281 
5282     MHW_VFE_PARAMS_G12 vfeParams = {};
5283     vfeParams.pKernelState              = params->pKernelState;
5284     vfeParams.eVfeSliceDisable          = MHW_VFE_SLICE_ALL;
5285     vfeParams.dwMaximumNumberofThreads  = m_encodeVfeMaxThreads;
5286     vfeParams.bFusedEuDispatch          = false; // legacy mode
5287 
5288     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaVfeCmd(cmdBuffer, &vfeParams));
5289 
5290     return MOS_STATUS_SUCCESS;
5291 }
5292 
5293 #if USE_CODECHAL_DEBUG_TOOL
KernelDebugDumps()5294 MOS_STATUS CodechalEncodeAvcEncG12::KernelDebugDumps()
5295 {
5296     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5297     CODECHAL_DEBUG_TOOL(
5298         if (m_hmeEnabled) {
5299             CODECHAL_ME_OUTPUT_PARAMS meOutputParams;
5300 
5301             memset((void *)&meOutputParams, 0, sizeof(meOutputParams));
5302             meOutputParams.psMeMvBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer);
5303             meOutputParams.psMeDistortionBuffer =
5304                 m_4xMeDistortionBufferSupported ?
5305                 m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : nullptr;
5306             meOutputParams.b16xMeInUse = false;
5307             meOutputParams.b32xMeInUse = false;
5308             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5309                 &meOutputParams.psMeMvBuffer->OsResource,
5310                 CodechalDbgAttr::attrOutput,
5311                 "MvData",
5312                 meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch,
5313                 m_hmeKernel ? m_hmeKernel->Get4xMeMvBottomFieldOffset() : (uint32_t)m_meMvBottomFieldOffset,
5314                 CODECHAL_MEDIA_STATE_4X_ME));
5315 
5316             if (meOutputParams.psMeDistortionBuffer)
5317             {
5318                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5319                     &meOutputParams.psMeDistortionBuffer->OsResource,
5320                     CodechalDbgAttr::attrOutput,
5321                     "MeDist",
5322                     meOutputParams.psMeDistortionBuffer->dwHeight *meOutputParams.psMeDistortionBuffer->dwPitch,
5323                     m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset,
5324                     CODECHAL_MEDIA_STATE_4X_ME));
5325             }
5326 
5327             if (m_16xMeEnabled)
5328             {
5329                 meOutputParams.psMeMvBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me16xMvDataBuffer);
5330                 CODECHAL_ENCODE_CHK_STATUS_RETURN(
5331                     m_debugInterface->DumpBuffer(
5332                         &meOutputParams.psMeMvBuffer->OsResource,
5333                         CodechalDbgAttr::attrOutput,
5334                         "MvData",
5335                         meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch,
5336                         m_hmeKernel ? m_hmeKernel->Get16xMeMvBottomFieldOffset() : (uint32_t)m_meMv16xBottomFieldOffset,
5337                         CODECHAL_MEDIA_STATE_16X_ME));
5338 
5339                 if (m_32xMeEnabled)
5340                 {
5341                     meOutputParams.psMeMvBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me32xMvDataBuffer);
5342                     CODECHAL_ENCODE_CHK_STATUS_RETURN(
5343                         m_debugInterface->DumpBuffer(
5344                             &meOutputParams.psMeMvBuffer->OsResource,
5345                             CodechalDbgAttr::attrOutput,
5346                             "MvData",
5347                             meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch,
5348                             m_hmeKernel ? m_hmeKernel->Get32xMeMvBottomFieldOffset() : (uint32_t)m_meMv32xBottomFieldOffset,
5349                             CODECHAL_MEDIA_STATE_32X_ME));
5350                 }
5351             }
5352         }
5353 
5354         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5355             &BrcBuffers.resBrcImageStatesWriteBuffer,
5356             CodechalDbgAttr::attrOutput,
5357             "ImgStateWrite",
5358             BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(),
5359             0,
5360             CODECHAL_MEDIA_STATE_BRC_UPDATE));
5361 
5362         if (!Mos_ResourceIsNull(&BrcBuffers.sBrcMbQpBuffer.OsResource))
5363         {
5364             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5365                 &BrcBuffers.sBrcMbQpBuffer.OsResource,
5366                 CodechalDbgAttr::attrOutput,
5367                 "MbQp",
5368                 BrcBuffers.sBrcMbQpBuffer.dwPitch*BrcBuffers.sBrcMbQpBuffer.dwHeight,
5369                 BrcBuffers.dwBrcMbQpBottomFieldOffset,
5370                 CODECHAL_MEDIA_STATE_MB_BRC_UPDATE));
5371         }
5372         if (bMbBrcEnabled)
5373         {
5374             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5375                 &BrcBuffers.resBrcHistoryBuffer,
5376                 CodechalDbgAttr::attrOutput,
5377                 "HistoryWrite",
5378                 m_brcHistoryBufferSize,
5379                 0,
5380                 CODECHAL_MEDIA_STATE_MB_BRC_UPDATE));
5381         }
5382         if (BrcBuffers.pMbEncKernelStateInUse)
5383         {
5384             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
5385                 CODECHAL_MEDIA_STATE_BRC_UPDATE,
5386                 BrcBuffers.pMbEncKernelStateInUse));
5387         }
5388         if (m_mbencBrcBufferSize > 0)
5389         {
5390             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5391                 &BrcBuffers.resMbEncBrcBuffer,
5392                 CodechalDbgAttr::attrOutput,
5393                 "MbEncBRCWrite",
5394                 m_mbencBrcBufferSize,
5395                 0,
5396                 CODECHAL_MEDIA_STATE_BRC_UPDATE));
5397         }
5398 
5399         if (m_mbStatsSupported) {
5400             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5401                 &m_resMbStatsBuffer,
5402                 CodechalDbgAttr::attrOutput,
5403                 "MBStatsSurf",
5404                 m_picWidthInMb * m_frameFieldHeightInMb * 16 * sizeof(uint32_t),
5405                 CodecHal_PictureIsBottomField(m_currOriginalPic) ? m_mbStatsBottomFieldOffset : 0,
5406                 CODECHAL_MEDIA_STATE_4X_SCALING));
5407         }
5408 
5409         else if (m_flatnessCheckEnabled) {
5410             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5411                 &m_flatnessCheckSurface.OsResource,
5412                 CodechalDbgAttr::attrOutput,
5413                 "FlatnessChkSurf",
5414                 ((CodecHal_PictureIsField(m_currOriginalPic)) ? m_flatnessCheckSurface.dwHeight / 2 : m_flatnessCheckSurface.dwHeight) * m_flatnessCheckSurface.dwPitch,
5415                 CodecHal_PictureIsBottomField(m_currOriginalPic) ? (m_flatnessCheckSurface.dwPitch * m_flatnessCheckSurface.dwHeight >> 1) : 0,
5416                 CODECHAL_MEDIA_STATE_4X_SCALING));
5417         }
5418         if (bMbQpDataEnabled) {
5419             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5420                 &sMbQpDataSurface.OsResource,
5421                 CodechalDbgAttr::attrInput,
5422                 "MbQp",
5423                 sMbQpDataSurface.dwHeight*sMbQpDataSurface.dwPitch,
5424                 0,
5425                 CODECHAL_MEDIA_STATE_ENC_QUALITY));
5426         }
5427 
5428         if (bMbSpecificDataEnabled) {
5429             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5430                 &resMbSpecificDataBuffer[m_currRecycledBufIdx],
5431                 CodechalDbgAttr::attrInput,
5432                 "MbSpecificData",
5433                 m_picWidthInMb*m_frameFieldHeightInMb * 16,
5434                 0,
5435                 CODECHAL_MEDIA_STATE_ENC_QUALITY));
5436         }
5437 
5438         uint8_t       index;
5439         CODEC_PICTURE refPic;
5440         if (bUseWeightedSurfaceForL0) {
5441             refPic = m_avcSliceParams->RefPicList[LIST_0][0];
5442             index = m_picIdx[refPic.FrameIdx].ucPicIdx;
5443 
5444             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
5445                 &m_refList[index]->sRefBuffer,
5446                 CodechalDbgAttr::attrEncodeRawInputSurface,
5447                 "WP_In_L0"));
5448             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
5449                 &WeightedPredOutputPicSelectList[LIST_0].sBuffer,
5450                 CodechalDbgAttr::attrEncodeRawInputSurface,
5451                 "WP_Out_L0"));
5452 
5453         } if (bUseWeightedSurfaceForL1) {
5454 
5455             refPic = m_avcSliceParams->RefPicList[LIST_1][0];
5456             index = m_picIdx[refPic.FrameIdx].ucPicIdx;
5457 
5458             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
5459                 &m_refList[index]->sRefBuffer,
5460                 CodechalDbgAttr::attrEncodeRawInputSurface,
5461                 "WP_In_L1"));
5462 
5463             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
5464                 &WeightedPredOutputPicSelectList[LIST_1].sBuffer,
5465                 CodechalDbgAttr::attrEncodeRawInputSurface,
5466                 "WP_Out_L1"));
5467         }
5468 
5469         if (m_feiEnable) {
5470             if (m_avcFeiPicParams->bMBQp) {
5471                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5472                     &m_avcFeiPicParams->resMBQp,
5473                     CodechalDbgAttr::attrInput,
5474                     "MbQp",
5475                     m_picWidthInMb * m_frameFieldHeightInMb + 3,
5476                     0,
5477                     CODECHAL_MEDIA_STATE_ENC_QUALITY));
5478             }
5479             if (m_avcFeiPicParams->MVPredictorEnable) {
5480                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5481                     &m_avcFeiPicParams->resMVPredictor,
5482                     CodechalDbgAttr::attrInput,
5483                     "MvPredictor",
5484                     m_picWidthInMb * m_frameFieldHeightInMb * 40,
5485                     0,
5486                     CODECHAL_MEDIA_STATE_ENC_QUALITY));
5487             }
5488         }
5489         if (m_arbitraryNumMbsInSlice) {
5490             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5491                 &m_sliceMapSurface[m_currRecycledBufIdx].OsResource,
5492                 CodechalDbgAttr::attrInput,
5493                 "SliceMapSurf",
5494                 m_sliceMapSurface[m_currRecycledBufIdx].dwPitch * m_frameFieldHeightInMb,
5495                 0,
5496                 CODECHAL_MEDIA_STATE_ENC_QUALITY));
5497         }
5498 
5499         // Dump SW scoreboard surface
5500         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
5501             &(m_swScoreboardState->GetCurSwScoreboardSurface())->OsResource,
5502             CodechalDbgAttr::attrOutput,
5503             "Out",
5504             (m_swScoreboardState->GetCurSwScoreboardSurface())->dwHeight * (m_swScoreboardState->GetCurSwScoreboardSurface())->dwPitch,
5505             0,
5506             CODECHAL_MEDIA_STATE_SW_SCOREBOARD_INIT));)
5507 
5508         return eStatus;
5509 }
5510 
PopulateBrcInitParam(void * cmd)5511 MOS_STATUS CodechalEncodeAvcEncG12::PopulateBrcInitParam(
5512     void *cmd)
5513 {
5514     CODECHAL_DEBUG_FUNCTION_ENTER;
5515 
5516     CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
5517 
5518     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
5519     {
5520         return MOS_STATUS_SUCCESS;
5521     }
5522 
5523     CodechalEncodeAvcEncG12::BrcInitResetCurbe *curbe = (CodechalEncodeAvcEncG12::BrcInitResetCurbe *)cmd;
5524 
5525     if (m_pictureCodingType == I_TYPE)
5526     {
5527         m_avcPar->MBBRCEnable          = bMbBrcEnabled;
5528         m_avcPar->MBRC                 = bMbBrcEnabled;
5529         m_avcPar->BitRate              = curbe->m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate;
5530         m_avcPar->InitVbvFullnessInBit = curbe->m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits;
5531         m_avcPar->MaxBitRate           = curbe->m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate;
5532         m_avcPar->VbvSzInBit           = curbe->m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits;
5533         m_avcPar->AvbrAccuracy         = curbe->m_brcInitResetCurbeCmd.m_dw10.m_avbrAccuracy;
5534         m_avcPar->AvbrConvergence      = curbe->m_brcInitResetCurbeCmd.m_dw11.m_avbrConvergence;
5535         m_avcPar->SlidingWindowSize    = curbe->m_brcInitResetCurbeCmd.m_dw22.m_slidingWindowSize;
5536         m_avcPar->LongTermInterval     = curbe->m_brcInitResetCurbeCmd.m_dw24.m_longTermInterval;
5537     }
5538 
5539     return MOS_STATUS_SUCCESS;
5540 }
5541 
PopulateBrcUpdateParam(void * cmd)5542 MOS_STATUS CodechalEncodeAvcEncG12::PopulateBrcUpdateParam(
5543     void *cmd)
5544 {
5545     CODECHAL_DEBUG_FUNCTION_ENTER;
5546 
5547     CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
5548 
5549     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
5550     {
5551         return MOS_STATUS_SUCCESS;
5552     }
5553 
5554     CodechalEncodeAvcEncG12::FrameBrcUpdateCurbe *curbe = (CodechalEncodeAvcEncG12::FrameBrcUpdateCurbe *)cmd;
5555 
5556     if (m_pictureCodingType == I_TYPE)
5557     {
5558         m_avcPar->EnableMultipass     = (curbe->m_frameBrcUpdateCurbeCmd.m_dw5.m_maxNumPAKs > 0) ? 1 : 0;
5559         m_avcPar->MaxNumPakPasses     = curbe->m_frameBrcUpdateCurbeCmd.m_dw5.m_maxNumPAKs;
5560         m_avcPar->SlidingWindowEnable = curbe->m_frameBrcUpdateCurbeCmd.m_dw6.m_enableSlidingWindow;
5561         m_avcPar->FrameSkipEnable     = curbe->m_frameBrcUpdateCurbeCmd.m_dw6.m_enableForceToSkip;
5562         m_avcPar->UserMaxFrame        = curbe->m_frameBrcUpdateCurbeCmd.m_dw19.m_userMaxFrame;
5563     }
5564     else
5565     {
5566         m_avcPar->UserMaxFrameP = curbe->m_frameBrcUpdateCurbeCmd.m_dw19.m_userMaxFrame;
5567     }
5568 
5569     return MOS_STATUS_SUCCESS;
5570 }
5571 
PopulateEncParam(uint8_t meMethod,void * cmd)5572 MOS_STATUS CodechalEncodeAvcEncG12::PopulateEncParam(
5573     uint8_t meMethod,
5574     void    *cmd)
5575 {
5576     CODECHAL_DEBUG_FUNCTION_ENTER;
5577 
5578     CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
5579 
5580     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
5581     {
5582         return MOS_STATUS_SUCCESS;
5583     }
5584 
5585     MbencCurbe *curbe = (MbencCurbe *)cmd;
5586 
5587     if (m_pictureCodingType == I_TYPE)
5588     {
5589         m_avcPar->MRDisableQPCheck = MRDisableQPCheck[m_targetUsage];
5590         m_avcPar->AllFractional =
5591             CODECHAL_ENCODE_AVC_AllFractional_Common[m_targetUsage & 0x7];
5592         m_avcPar->DisableAllFractionalCheckForHighRes =
5593             CODECHAL_ENCODE_AVC_DisableAllFractionalCheckForHighRes_Common[m_targetUsage & 0x7];
5594         m_avcPar->EnableAdaptiveSearch              = curbe->m_curbe.DW37.m_adaptiveEn;
5595         m_avcPar->EnableFBRBypass                   = curbe->m_curbe.DW4.m_enableFBRBypass;
5596         m_avcPar->BlockBasedSkip                    = curbe->m_curbe.DW3.m_blockBasedSkipEnable;
5597         m_avcPar->MADEnableFlag                     = curbe->m_curbe.DW34.m_madEnableFlag;
5598         m_avcPar->MBTextureThreshold                = curbe->m_curbe.DW60.m_mbTextureThreshold;
5599         m_avcPar->EnableMBFlatnessCheckOptimization = curbe->m_curbe.DW34.m_enableMBFlatnessChkOptimization;
5600         m_avcPar->EnableArbitrarySliceSize          = curbe->m_curbe.DW34.m_arbitraryNumMbsPerSlice;
5601         m_avcPar->RefThresh                         = curbe->m_curbe.DW38.m_refThreshold;
5602         m_avcPar->EnableWavefrontOptimization       = curbe->m_curbe.DW4.m_enableWavefrontOptimization;
5603         m_avcPar->MaxLenSP                          = curbe->m_curbe.DW2.m_lenSP;
5604         m_avcPar->DisableExtendedMvCostRange        = !curbe->m_curbe.DW1.m_extendedMvCostRange;
5605     }
5606     else if (m_pictureCodingType == P_TYPE)
5607     {
5608         m_avcPar->MEMethod                             = meMethod;
5609         m_avcPar->HMECombineLen                        = HMECombineLen[m_targetUsage];
5610         m_avcPar->FTQBasedSkip                         = FTQBasedSkip[m_targetUsage];
5611         m_avcPar->MultiplePred                         = MultiPred[m_targetUsage];
5612         m_avcPar->EnableAdaptiveIntraScaling           = bAdaptiveIntraScalingEnable;
5613         m_avcPar->StaticFrameIntraCostScalingRatioP    = 240;
5614         m_avcPar->SubPelMode                           = curbe->m_curbe.DW3.m_subPelMode;
5615         m_avcPar->HMECombineOverlap                    = curbe->m_curbe.DW36.m_hmeCombineOverlap;
5616         m_avcPar->SearchX                              = curbe->m_curbe.DW5.m_refWidth;
5617         m_avcPar->SearchY                              = curbe->m_curbe.DW5.m_refHeight;
5618         m_avcPar->SearchControl                        = curbe->m_curbe.DW3.m_searchCtrl;
5619         m_avcPar->EnableAdaptiveTxDecision             = curbe->m_curbe.DW34.m_enableAdaptiveTxDecision;
5620         m_avcPar->TxDecisionThr                        = curbe->m_curbe.DW60.m_txDecisonThreshold;
5621         m_avcPar->EnablePerMBStaticCheck               = curbe->m_curbe.DW34.m_enablePerMBStaticCheck;
5622         m_avcPar->EnableAdaptiveSearchWindowSize       = curbe->m_curbe.DW34.m_enableAdaptiveSearchWindowSize;
5623         m_avcPar->EnableIntraCostScalingForStaticFrame = curbe->m_curbe.DW4.m_enableIntraCostScalingForStaticFrame;
5624         m_avcPar->BiMixDisable                         = curbe->m_curbe.DW0.m_biMixDis;
5625         m_avcPar->SurvivedSkipCost                     = (curbe->m_curbe.DW7.m_nonSkipZMvAdded << 1) + curbe->m_curbe.DW7.m_nonSkipModeAdded;
5626         m_avcPar->UniMixDisable                        = curbe->m_curbe.DW1.m_uniMixDisable;
5627     }
5628     else if (m_pictureCodingType == B_TYPE)
5629     {
5630         m_avcPar->BMEMethod                         = meMethod;
5631         m_avcPar->HMEBCombineLen                    = HMEBCombineLen[m_targetUsage];
5632         m_avcPar->StaticFrameIntraCostScalingRatioB = 200;
5633         m_avcPar->BSearchX                          = curbe->m_curbe.DW5.m_refWidth;
5634         m_avcPar->BSearchY                          = curbe->m_curbe.DW5.m_refHeight;
5635         m_avcPar->BSearchControl                    = curbe->m_curbe.DW3.m_searchCtrl;
5636         m_avcPar->BSkipType                         = curbe->m_curbe.DW3.m_skipType;
5637         m_avcPar->DirectMode                        = curbe->m_curbe.DW34.m_bDirectMode;
5638         m_avcPar->BiWeight                          = curbe->m_curbe.DW1.m_biWeight;
5639     }
5640 
5641     return MOS_STATUS_SUCCESS;
5642 }
5643 
PopulatePakParam(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER secondLevelBatchBuffer)5644 MOS_STATUS CodechalEncodeAvcEncG12::PopulatePakParam(
5645     PMOS_COMMAND_BUFFER cmdBuffer,
5646     PMHW_BATCH_BUFFER   secondLevelBatchBuffer)
5647 {
5648     CODECHAL_DEBUG_FUNCTION_ENTER;
5649 
5650     CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
5651 
5652     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
5653     {
5654         return MOS_STATUS_SUCCESS;
5655     }
5656 
5657     uint8_t         *data = nullptr;
5658     MOS_LOCK_PARAMS lockFlags;
5659     MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
5660     lockFlags.ReadOnly = 1;
5661 
5662     if (cmdBuffer != nullptr)
5663     {
5664         data = (uint8_t*)(cmdBuffer->pCmdPtr - (mhw_vdbox_mfx_g12_X::MFX_AVC_IMG_STATE_CMD::byteSize / sizeof(uint32_t)));
5665     }
5666     else if (secondLevelBatchBuffer != nullptr)
5667     {
5668         data = secondLevelBatchBuffer->pData;
5669     }
5670     else
5671     {
5672         data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx], &lockFlags);
5673     }
5674 
5675     CODECHAL_DEBUG_CHK_NULL(data);
5676 
5677     mhw_vdbox_mfx_g12_X::MFX_AVC_IMG_STATE_CMD mfxCmd;
5678     mfxCmd = *(mhw_vdbox_mfx_g12_X::MFX_AVC_IMG_STATE_CMD *)(data);
5679 
5680     if (m_pictureCodingType == I_TYPE)
5681     {
5682         m_avcPar->TrellisQuantizationEnable         = mfxCmd.DW5.TrellisQuantizationEnabledTqenb;
5683         m_avcPar->EnableAdaptiveTrellisQuantization = mfxCmd.DW5.TrellisQuantizationEnabledTqenb;
5684         m_avcPar->TrellisQuantizationRounding       = mfxCmd.DW5.TrellisQuantizationRoundingTqr;
5685         m_avcPar->TrellisQuantizationChromaDisable  = mfxCmd.DW5.TrellisQuantizationChromaDisableTqchromadisable;
5686         m_avcPar->ExtendedRhoDomainEn               = mfxCmd.DW17.ExtendedRhodomainStatisticsEnable;
5687     }
5688 
5689     if (data && (cmdBuffer == nullptr) && (secondLevelBatchBuffer == nullptr))
5690     {
5691         m_osInterface->pfnUnlockResource(
5692             m_osInterface,
5693             &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx]);
5694     }
5695 
5696     return MOS_STATUS_SUCCESS;
5697 }
5698 #endif
5699