1 /*
2 * Copyright (c) 2011-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 //!
24 //! \file     codechal_decode_vc1.cpp
25 //! \brief    Implements the decode interface extension for VC1.
26 //! \details  Implements all functions required by CodecHal for VC1 decoding.
27 //!
28 
29 #include "codechal_decoder.h"
30 #include "codechal_decode_vc1.h"
31 #include "codechal_secure_decode_interface.h"
32 #include "codechal_mmc_decode_vc1.h"
33 #include "hal_oca_interface.h"
34 #if USE_CODECHAL_DEBUG_TOOL
35 #include <sstream>
36 #include <fstream>
37 #include "codechal_debug.h"
38 #endif
39 #define CODECHAL_DECODE_VC1_EOS                    ((uint32_t)(-1))
40 
41 // picture layer bits
42 #define CODECHAL_DECODE_VC1_BITS_INTERPFRM         1
43 #define CODECHAL_DECODE_VC1_BITS_FRMCNT            2
44 #define CODECHAL_DECODE_VC1_BITS_RANGEREDFRM       1
45 #define CODECHAL_DECODE_VC1_BITS_FPTYPE            3
46 #define CODECHAL_DECODE_VC1_BITS_BF                7
47 #define CODECHAL_DECODE_VC1_BITS_PQINDEX           5
48 #define CODECHAL_DECODE_VC1_BITS_HALFQP            1
49 #define CODECHAL_DECODE_VC1_BITS_PQUANTIZER        1
50 #define CODECHAL_DECODE_VC1_BITS_RESPIC            2
51 #define CODECHAL_DECODE_VC1_BITS_INTERLCF          1
52 
53 #define CODECHAL_DECODE_VC1_BITS_TRANSACFRM_1      1
54 #define CODECHAL_DECODE_VC1_BITS_TRANSACFRM_2      1
55 #define CODECHAL_DECODE_VC1_BITS_TRANSACFRM2_1     1
56 #define CODECHAL_DECODE_VC1_BITS_TRANSACFRM2_2     1
57 #define CODECHAL_DECODE_VC1_BITS_TRANSDCTAB        1
58 
59 #define CODECHAL_DECODE_VC1_BITS_FRSKIP            1
60 #define CODECHAL_DECODE_VC1_BITS_TFCNTR            8
61 #define CODECHAL_DECODE_VC1_BITS_FCM_1             1
62 #define CODECHAL_DECODE_VC1_BITS_FCM_2             1
63 #define CODECHAL_DECODE_VC1_BITS_TFF               1
64 #define CODECHAL_DECODE_VC1_BITS_RFF               1
65 #define CODECHAL_DECODE_VC1_BITS_REPSEQHDR         1
66 #define CODECHAL_DECODE_VC1_BITS_UVSAMP            1
67 #define CODECHAL_DECODE_VC1_BITS_POSTPROC          2
68 #define CODECHAL_DECODE_VC1_BITS_DQUANTFRM         1
69 #define CODECHAL_DECODE_VC1_BITS_DQPROFILE         2
70 #define CODECHAL_DECODE_VC1_BITS_DQSBEDGE          2
71 #define CODECHAL_DECODE_VC1_BITS_DQDBEDGE          2
72 #define CODECHAL_DECODE_VC1_BITS_DQBILEVEL         1
73 #define CODECHAL_DECODE_VC1_BITS_PQDIFF            3
74 #define CODECHAL_DECODE_VC1_BITS_ABSPQ             5
75 
76 #define CODECHAL_DECODE_VC1_BITS_MVMODEBIT         1
77 #define CODECHAL_DECODE_VC1_BITS_LUMSCALE          6
78 #define CODECHAL_DECODE_VC1_BITS_LUMSHIFT          6
79 #define CODECHAL_DECODE_VC1_BITS_MVTAB             2
80 #define CODECHAL_DECODE_VC1_BITS_CBPTAB            2
81 #define CODECHAL_DECODE_VC1_BITS_TTMBF             1
82 #define CODECHAL_DECODE_VC1_BITS_TTFRM             2
83 #define CODECHAL_DECODE_VC1_BITS_ABSMQ             5
84 
85 #define CODECHAL_DECODE_VC1_BITS_RPTFRM            2
86 #define CODECHAL_DECODE_VC1_BITS_RNDCTRL           1
87 
88 #define CODECHAL_DECODE_VC1_BITS_PS_PRESENT        1
89 #define CODECHAL_DECODE_VC1_BITS_PS_HOFFSET        18
90 #define CODECHAL_DECODE_VC1_BITS_PS_VOFFSET        18
91 #define CODECHAL_DECODE_VC1_BITS_PS_WIDTH          14
92 #define CODECHAL_DECODE_VC1_BITS_PS_HEIGHT         14
93 
94 #define CODECHAL_DECODE_VC1_BITS_REFDIST           2
95 #define CODECHAL_DECODE_VC1_BITS_REFFIELD          1
96 
97 #define CODECHAL_DECODE_VC1_BITS_NUMREF            1
98 #define CODECHAL_DECODE_VC1_BITS_MBMODETAB         3
99 #define CODECHAL_DECODE_VC1_BITS_CBPTAB_INTERLACE  3
100 #define CODECHAL_DECODE_VC1_BITS_4MVBPTAB          2
101 #define CODECHAL_DECODE_VC1_BITS_2MVBPTAB          2
102 
103 #define CODECHAL_DECODE_VC1_BITS_4MVSWITCH         1
104 #define CODECHAL_DECODE_VC1_BITS_INTCOMP           1
105 
106 // bitplane
107 #define CODECHAL_DECODE_VC1_BITS_BITPLANE_INVERT   1
108 #define CODECHAL_DECODE_VC1_BITS_BITPLANE_ROWSKIP  1
109 #define CODECHAL_DECODE_VC1_BITS_BITPLANE_COLSKIP  1
110 
111 // slice layer bits
112 #define CODECHAL_DECODE_VC1_BITS_SC_SUFFIX         8
113 #define CODECHAL_DECODE_VC1_BITS_SLICE_ADDR        9
114 #define CODECHAL_DECODE_VC1_BITS_PIC_HEADER_FLAG   1
115 #define CODECHAL_DECODE_VC1_BITS_SLICE_HEADER      ((CODECHAL_DECODE_VC1_BITS_SC_SUFFIX) + (CODECHAL_DECODE_VC1_BITS_SLICE_ADDR) + (CODECHAL_DECODE_VC1_BITS_PIC_HEADER_FLAG))
116 
117 #define CODECHAL_DECODE_VC1_MV_OFFEST_SIZE         3
118 
GetBits(uint32_t bitsRead,uint32_t & value)119 MOS_STATUS CodechalDecodeVc1::GetBits(uint32_t bitsRead, uint32_t &value)
120 {
121     value = GetBits(bitsRead);
122 
123     if (CODECHAL_DECODE_VC1_EOS == value)
124     {
125         return MOS_STATUS_UNKNOWN;
126     }
127 
128     return MOS_STATUS_SUCCESS;
129 }
130 
GetVLC(const uint32_t * table,uint32_t & value)131 MOS_STATUS CodechalDecodeVc1::GetVLC(const uint32_t* table, uint32_t &value)
132 {
133     value = GetVLC(table);
134     if (CODECHAL_DECODE_VC1_EOS == value)
135     {
136         return MOS_STATUS_UNKNOWN;
137     }
138     return MOS_STATUS_SUCCESS;
139 }
140 
SkipWords(uint32_t dwordNumber,uint32_t & value)141 MOS_STATUS CodechalDecodeVc1::SkipWords(uint32_t dwordNumber, uint32_t &value)
142 {
143     for (uint32_t i = 0; i < dwordNumber; i++)
144     {
145         value = SkipBits(16);
146         if (CODECHAL_DECODE_VC1_EOS == value)
147         {
148             return MOS_STATUS_UNKNOWN;
149         }
150     }
151 
152     return MOS_STATUS_SUCCESS;
153 }
154 
SkipBits(uint32_t bits,uint32_t & value)155 MOS_STATUS CodechalDecodeVc1::SkipBits(uint32_t bits, uint32_t &value)
156 {
157     if ((bits) > 0)
158     {
159         value = SkipBits(bits);
160         if (CODECHAL_DECODE_VC1_EOS == value)
161         {
162             return MOS_STATUS_UNKNOWN;
163         }
164     }
165     return MOS_STATUS_SUCCESS;
166 }
167 
168 typedef union _CODECHAL_DECODE_VC1_BITSTREAM_BUFFER_VALUE
169 {
170     uint32_t u32Value;
171     uint8_t  u8Value[sizeof(uint32_t)];
172 } CODECHAL_DECODE_VC1_BITSTREAM_VALUE, *PCODECHAL_DECODE_VC1_BITSTREAM_VALUE;
173 
174 typedef enum _CODECHAL_DECODE_VC1_MVMODE
175 {
176     CODECHAL_VC1_MVMODE_1MV_HALFPEL_BILINEAR,
177     CODECHAL_VC1_MVMODE_1MV_HALFPEL,
178     CODECHAL_VC1_MVMODE_1MV,
179     CODECHAL_VC1_MVMODE_MIXEDMV,
180     CODECHAL_VC1_MVMODE_IC          // Intensity Compensation
181 } CODECHAL_DECODE_VC1_MVMODE;
182 
183 typedef enum _CODECHAL_DECODE_VC1_BITPLANE_CODING_MODE
184 {
185     CODECHAL_VC1_BITPLANE_RAW,
186     CODECHAL_VC1_BITPLANE_NORMAL2,
187     CODECHAL_VC1_BITPLANE_DIFF2,
188     CODECHAL_VC1_BITPLANE_NORMAL6,
189     CODECHAL_VC1_BITPLANE_DIFF6,
190     CODECHAL_VC1_BITPLANE_ROWSKIP,
191     CODECHAL_VC1_BITPLANE_COLSKIP
192 } CODECHAL_DECODE_VC1_BITPLANE_CODING_MODE;
193 
194 static const uint32_t CODECHAL_DECODE_VC1_VldBitplaneModeTable[] =
195 {
196     4, /* max bits */
197     0, /* 1-bit codes */
198     2, /* 2-bit codes */
199     2, CODECHAL_VC1_BITPLANE_NORMAL2,
200     3, CODECHAL_VC1_BITPLANE_NORMAL6,
201     3, /* 3-bit codes */
202     1, CODECHAL_VC1_BITPLANE_DIFF2,
203     2, CODECHAL_VC1_BITPLANE_ROWSKIP,
204     3, CODECHAL_VC1_BITPLANE_COLSKIP,
205     2, /* 4-bit codes */
206     0, CODECHAL_VC1_BITPLANE_RAW,
207     1, CODECHAL_VC1_BITPLANE_DIFF6,
208     (uint32_t)-1
209 };
210 
211 static const uint32_t CODECHAL_DECODE_VC1_VldCode3x2Or2x3TilesTable[] =
212 {
213     13, /* max bits */
214     1,  /* 1-bit codes */
215     1, 0,
216     0,  /* 2-bit codes */
217     0,  /* 3-bit codes */
218     6,  /* 4-bit codes */
219     2, 1,
220     3, 2,
221     4, 4,
222     5, 8,
223 
224     6, 16,
225     7, 32,
226     0,  /* 5-bit codes */
227     1,  /* 6-bit codes */
228     (3 << 1) | 1, 63,
229     0,  /* 7-bit codes */
230     15, /* 8-bit codes */
231     0, 3,
232     1, 5,
233     2, 6,
234     3, 9,
235 
236     4, 10,
237     5, 12,
238     6, 17,
239     7, 18,
240 
241     8, 20,
242     9, 24,
243     10, 33,
244     11, 34,
245 
246     12, 36,
247     13, 40,
248     14, 48,
249     6, /* 9-bit codes */
250     (3 << 4) | 7, 31,
251     (3 << 4) | 6, 47,
252     (3 << 4) | 5, 55,
253     (3 << 4) | 4, 59,
254 
255     (3 << 4) | 3, 61,
256     (3 << 4) | 2, 62,
257     20, /* 10-bit codes */
258     (1 << 6) | 11, 11,
259     (1 << 6) | 7, 7,
260     (1 << 6) | 13, 13,
261     (1 << 6) | 14, 14,
262 
263     (1 << 6) | 19, 19,
264     (1 << 6) | 21, 21,
265     (1 << 6) | 22, 22,
266     (1 << 6) | 25, 25,
267 
268     (1 << 6) | 26, 26,
269     (1 << 6) | 28, 28,
270     (1 << 6) | 3, 35,
271     (1 << 6) | 5, 37,
272 
273     (1 << 6) | 6, 38,
274     (1 << 6) | 9, 41,
275     (1 << 6) | 10, 42,
276     (1 << 6) | 12, 44,
277 
278     (1 << 6) | 17, 49,
279     (1 << 6) | 18, 50,
280     (1 << 6) | 20, 52,
281     (1 << 6) | 24, 56,
282     0,  /* 11-bit codes */
283     0,  /* 12-bit codes */
284     15, /* 13-bit codes */
285     (3 << 8) | 14, 15,
286     (3 << 8) | 13, 23,
287     (3 << 8) | 12, 27,
288     (3 << 8) | 11, 29,
289 
290     (3 << 8) | 10, 30,
291     (3 << 8) | 9, 39,
292     (3 << 8) | 8, 43,
293     (3 << 8) | 7, 45,
294 
295     (3 << 8) | 6, 46,
296     (3 << 8) | 5, 51,
297     (3 << 8) | 4, 53,
298     (3 << 8) | 3, 54,
299 
300     (3 << 8) | 2, 57,
301     (3 << 8) | 1, 58,
302     (3 << 8) | 0, 60,
303     (uint32_t)-1
304 };
305 
306 static const uint32_t CODECHAL_DECODE_VC1_VldPictureTypeTable[] =
307 {
308     4,  /* max bits */
309     1, /* 1-bit codes */
310     0, vc1PFrame,
311     1, /* 2-bit codes */
312     2, vc1BFrame,
313     1, /* 3-bit codes */
314     6, vc1IFrame,
315     2, /* 4-bit codes */
316     14, vc1BIFrame,
317     15, vc1SkippedFrame,
318     (uint32_t)-1
319 };
320 
321 static const uint32_t CODECHAL_DECODE_VC1_VldBFractionTable[] =
322 {
323     7,  /* max bits */
324     0,  /* 1-bit codes */
325     0,  /* 2-bit codes */
326     7,  /* 3-bit codes */
327     0x00, 0,
328     0x01, 1,
329     0x02, 2,
330     0x03, 3,
331 
332     0x04, 4,
333     0x05, 5,
334     0x06, 6,
335     0,  /* 4-bit codes */
336     0,  /* 5-bit codes */
337     0,  /* 6-bit codes */
338     14, /* 7-bit codes */
339     0x70, 7,
340     0x71, 8,
341     0x72, 9,
342     0x73, 10,
343 
344     0x74, 11,
345     0x75, 12,
346     0x76, 13,
347     0x77, 14,
348 
349     0x78, 15,
350     0x79, 16,
351     0x7A, 17,
352     0x7B, 18,
353 
354     0x7C, 19,
355     0x7D, 20,
356     (uint32_t)-1
357 };
358 
359 static const uint32_t CODECHAL_DECODE_VC1_VldRefDistTable[] =
360 {
361     14, /* max bits */
362     1,  /* 1-bit codes */
363     0, 3,
364     1,  /* 2-bit codes */
365     2, 4,
366     1,  /* 3-bit codes */
367     6, 5,
368     1,  /* 4-bit codes */
369     14, 6,
370     1,  /* 5-bit codes */
371     30, 7,
372     1,  /* 6-bit codes */
373     62, 8,
374     1,  /* 7-bit codes */
375     126, 9,
376     1,  /* 8-bit codes */
377     254, 10,
378     1,  /* 9-bit codes */
379     510, 11,
380     1,  /* 10-bit codes */
381     1022, 12,
382     1,  /* 11-bit codes */
383     2046, 13,
384     1,  /* 12-bit codes */
385     4094, 14,
386     1,  /* 13-bit codes */
387     8190, 15,
388     1,  /* 14-bit codes */
389     16382, 16,
390     (uint32_t)-1
391 };
392 
393 // lookup tables for MVMODE
394 static const uint32_t CODECHAL_DECODE_VC1_LowRateMvModeTable[] =
395 {
396     CODECHAL_VC1_MVMODE_1MV_HALFPEL_BILINEAR,
397     CODECHAL_VC1_MVMODE_1MV,
398     CODECHAL_VC1_MVMODE_1MV_HALFPEL,
399     CODECHAL_VC1_MVMODE_MIXEDMV,
400     CODECHAL_VC1_MVMODE_IC
401 };
402 
403 static const uint32_t CODECHAL_DECODE_VC1_HighRateMvModeTable[] =
404 {
405     CODECHAL_VC1_MVMODE_1MV,
406     CODECHAL_VC1_MVMODE_MIXEDMV,
407     CODECHAL_VC1_MVMODE_1MV_HALFPEL,
408     CODECHAL_VC1_MVMODE_1MV_HALFPEL_BILINEAR,
409     CODECHAL_VC1_MVMODE_IC
410 };
411 
412 // lock up table for luma polarity (Interlaced picture)
413 static const CODECHAL_DECODE_VC1_I_LUMA_BLOCKS CODECHAL_DECODE_VC1_LumaBlocks_I[16] =
414 {
415     { 4,{ 0 }, 0, 0, 0 },{ 3,{ 0 }, 2, 4, 6 },{ 3,{ 0 }, 0, 4, 6 },{ 2,{ 4 }, 6, 0, 2 },{ 3,{ 0 }, 0, 2, 6 },{ 2,{ 2 }, 6, 0, 4 },{ 2,{ 0 }, 6, 2, 4 },{ 3,{ 1 }, 0, 2, 4 },
416     { 3,{ 0 }, 0, 2, 4 },{ 2,{ 2 }, 4, 0, 6 },{ 2,{ 0 }, 4, 2, 6 },{ 3,{ 1 }, 0, 2, 6 },{ 2,{ 0 }, 2, 4, 6 },{ 3,{ 1 }, 0, 4, 6 },{ 3,{ 1 }, 2, 4, 6 },{ 4,{ 1 }, 0, 0, 0 }
417 };
418 
419 // lock up table for luma inter-coded blocks (Progressive picture)
420 static const CODECHAL_DECODE_VC1_P_LUMA_BLOCKS CODECHAL_DECODE_VC1_LumaBlocks_P[16] =
421 {
422     { 4, 0, 0, 0 },{ 3, 0, 2, 4 },{ 3, 0, 2, 6 },{ 2, 0, 2, 0 },{ 3, 0, 4, 6 },{ 2, 0, 4, 0 },{ 2, 0, 6, 0 },{ 0, 0, 0, 0 },
423     { 3, 2, 4, 6 },{ 2, 2, 4, 0 },{ 2, 2, 6, 0 },{ 0, 0, 0, 0 },{ 2, 4, 6, 0 },{ 0, 0, 0, 0 },{ 0, 0, 0, 0 },{ 0, 0, 0, 0 }
424 };
425 
426 static const int16_t CODECHAL_DECODE_VC1_MV_OFFEST[CODECHAL_DECODE_VC1_MV_OFFEST_SIZE][2] = { { 0, 2 },{ -2, 0 },{ 0, 0 } };
427 static const uint8_t CODECHAL_DECODE_VC1_RndTb[4] = { 0, 0, 0, 1 };
428 
429 const CODECHAL_DECODE_VC1_OLP_STATIC_DATA g_cInit_CODECHAL_DECODE_VC1_OLP_STATIC_DATA =
430 {
431     // uint32_t 0
432     {
433         { 0 }                                                // Reserved
434     },
435 
436     // uint32_t 1
437     {
438         {
439             16,                                              // BlockWidth in Byte
440             16                                               // BlockHeight in Byte
441         }
442     },
443 
444     // uint32_t 2
445     {
446         {
447             0,                                               // Profile
448             0,                                               // RangeExpansionFlag
449             0,                                               // UpsamplingFlag
450             0,                                               // InterlaceFieldFlag
451             0,                                               // RangeMapUV
452             0,                                               // RangeMapUVFlag
453             0,                                               // RangeMapY
454             0,                                               // RangeMapYFlag
455             0                                                // ComponentFlag
456         }
457     },
458 
459     // uint32_t 3
460     {
461         { 0 }                                                // ComponentFlag
462     },
463 
464     // uint32_t 4
465     {
466         { 0 }                                                // SourceDataBindingIndex (default: CODECHAL_DECODE_VC1_OLP_SRC_Y)
467     },
468 
469     // uint32_t 5
470     {
471         { 3 }                                                // DestDataBindingIndex (default: CODECHAL_DECODE_VC1_OLP_DST_Y)
472     },
473 
474     // uint32_t 6
475     {
476         { 0 }                                                // Reserved
477     },
478 
479     // uint32_t 7
480     {
481         { 0 }                                                // Reserved
482     }
483 };
484 
485 //==<Functions>=======================================================
486 
PackMotionVectorsMedian3(int16_t mv1,int16_t mv2,int16_t mv3)487 int16_t CodechalDecodeVc1::PackMotionVectorsMedian3(int16_t mv1, int16_t mv2, int16_t mv3)
488 {
489     if (mv1 > mv2)
490     {
491         if (mv2 > mv3)
492             return mv2;
493         if (mv1 > mv3)
494             return mv3;
495         return mv1;
496     }
497     if (mv1 > mv3)
498         return mv1;
499     if (mv2 > mv3)
500         return mv3;
501     return mv2;
502 }
503 
PackMotionVectorsMedian4(int16_t mv1,int16_t mv2,int16_t mv3,int16_t mv4)504 int16_t CodechalDecodeVc1::PackMotionVectorsMedian4(int16_t mv1, int16_t mv2, int16_t mv3, int16_t mv4)
505 {
506     int16_t max = mv1, min = mv1;
507 
508     if (mv2 > max)
509     {
510         max = mv2;
511     }
512     else if (mv2 < min)
513     {
514         min = mv2;
515     }
516 
517     if (mv3 > max)
518     {
519         max = mv3;
520     }
521     else if (mv3 < min)
522     {
523         min = mv3;
524     }
525 
526     if (mv4 > max)
527     {
528         max = mv4;
529     }
530     else if (mv4 < min)
531     {
532         min = mv4;
533     }
534 
535     return (mv1 + mv2 + mv3 + mv4 - max - min) / 2;
536 }
537 
PackMotionVectorsChroma4MvP(uint16_t intraFlags,int16_t * lmv,int16_t * cmv)538 void CodechalDecodeVc1::PackMotionVectorsChroma4MvP(uint16_t intraFlags, int16_t *lmv, int16_t *cmv)
539 {
540     int16_t mvX = 0, mvY = 0;
541 
542     if (CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8NumIntercodedBlocks == 4)
543     {
544         mvX = PackMotionVectorsMedian4(lmv[0], lmv[2], lmv[4], lmv[6]);
545         mvY = PackMotionVectorsMedian4(lmv[1], lmv[3], lmv[5], lmv[7]);
546     }
547     else if (CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8NumIntercodedBlocks == 3)
548     {
549         mvX = PackMotionVectorsMedian3(lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex1],
550             lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex2],
551             lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex3]);
552         mvY = PackMotionVectorsMedian3(lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex1 + 1],
553             lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex2 + 1],
554             lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex3 + 1]);
555     }
556     else if (CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8NumIntercodedBlocks == 2)
557     {
558         mvX = (lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex1] + lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex2]) / 2;
559         mvY = (lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex1 + 1] + lmv[CODECHAL_DECODE_VC1_LumaBlocks_P[intraFlags].u8MvIndex2 + 1]) / 2;
560     }
561 
562     cmv[0] = CODECHAL_DECODE_VC1_CHROMA_MV(mvX);
563     cmv[1] = CODECHAL_DECODE_VC1_CHROMA_MV(mvY);
564 }
565 
PackMotionVectorsChroma4MvI(uint16_t fieldSelect,uint16_t currentField,bool fastUVMotionCompensation,int16_t * lmv,int16_t * cmv)566 uint8_t CodechalDecodeVc1::PackMotionVectorsChroma4MvI(
567     uint16_t    fieldSelect,
568     uint16_t    currentField,
569     bool        fastUVMotionCompensation,
570     int16_t      *lmv,
571     int16_t      *cmv)
572 {
573     int16_t mvX = 0, mvY = 0;
574     uint8_t polarity;
575     uint16_t offset, offsetIndex;
576     uint8_t index1, index2, index3, index4;
577 
578     if ((currentField == PICTURE_FRAME) || (currentField == PICTURE_INTERLACED_FRAME))
579     {
580         offsetIndex = 2;
581     }
582     else
583     {
584         offsetIndex = currentField - 1;
585     }
586 
587     if (offsetIndex >= CODECHAL_DECODE_VC1_MV_OFFEST_SIZE)
588     {
589         CODECHAL_DECODE_ASSERTMESSAGE("ERROR: offsetIndex out of bounds (%d, max %d)", offsetIndex, CODECHAL_DECODE_VC1_MV_OFFEST_SIZE);
590         return 0;
591     }
592 
593     if (CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8NumSamePolarity == 4)
594     {
595         polarity = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8Polarity ? 1 : 0;
596         offset = CODECHAL_DECODE_VC1_MV_OFFEST[offsetIndex][polarity];
597 
598         // Unadjust Luma
599         lmv[1] += offset;
600         lmv[3] += offset;
601         lmv[5] += offset;
602         lmv[7] += offset;
603 
604         mvX = PackMotionVectorsMedian4(lmv[0], lmv[2], lmv[4], lmv[6]);
605         mvY = PackMotionVectorsMedian4(lmv[1], lmv[3], lmv[5], lmv[7]);
606     }
607     else if (CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8NumSamePolarity == 3)
608     {
609         polarity = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8Polarity ? 1 : 0;
610         index2 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex1;
611         index3 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex2;
612         index4 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex3;
613         index1 = 12 - (index2 + index3 + index4); // Sum of indices is 12
614 
615                                                           // Unadjust Luma of current polarity
616         offset = CODECHAL_DECODE_VC1_MV_OFFEST[offsetIndex][polarity];
617         lmv[index2 + 1] += offset;
618         lmv[index3 + 1] += offset;
619         lmv[index4 + 1] += offset;
620 
621         if (PICTURE_TOP_FIELD != currentField && PICTURE_BOTTOM_FIELD != currentField)
622         {
623             CODECHAL_DECODE_ASSERTMESSAGE("Invalid Parameters.");
624         }
625         else
626         {
627             // Unadjust Luma of opposite polarity
628             offset = CODECHAL_DECODE_VC1_MV_OFFEST[currentField - 1][1 - polarity];
629         }
630 
631         lmv[index1 + 1] += offset;
632 
633         mvX = PackMotionVectorsMedian3(lmv[index2],
634             lmv[index3],
635             lmv[index4]);
636         mvY = PackMotionVectorsMedian3(lmv[index2 + 1],
637             lmv[index3 + 1],
638             lmv[index4 + 1]);
639     }
640     else
641     {
642         if (currentField == PICTURE_TOP_FIELD)
643         {
644             index1 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex0;
645             index2 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex1;
646             index3 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex2;
647             index4 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex3;
648             polarity = 0;
649         }
650         else
651         {
652             index1 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex2;
653             index2 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex3;
654             index3 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex0;
655             index4 = CODECHAL_DECODE_VC1_LumaBlocks_I[fieldSelect].u8MvIndex1;
656             polarity = 1;
657         }
658 
659         // Unadjust Luma of current polarity
660         offset = CODECHAL_DECODE_VC1_MV_OFFEST[offsetIndex][polarity];
661         lmv[index1 + 1] += offset;
662         lmv[index2 + 1] += offset;
663 
664         // Unadjust Luma of opposite polarity
665         offset = CODECHAL_DECODE_VC1_MV_OFFEST[offsetIndex][1 - polarity];
666         lmv[index3 + 1] += offset;
667         lmv[index4 + 1] += offset;
668 
669         mvX = (lmv[index1] + lmv[index2]) / 2;
670         mvY = (lmv[index1 + 1] + lmv[index2 + 1]) / 2;
671         offset = 0;
672     }
673 
674     cmv[0] = CODECHAL_DECODE_VC1_CHROMA_MV(mvX);
675     cmv[1] = CODECHAL_DECODE_VC1_CHROMA_MV(mvY);
676 
677     if (fastUVMotionCompensation)
678     {
679         cmv[0] = CODECHAL_DECODE_VC1_FAST_CHROMA_MV(cmv[0]);
680         cmv[1] = CODECHAL_DECODE_VC1_FAST_CHROMA_MV(cmv[1]);
681     }
682 
683     return polarity;
684 }
685 
PackMotionVectors(PMHW_VDBOX_VC1_MB_STATE vc1MbState,int16_t * mv,int16_t * packedLumaMvs,int16_t * packedChromaMv)686 void CodechalDecodeVc1::PackMotionVectors(
687     PMHW_VDBOX_VC1_MB_STATE         vc1MbState,
688     int16_t                           *mv,
689     int16_t                           *packedLumaMvs,
690     int16_t                           *packedChromaMv)
691 {
692     uint16_t selectFlags;
693 
694     PCODEC_VC1_MB_PARAMS mb = vc1MbState->pMb;
695     uint8_t b4Mv = mb->mb_type.motion_4mv;
696     uint8_t mfwd = mb->mb_type.motion_forward;
697     uint8_t mbwd = mb->mb_type.motion_backward;
698     uint8_t mtype = mb->mb_type.motion_type;
699     vc1MbState->bMotionSwitch = 0;
700     PCODEC_VC1_PIC_PARAMS vc1PicParams = vc1MbState->pVc1PicParams;
701 
702     bool isPPicture = m_mfxInterface->IsVc1PPicture(
703         vc1PicParams->CurrPic,
704         vc1PicParams->picture_fields.is_first_field,
705         vc1PicParams->picture_fields.picture_type) ? true : false;
706 
707     if (packedLumaMvs == nullptr)
708     {
709         CODECHAL_DECODE_ASSERTMESSAGE("ERROR: packedLumaMvs is nullptr");
710         return;
711     }
712 
713     if (packedChromaMv == nullptr)
714     {
715         CODECHAL_DECODE_ASSERTMESSAGE("ERROR: packedChromaMv is nullptr");
716         return;
717     }
718 
719     packedLumaMvs[0] = packedLumaMvs[2] = packedLumaMvs[4] = packedLumaMvs[6] = 0;
720     packedLumaMvs[1] = packedLumaMvs[3] = packedLumaMvs[5] = packedLumaMvs[7] = 0;
721 
722     packedChromaMv[0] = CODECHAL_DECODE_VC1_CHROMA_MV(packedLumaMvs[0]);
723     packedChromaMv[1] = CODECHAL_DECODE_VC1_CHROMA_MV(packedLumaMvs[1]);
724 
725     if (b4Mv)
726     {
727         packedLumaMvs[0] = (int16_t)mv[CodechalDecodeRstFirstForwHorz];
728         packedLumaMvs[1] = (int16_t)mv[CodechalDecodeRstFirstForwVert];
729         packedLumaMvs[2] = (int16_t)mv[CodechalDecodeRstFirstBackHorz];
730         packedLumaMvs[3] = (int16_t)mv[CodechalDecodeRstFirstBackVert];
731         packedLumaMvs[4] = (int16_t)mv[CodechalDecodeRstSecndForwHorz];
732         packedLumaMvs[5] = (int16_t)mv[CodechalDecodeRstSecndForwVert];
733         packedLumaMvs[6] = (int16_t)mv[CodechalDecodeRstSecndBackHorz];
734         packedLumaMvs[7] = (int16_t)mv[CodechalDecodeRstSecndBackVert];
735         if (vc1MbState->PicFlags == PICTURE_FRAME)
736         {
737             selectFlags = mb->pattern_code.block_luma_intra;
738             PackMotionVectorsChroma4MvP(selectFlags, packedLumaMvs, packedChromaMv);
739         }
740         else if (vc1MbState->PicFlags != PICTURE_INTERLACED_FRAME)
741         {
742             selectFlags = (mb->mb_type.value & 0xF000) >> 12;
743             vc1MbState->bFieldPolarity = PackMotionVectorsChroma4MvI(
744                 selectFlags,
745                 vc1MbState->PicFlags,
746                 vc1PicParams->fast_uvmc_flag ? true : false,
747                 packedLumaMvs,
748                 packedChromaMv);
749         }
750     }
751     else
752     {
753         // default settings for frame pictures, relevant Motion Vectors will be reset if needed
754         packedLumaMvs[0] = packedLumaMvs[2] = packedLumaMvs[4] = packedLumaMvs[6] = (int16_t)mv[CodechalDecodeRstFirstForwHorz];
755         packedLumaMvs[1] = packedLumaMvs[3] = packedLumaMvs[5] = packedLumaMvs[7] = (int16_t)mv[CodechalDecodeRstFirstForwVert];
756 
757         packedChromaMv[0] = CODECHAL_DECODE_VC1_CHROMA_MV(packedLumaMvs[0]);
758         packedChromaMv[1] = CODECHAL_DECODE_VC1_CHROMA_MV(packedLumaMvs[1]);
759 
760         if (vc1MbState->PicFlags == PICTURE_FRAME)
761         {
762             if (mbwd && mfwd)
763             {
764                 // Progressive, direct
765                 packedLumaMvs[2] = packedLumaMvs[6] = (int16_t)mv[CodechalDecodeRstSecndForwHorz];
766                 packedLumaMvs[3] = packedLumaMvs[7] = (int16_t)mv[CodechalDecodeRstSecndForwVert];
767             }
768         }
769         else
770         {
771             if (vc1MbState->PicFlags == PICTURE_INTERLACED_FRAME)
772             {
773                 packedLumaMvs[2] = packedLumaMvs[6] = (int16_t)mv[CodechalDecodeRstFirstBackHorz];
774                 packedLumaMvs[3] = packedLumaMvs[7] = (int16_t)mv[CodechalDecodeRstFirstBackVert];
775 
776                 if (mtype == CodechalDecodeMcFrame)
777                 {
778                     if (isPPicture)
779                     {
780                         packedLumaMvs[2] = packedLumaMvs[6] = packedLumaMvs[0];
781                         packedLumaMvs[3] = packedLumaMvs[7] = packedLumaMvs[1];
782                     }
783                 }
784                 else if (mtype == CodechalDecodeMcField)
785                 {
786                     packedLumaMvs[4] = (int16_t)mv[CodechalDecodeRstSecndForwHorz];
787                     packedLumaMvs[5] = (int16_t)mv[CodechalDecodeRstSecndForwVert];
788                     packedLumaMvs[6] = (int16_t)mv[CodechalDecodeRstSecndBackHorz];
789                     packedLumaMvs[7] = (int16_t)mv[CodechalDecodeRstSecndBackVert];
790                 }
791             }
792             else // Interlaced field
793             {
794                 uint8_t fieldPolarity2, offsetIndex;
795                 uint32_t i;
796                 int16_t offset;
797 
798                 i = 0;
799                 fieldPolarity2 = 0;
800                 offsetIndex = vc1MbState->PicFlags - 1;
801 
802                 if (offsetIndex >= CODECHAL_DECODE_VC1_MV_OFFEST_SIZE)
803                 {
804                     CODECHAL_DECODE_ASSERTMESSAGE("ERROR: offsetIndex out of bounds (%d, max %d)", offsetIndex, CODECHAL_DECODE_VC1_MV_OFFEST_SIZE);
805                     return;
806                 }
807 
808                 if (mfwd)
809                 {
810                     vc1MbState->bFieldPolarity = mb->mb_type.mvert_field_sel_0;
811                     fieldPolarity2 = mb->mb_type.mvert_field_sel_1;
812                     i = 1;
813                 }
814 
815                 if (mbwd)
816                 {
817                     vc1MbState->bFieldPolarity = mb->mb_type.mvert_field_sel_1;
818                     fieldPolarity2 = mb->mb_type.mvert_field_sel_0;
819                     i = 3;
820 
821                     packedLumaMvs[2] = packedLumaMvs[6] = (int16_t)mv[CodechalDecodeRstFirstBackHorz];
822                     packedLumaMvs[3] = packedLumaMvs[7] = (int16_t)mv[CodechalDecodeRstFirstBackVert];
823                 }
824 
825                 // Unadjust luma
826                 offset = CODECHAL_DECODE_VC1_MV_OFFEST[offsetIndex][vc1MbState->bFieldPolarity];
827                 packedLumaMvs[i] += offset;
828 
829                 // Unadjust Luma of opposite polarity
830                 offset = CODECHAL_DECODE_VC1_MV_OFFEST[offsetIndex][fieldPolarity2];
831                 packedLumaMvs[4 - i] += offset;
832 
833                 if (isPPicture)
834                 {
835                     packedLumaMvs[3] = packedLumaMvs[5] = packedLumaMvs[7] = packedLumaMvs[1];
836 
837                     if (mb->mb_type.mvert_field_sel_0)
838                     {
839                         mb->mb_type.mvert_field_sel_0 = 1;
840                         mb->mb_type.mvert_field_sel_1 = 1;
841                         mb->mb_type.mvert_field_sel_2 = 1;
842                         mb->mb_type.mvert_field_sel_3 = 1;
843                     }
844                 }
845                 else
846                 {
847                     packedLumaMvs[5] = packedLumaMvs[1];
848                     packedLumaMvs[7] = packedLumaMvs[3];
849                 }
850 
851                 // Derive unadjusted chroma
852                 packedChromaMv[0] = CODECHAL_DECODE_VC1_CHROMA_MV(packedLumaMvs[i - 1]);
853                 packedChromaMv[1] = CODECHAL_DECODE_VC1_CHROMA_MV(packedLumaMvs[i]);
854             }
855         }
856     }
857 
858     if ((vc1MbState->PicFlags == PICTURE_INTERLACED_FRAME) && (mtype == CodechalDecodeMcField))
859     {
860         uint16_t mvFieldSel = (mb->mb_type.value & 0xF000) >> 12;
861         uint16_t concealForSel2 = 0;
862         uint16_t concealForSel3 = 0;
863 
864         if (!mb->mb_type.mvert_field_sel_2)
865         {
866             if (!(packedLumaMvs[4] || packedLumaMvs[5]))
867             {
868                 concealForSel2 = 1;
869             }
870             packedLumaMvs[5] += 4;
871         }
872         if (!mb->mb_type.mvert_field_sel_3)
873         {
874             if (!(packedLumaMvs[6] || packedLumaMvs[7]))
875             {
876                 concealForSel3 = 1;
877             }
878             packedLumaMvs[7] += 4;
879         }
880 
881         if (!(mfwd && mbwd) && !b4Mv)
882         {
883             uint16_t topPredBit, botPredBit;
884             uint16_t topPred, botPred;
885 
886             if (mfwd && !mbwd)
887             {
888                 vc1MbState->bMotionSwitch = mb->mb_type.mvert_field_sel_1;
889 
890                 topPredBit = 0;
891                 botPredBit = (vc1MbState->bMotionSwitch) ? 3 : 2;
892             }
893             else
894             {
895                 vc1MbState->bMotionSwitch = mb->mb_type.mvert_field_sel_0;
896 
897                 topPredBit = 1;
898                 botPredBit = (vc1MbState->bMotionSwitch) ? 2 : 3;
899             }
900 
901             topPred = mvFieldSel & (1 << topPredBit);
902             botPred = mvFieldSel & (1 << botPredBit);
903 
904             if (isPPicture)
905             {
906                 packedLumaMvs[0] = packedLumaMvs[2] = packedLumaMvs[topPredBit * 2];
907                 packedLumaMvs[1] = packedLumaMvs[3] = packedLumaMvs[(topPredBit * 2) + 1];
908 
909                 packedLumaMvs[4] = packedLumaMvs[6] = packedLumaMvs[botPredBit * 2];
910                 packedLumaMvs[5] = packedLumaMvs[7] = packedLumaMvs[(botPredBit * 2) + 1];
911 
912                 mb->mb_type.value &= 0x0FFF;
913 
914                 if (topPred)
915                 {
916                     mb->mb_type.mvert_field_sel_0 = 1;
917                     mb->mb_type.mvert_field_sel_1 = 1;
918                 }
919 
920                 if (botPred)
921                 {
922                     mb->mb_type.mvert_field_sel_2 = 1;
923                     mb->mb_type.mvert_field_sel_3 = 1;
924                 }
925             }
926             else if (vc1MbState->bMotionSwitch) // && !P_TYPE
927             {
928                 if (concealForSel2)
929                 {
930                     packedLumaMvs[4] = packedLumaMvs[6];
931                     packedLumaMvs[5] = packedLumaMvs[7];
932                 }
933                 if (concealForSel3)
934                 {
935                     packedLumaMvs[6] = packedLumaMvs[4];
936                     packedLumaMvs[7] = packedLumaMvs[5];
937                 }
938 
939                 mb->mb_type.value &= 0x0FFF;
940 
941                 if (topPred)
942                 {
943                     if (topPredBit == 1)
944                     {
945                         mb->mb_type.mvert_field_sel_1 = 1;
946                     }
947                     else // topPredBit == 0
948                     {
949                         mb->mb_type.mvert_field_sel_0 = 1;
950                     }
951                 }
952 
953                 if (botPred)
954                 {
955                     if (botPredBit == 3)
956                     {
957                         mb->mb_type.mvert_field_sel_2 = 1;
958                     }
959                     else // botPredBit == 2
960                     {
961                         mb->mb_type.mvert_field_sel_3 = 1;
962                     }
963                 }
964             }
965         }
966     }
967 
968     if (vc1PicParams->fast_uvmc_flag)
969     {
970         packedChromaMv[0] = CODECHAL_DECODE_VC1_FAST_CHROMA_MV(packedChromaMv[0]);
971         packedChromaMv[1] = CODECHAL_DECODE_VC1_FAST_CHROMA_MV(packedChromaMv[1]);
972     }
973 }
974 
InitializeUnequalFieldSurface(uint8_t refListIdx,bool nullHwInUse)975 MOS_STATUS CodechalDecodeVc1::InitializeUnequalFieldSurface(
976     uint8_t                     refListIdx,
977     bool                        nullHwInUse)
978 {
979     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
980 
981     CODECHAL_DECODE_FUNCTION_ENTER;
982 
983     CODEC_PICTURE picture = m_vc1RefList[refListIdx]->RefPic;
984 
985     bool isBPicture = m_mfxInterface->IsVc1BPicture(
986                           m_vc1PicParams->CurrPic,
987                           m_vc1PicParams->picture_fields.is_first_field,
988                           m_vc1PicParams->picture_fields.picture_type)
989                           ? true
990                           : false;
991 
992     if (m_vc1RefList[refListIdx]->bUnequalFieldSurfaceValid)
993     {
994         // Reset the Surface Valid flag for second field of B picture
995         if (m_vc1PicParams->CurrPic.FrameIdx == refListIdx && isBPicture)
996         {
997             m_vc1RefList[refListIdx]->bUnequalFieldSurfaceValid = false;
998         }
999 
1000         // Unequal field surface may be re-used
1001         return eStatus;
1002     }
1003 
1004     uint32_t currUnequalFieldIdx, prevRefListIdx;
1005     if (m_vc1PicParams->CurrPic.FrameIdx == refListIdx && isBPicture)
1006     {
1007         currUnequalFieldIdx = m_unequalFieldSurfaceForBType;
1008     }
1009     else
1010     {
1011         currUnequalFieldIdx = m_currUnequalFieldSurface;
1012 
1013         m_currUnequalFieldSurface =
1014             (m_currUnequalFieldSurface + 1) % (CODECHAL_DECODE_VC1_UNEQUAL_FIELD_WA_SURFACES - 1);
1015 
1016         prevRefListIdx = m_unequalFieldRefListIdx[currUnequalFieldIdx];
1017 
1018         if (prevRefListIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1 &&
1019             m_vc1PicParams->CurrPic.FrameIdx != prevRefListIdx)
1020         {
1021             // Invalidate unequal field index for the old reference
1022             m_vc1RefList[prevRefListIdx]->bUnequalFieldSurfaceValid = false;
1023         }
1024     }
1025     // Set up new unequal field values
1026     m_vc1RefList[refListIdx]->bUnequalFieldSurfaceValid = true;
1027     m_vc1RefList[refListIdx]->dwUnequalFieldSurfaceIdx  = currUnequalFieldIdx;
1028     m_unequalFieldRefListIdx[currUnequalFieldIdx]       = refListIdx;
1029 
1030     if (m_vc1PicParams->CurrPic.FrameIdx != refListIdx)
1031     {
1032         MOS_SURFACE srcSurface;
1033         MOS_ZeroMemory(&srcSurface, sizeof(MOS_SURFACE));
1034         srcSurface.Format = Format_NV12;
1035         srcSurface.OsResource = m_vc1RefList[refListIdx]->resRefPic;
1036         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &srcSurface));
1037 
1038         // Format the unequal field reference
1039         CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture(
1040             srcSurface,
1041             m_unequalFieldSurface[currUnequalFieldIdx],
1042             false,
1043             nullHwInUse));
1044     }
1045 
1046     return eStatus;
1047 }
1048 
1049 /*----------------------------------------------------------------------------
1050 | Name      : CodechalDecodeVc1::FormatUnequalFieldPicture
1051 | Purpose   : Formats the destination surface, in the pack case the UV surface
1052 |               is moved to be adjacent to the UV surface such that NV12
1053 |               formatting is maintained when the surface is returned to SW,
1054 |               in the unpack case the UV surface is moved to be 32-pixel rows
1055 |               away from the Y surface so that during decoding HW will not
1056 |               overwrite the UV surface
1057 | Arguments : dwSrcSurfaceHandle - surface handle for the source surface
1058 |             dwDstSurfaceHandle - surface handle for the destination surface
1059 |             bPack - boolean value determining whether or not the source
1060 |               surface should be packed or unpacked
1061 | Returns   : MOS_STATUS - for success or failure
1062 \---------------------------------------------------------------------------*/
FormatUnequalFieldPicture(MOS_SURFACE srcSurface,MOS_SURFACE dstSurface,bool pack,bool nullHwInUse)1063 MOS_STATUS CodechalDecodeVc1::FormatUnequalFieldPicture(
1064     MOS_SURFACE                 srcSurface,
1065     MOS_SURFACE                 dstSurface,
1066     bool                        pack,
1067     bool                        nullHwInUse)
1068 {
1069     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
1070 
1071     CODECHAL_DECODE_FUNCTION_ENTER;
1072 
1073     uint32_t uvblockWidth = 16;
1074     uint32_t uvblockHeight = 16;
1075     uint32_t uvblockSize = uvblockWidth * uvblockHeight;
1076     uint32_t frameHeight = MOS_ALIGN_CEIL(m_height, 16);
1077     uint32_t ysize = srcSurface.dwPitch * MOS_ALIGN_CEIL(frameHeight, MOS_YTILE_H_ALIGNMENT);
1078 
1079     MOS_COMMAND_BUFFER cmdBuffer;
1080     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1081 
1082     // Send command buffer header at the beginning (OS dependent)
1083     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
1084 
1085     uint32_t frameSize = MOS_ALIGN_CEIL((srcSurface.dwPitch * (frameHeight + frameHeight / 2)), MOS_YTILE_H_ALIGNMENT);
1086 
1087     // Copy Y data first
1088     if (m_hwInterface->m_noHuC)
1089     {
1090         CodechalDataCopyParams dataCopyParams;
1091         MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
1092         dataCopyParams.srcResource = &srcSurface.OsResource;
1093         dataCopyParams.srcSize = ysize;
1094         dataCopyParams.srcOffset = 0;
1095         dataCopyParams.dstResource = &dstSurface.OsResource;
1096         dataCopyParams.dstSize = frameSize;
1097         dataCopyParams.dstOffset = 0;
1098 
1099         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
1100     }
1101     else
1102     {
1103         // Stream object params
1104         CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
1105             &cmdBuffer,                 // pCmdBuffer
1106             &srcSurface.OsResource,    // presSrc
1107             &dstSurface.OsResource,    // presDst
1108             ysize,                   // u32CopyLength
1109             0,                          // u32CopyInputOffset
1110             0));                        // u32CopyOutputOffset
1111     }
1112 
1113     // Copy 1 MB row of UV
1114     uint32_t srcOffset, dstOffset;
1115     for (uint32_t x = 0; x < srcSurface.dwPitch; x += uvblockWidth)
1116     {
1117         if (pack)
1118         {
1119             srcOffset = LinearToYTiledAddress(
1120                 x,
1121                 frameHeight + MOS_YTILE_H_ALIGNMENT,
1122                 srcSurface.dwPitch);
1123             dstOffset = LinearToYTiledAddress(
1124                 x,
1125                 frameHeight,
1126                 dstSurface.dwPitch);
1127         }
1128         else
1129         {
1130             srcOffset = LinearToYTiledAddress(
1131                 x,
1132                 frameHeight,
1133                 srcSurface.dwPitch);
1134             dstOffset = LinearToYTiledAddress(
1135                 x,
1136                 frameHeight + MOS_YTILE_H_ALIGNMENT,
1137                 dstSurface.dwPitch);
1138         }
1139 
1140         if (m_hwInterface->m_noHuC)
1141         {
1142             CodechalDataCopyParams dataCopyParams;
1143             MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
1144             dataCopyParams.srcResource = &srcSurface.OsResource;
1145             dataCopyParams.srcSize = uvblockSize;
1146             dataCopyParams.srcOffset = srcOffset;
1147             dataCopyParams.dstResource = &dstSurface.OsResource;
1148             dataCopyParams.dstSize = frameSize;
1149             dataCopyParams.dstOffset = dstOffset;
1150 
1151             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
1152         }
1153         else
1154         {
1155             // Stream object params
1156             CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
1157                 &cmdBuffer,                 // pCmdBuffer
1158                 &srcSurface.OsResource,    // presSrc
1159                 &dstSurface.OsResource,    // presDst
1160                 uvblockSize,             // u32CopyLength
1161                 srcOffset,               // u32CopyInputOffset
1162                 dstOffset));             // u32CopyOutputOffset
1163         }
1164     }
1165 
1166     uint32_t uvsize = srcSurface.dwPitch * MOS_ALIGN_CEIL(((frameHeight / 2) - uvblockHeight), MOS_YTILE_H_ALIGNMENT);
1167 
1168     if (pack)
1169     {
1170         srcOffset = srcSurface.dwPitch *
1171             (frameHeight + MOS_YTILE_H_ALIGNMENT + uvblockHeight);
1172         dstOffset = dstSurface.dwPitch * (frameHeight + uvblockHeight);
1173     }
1174     else
1175     {
1176         srcOffset = srcSurface.dwPitch * (frameHeight + uvblockHeight);
1177         dstOffset = dstSurface.dwPitch *
1178             (frameHeight + MOS_YTILE_H_ALIGNMENT + uvblockHeight);
1179     }
1180 
1181     if (m_hwInterface->m_noHuC)
1182     {
1183         CodechalDataCopyParams dataCopyParams;
1184         MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
1185         dataCopyParams.srcResource = &srcSurface.OsResource;
1186         dataCopyParams.srcSize = uvsize;
1187         dataCopyParams.srcOffset = srcOffset;
1188         dataCopyParams.dstResource = &dstSurface.OsResource;
1189         dataCopyParams.dstSize = frameSize;
1190         dataCopyParams.dstOffset = dstOffset;
1191 
1192         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
1193     }
1194     else
1195     {
1196         // Stream object params
1197         CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
1198             &cmdBuffer,                 // pCmdBuffer
1199             &srcSurface.OsResource,    // presSrc
1200             &dstSurface.OsResource,    // presDst
1201             uvsize,                  // u32CopyLength
1202             srcOffset,               // u32CopyInputOffset
1203             dstOffset));             // u32CopyOutputOffset
1204     }
1205 
1206     if (pack)
1207     {
1208         MOS_SYNC_PARAMS syncParams;
1209 
1210         syncParams = g_cInitSyncParams;
1211         syncParams.GpuContext = m_videoContext;
1212         syncParams.presSyncResource         = &m_destSurface.OsResource;
1213         syncParams.bReadOnly = false;
1214         syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1215         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1216 
1217         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1218         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1219 
1220         // Update the resource tag (s/w tag) for On-Demand Sync
1221         m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1222 
1223         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1224         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1225 
1226         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
1227 
1228         // Update the tag in GPU Sync status buffer (H/W Tag) to match the current S/W tag
1229         if (m_osInterface->bTagResourceSync)
1230         {
1231             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
1232         }
1233 
1234     }
1235     else
1236     {
1237         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1238         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1239         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
1240     }
1241 
1242     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1243         &cmdBuffer,
1244         nullptr));
1245 
1246     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1247 
1248     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, nullHwInUse));
1249 
1250     return eStatus;
1251 }
1252 
ConstructBistreamBuffer()1253 MOS_STATUS CodechalDecodeVc1::ConstructBistreamBuffer()
1254 {
1255     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
1256 
1257     CODECHAL_DECODE_FUNCTION_ENTER;
1258 
1259     if (m_hwInterface->m_noHuC)
1260     {
1261         CodechalDataCopyParams dataCopyParams;
1262         MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
1263         dataCopyParams.srcResource = &m_resDataBuffer;
1264         dataCopyParams.srcSize     = m_dataSize;
1265         dataCopyParams.srcOffset = 0;
1266         dataCopyParams.dstResource = &m_resPrivateBistreamBuffer;
1267         dataCopyParams.dstSize     = m_privateBistreamBufferSize;
1268         dataCopyParams.dstOffset = CODECHAL_DECODE_VC1_STUFFING_BYTES;
1269 
1270         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
1271 
1272         return MOS_STATUS_SUCCESS;
1273     }
1274 
1275     m_huCCopyInUse = true;
1276 
1277     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContextForWa));
1278     m_osInterface->pfnResetOsStates(m_osInterface);
1279     m_osInterface->pfnSetPerfTag(m_osInterface, (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE));
1280 
1281     MOS_COMMAND_BUFFER cmdBuffer;
1282     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1283 
1284     // Send command buffer header at the beginning (OS dependent)
1285     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
1286 
1287     CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
1288         &cmdBuffer,                            // pCmdBuffer
1289         &m_resDataBuffer,                      // presSrc
1290         &m_resPrivateBistreamBuffer,           // presDst
1291         MOS_ALIGN_CEIL(m_dataSize, 16),        // u32CopyLength
1292         0,                                     // u32CopyInputOffset
1293         CODECHAL_DECODE_VC1_STUFFING_BYTES));  // u32CopyOutputOffset
1294 
1295     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1296     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1297     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1298         &cmdBuffer,
1299         &flushDwParams));
1300 
1301     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1302         &cmdBuffer,
1303         nullptr));
1304 
1305     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1306 
1307     MOS_SYNC_PARAMS syncParams;
1308 
1309     syncParams                  = g_cInitSyncParams;
1310     syncParams.GpuContext       = m_videoContext;
1311     syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1312 
1313     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1314 
1315     syncParams                  = g_cInitSyncParams;
1316     syncParams.GpuContext       = m_videoContextForWa;
1317     syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1318 
1319     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1320 
1321     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
1322 
1323     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext));
1324 
1325     return (MOS_STATUS)eStatus;
1326 }
1327 
HandleSkipFrame()1328 MOS_STATUS CodechalDecodeVc1::HandleSkipFrame()
1329 {
1330     MOS_COMMAND_BUFFER                  cmdBuffer;
1331     MHW_MI_FLUSH_DW_PARAMS              flushDwParams;
1332     MHW_GENERIC_PROLOG_PARAMS           genericPrologParams;
1333     MOS_SURFACE                         srcSurface;
1334     uint8_t                             fwdRefIdx;
1335     uint32_t                            surfaceSize;
1336     MOS_SYNC_PARAMS                     syncParams;
1337     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1338 
1339     CODECHAL_DECODE_FUNCTION_ENTER;
1340 
1341     fwdRefIdx = (uint8_t)m_vc1PicParams->ForwardRefIdx;
1342 
1343     MOS_ZeroMemory(&srcSurface, sizeof(MOS_SURFACE));
1344     srcSurface.Format      = Format_NV12;
1345     srcSurface.OsResource  = m_vc1RefList[fwdRefIdx]->resRefPic;
1346     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &srcSurface));
1347 
1348 #ifdef _MMC_SUPPORTED
1349     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceMmcMode(&m_destSurface, &srcSurface));
1350 #endif
1351 
1352         surfaceSize = ((srcSurface.OsResource.pGmmResInfo->GetArraySize()) > 1) ?
1353             ((uint32_t)(srcSurface.OsResource.pGmmResInfo->GetQPitchPlanar(GMM_PLANE_Y) *
1354                         srcSurface.OsResource.pGmmResInfo->GetRenderPitch())) :
1355             (uint32_t)(srcSurface.OsResource.pGmmResInfo->GetSizeMainSurface());
1356 
1357     // HuC is present
1358     if (m_hwInterface->m_noHuC)
1359     {
1360         CodechalDataCopyParams dataCopyParams;
1361         MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
1362         dataCopyParams.srcResource = &srcSurface.OsResource;
1363         dataCopyParams.srcSize     = surfaceSize;
1364         dataCopyParams.srcOffset = srcSurface.dwOffset;
1365         dataCopyParams.dstResource = &m_destSurface.OsResource;
1366         dataCopyParams.dstSize     = surfaceSize;
1367         dataCopyParams.dstOffset   = m_destSurface.dwOffset;
1368 
1369         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
1370     }
1371     else
1372     {
1373         m_huCCopyInUse = true;
1374 
1375         syncParams                  = g_cInitSyncParams;
1376         syncParams.GpuContext       = m_videoContext;
1377         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1378 
1379         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1380 
1381         syncParams                  = g_cInitSyncParams;
1382         syncParams.GpuContext       = m_videoContextForWa;
1383         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1384 
1385         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1386 
1387         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContextForWa));
1388         m_osInterface->pfnResetOsStates(m_osInterface);
1389 
1390         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1391 
1392         // Send command buffer header at the beginning (OS dependent)
1393         CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
1394 
1395         CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
1396             &cmdBuffer,                             // pCmdBuffer
1397             &srcSurface.OsResource,                 // presSrc
1398             &m_destSurface.OsResource,              // presDst
1399             surfaceSize,                            // u32CopyLength
1400             srcSurface.dwOffset,                    // u32CopyInputOffset
1401             m_destSurface.dwOffset));               // u32CopyOutputOffset
1402 
1403         syncParams                          = g_cInitSyncParams;
1404         syncParams.GpuContext               = m_videoContextForWa;
1405         syncParams.presSyncResource         = &m_destSurface.OsResource;
1406         syncParams.bReadOnly                = false;
1407         syncParams.bDisableDecodeSyncLock   = m_disableDecodeSyncLock;
1408         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1409 
1410         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1411         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1412 
1413         // Update the resource tag (s/w tag) for On-Demand Sync
1414         m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1415 
1416         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1417         if (m_osInterface->bTagResourceSync)
1418         {
1419             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
1420                 &cmdBuffer,
1421                 &syncParams));
1422         }
1423 
1424         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1425         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1426             &cmdBuffer,
1427             &flushDwParams));
1428 
1429         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1430                 &cmdBuffer,
1431                 nullptr));
1432 
1433         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1434 
1435         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
1436 
1437         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext));
1438     }
1439 
1440     return (MOS_STATUS)eStatus;
1441 }
1442 
PeekBits(uint32_t bitsRead)1443 uint32_t CodechalDecodeVc1::PeekBits(uint32_t bitsRead)
1444 {
1445     uint32_t value = 0;
1446 
1447     CODECHAL_DECODE_ASSERT((bitsRead) > 0 && (bitsRead) <= 32);
1448 
1449     uint32_t *cache       = m_bitstream.pu32Cache;
1450     int32_t   shiftOffset = m_bitstream.iBitOffset - (bitsRead);
1451 
1452     if (shiftOffset >= 0)
1453     {
1454         value = (*cache) >> (shiftOffset);
1455     }
1456     else
1457     {
1458         shiftOffset += 32;
1459         value = (cache[0] << (32 - shiftOffset)) + (cache[1] >> shiftOffset);
1460     }
1461 
1462     return (value & ((1 << bitsRead) - 1));
1463 }
1464 
UpdateBitstreamBuffer()1465 uint32_t CodechalDecodeVc1::UpdateBitstreamBuffer()
1466 {
1467     uint32_t *cache             = (uint32_t *)m_bitstream.CacheBuffer;
1468     uint32_t *cacheEnd          = m_bitstream.pu32CacheEnd;
1469     uint32_t *cacheDataEnd      = m_bitstream.pu32CacheDataEnd;
1470     uint32_t  zeroNum           = m_bitstream.u32ZeroNum;
1471     uint8_t * originalBitBuffer = m_bitstream.pOriginalBitBuffer;
1472     uint8_t * originalBufferEnd = m_bitstream.pOriginalBufferEnd;
1473 
1474     if (cacheDataEnd == cacheEnd)
1475     {
1476         *cache++ = *cacheEnd;
1477     }
1478 
1479     while (cache <= cacheEnd)
1480     {
1481         uint32_t leftByte;
1482         CODECHAL_DECODE_VC1_BITSTREAM_VALUE value;
1483         if (m_bitstream.bIsEBDU)
1484         {
1485             // for EBDU, set dwLeftByte to 4 to remove emulation prevention bytes in the later while loop
1486             leftByte = 4;
1487             value.u32Value = 0;
1488         }
1489         else
1490         {
1491             leftByte = 0;
1492             value.u8Value[3] = *originalBitBuffer++;
1493             value.u8Value[2] = *originalBitBuffer++;
1494             value.u8Value[1] = *originalBitBuffer++;
1495             value.u8Value[0] = *originalBitBuffer++;
1496         }
1497 
1498         while (leftByte)
1499         {
1500             if (originalBitBuffer >= originalBufferEnd) // End of the bitstream;
1501             {
1502                 *cache = value.u32Value;
1503                 m_bitstream.pu32Cache          = (uint32_t *)m_bitstream.CacheBuffer;
1504                 m_bitstream.u32ZeroNum         = zeroNum;
1505                 m_bitstream.pOriginalBitBuffer = originalBitBuffer;
1506                 m_bitstream.pu32CacheDataEnd   = cache;
1507                 m_bitstream.iBitOffsetEnd      = leftByte * 8;
1508                 return 0;
1509             }
1510 
1511             uint8_t data = *originalBitBuffer++;
1512 
1513             if (zeroNum < 2)
1514             {
1515                 zeroNum = data ? 0 : zeroNum + 1;
1516             }
1517             else if (zeroNum == 2)
1518             {
1519                 if (data == 0x03)
1520                 {
1521                     if (originalBitBuffer < originalBufferEnd)
1522                     {
1523                         data = *originalBitBuffer++;
1524                         zeroNum = (data == 0);
1525                     }
1526                     else
1527                     {
1528                         CODECHAL_DECODE_ASSERTMESSAGE("VC1 Bitstream Parsing Error: Incomplete bitstream.");
1529                         return(CODECHAL_DECODE_VC1_EOS);
1530                     }
1531 
1532                     if (data > 0x03)
1533                     {
1534                         CODECHAL_DECODE_ASSERTMESSAGE("VC1 Bitstream Parsing Error: Not a valid code 0x000003 %x.", data);
1535                         return(CODECHAL_DECODE_VC1_EOS);
1536                     }
1537                 }
1538                 else if (data == 0x02)
1539                 {
1540                     CODECHAL_DECODE_ASSERTMESSAGE("VC1 Bitstream Parsing Error: Not a valid code 0x000002.");
1541                     return(CODECHAL_DECODE_VC1_EOS);
1542                 }
1543                 else
1544                 {
1545                     zeroNum = data ? 0 : (zeroNum + 1);
1546                 }
1547             }
1548             else // zeroNum > 3
1549             {
1550                 if (data == 0x00)
1551                 {
1552                     zeroNum++;
1553                 }
1554                 else if (data == 0x01)
1555                 {
1556                     zeroNum = 0;
1557                 }
1558                 else
1559                 {
1560                     CODECHAL_DECODE_ASSERTMESSAGE("VC1 Bitstream Parsing Error: Not a start code 0x000001.");
1561                     return(CODECHAL_DECODE_VC1_EOS);
1562                 }
1563             }
1564 
1565             leftByte--;
1566             value.u8Value[leftByte] = data;
1567         }
1568 
1569         *cache = value.u32Value;
1570         cache++;
1571     }
1572 
1573     m_bitstream.pu32Cache          = (uint32_t *)m_bitstream.CacheBuffer;
1574     m_bitstream.u32ZeroNum         = zeroNum;
1575     m_bitstream.pOriginalBitBuffer = originalBitBuffer;
1576     m_bitstream.iBitOffsetEnd      = 0;
1577     m_bitstream.pu32CacheDataEnd   = m_bitstream.pu32CacheEnd;
1578 
1579     return 0;
1580 }
1581 
GetBits(uint32_t bitsRead)1582 uint32_t CodechalDecodeVc1::GetBits(uint32_t bitsRead)
1583 {
1584     uint32_t        value = 0;
1585 
1586     CODECHAL_DECODE_ASSERT((bitsRead > 0) && (bitsRead <= 32));
1587 
1588     uint32_t *cache       = m_bitstream.pu32Cache;
1589     int32_t   shiftOffset = m_bitstream.iBitOffset - (bitsRead);
1590 
1591     if (shiftOffset >= 0)
1592     {
1593         value = (*cache) >> (shiftOffset);
1594     }
1595     else
1596     {
1597         shiftOffset += 32;
1598         value = (cache[0] << (32 - shiftOffset)) + (cache[1] >> shiftOffset);
1599         m_bitstream.pu32Cache++;
1600     }
1601 
1602     value &= ((0x1 << bitsRead) - 1);
1603     m_bitstream.iBitOffset = shiftOffset;
1604     m_bitstream.u32ProcessedBitNum += bitsRead;
1605 
1606     if ((cache == m_bitstream.pu32CacheDataEnd) &&
1607         (m_bitstream.iBitOffset < m_bitstream.iBitOffsetEnd))
1608     {
1609         return CODECHAL_DECODE_VC1_EOS;
1610     }
1611 
1612     if (cache == m_bitstream.pu32CacheEnd)
1613     {
1614         if (UpdateBitstreamBuffer() == CODECHAL_DECODE_VC1_EOS)
1615         {
1616             return CODECHAL_DECODE_VC1_EOS;
1617         }
1618     }
1619 
1620     return value;
1621 }
1622 
SkipBits(uint32_t bitsRead)1623 uint32_t CodechalDecodeVc1::SkipBits(uint32_t bitsRead)
1624 {
1625     CODECHAL_DECODE_ASSERT((bitsRead > 0) && (bitsRead <= 32));
1626 
1627     uint32_t *cache       = m_bitstream.pu32Cache;
1628     int32_t   shiftOffset = m_bitstream.iBitOffset - (bitsRead);
1629 
1630     if (shiftOffset < 0)
1631     {
1632         shiftOffset += 32;
1633         m_bitstream.pu32Cache++;
1634     }
1635 
1636     m_bitstream.iBitOffset = shiftOffset;
1637     m_bitstream.u32ProcessedBitNum += bitsRead;
1638 
1639     if ((cache == m_bitstream.pu32CacheDataEnd) &&
1640         (m_bitstream.iBitOffset < m_bitstream.iBitOffsetEnd))
1641     {
1642         return CODECHAL_DECODE_VC1_EOS;
1643     }
1644 
1645     if (cache == m_bitstream.pu32CacheEnd)
1646     {
1647         if (UpdateBitstreamBuffer() == CODECHAL_DECODE_VC1_EOS)
1648         {
1649             return CODECHAL_DECODE_VC1_EOS;
1650         }
1651     }
1652 
1653     return 0;
1654 }
1655 
GetVLC(const uint32_t * table)1656 uint32_t CodechalDecodeVc1::GetVLC(const uint32_t *table)
1657 {
1658     if (table == nullptr)
1659         return CODECHAL_DECODE_VC1_EOS;
1660 
1661     CODECHAL_DECODE_ASSERT(table[0] > 0);    // max bits
1662 
1663     uint32_t maxCodeLength = table[0];
1664     uint32_t tableSize = table[0];
1665     uint32_t index = 1;
1666     uint32_t codeLength = 1;
1667 
1668     uint32_t value = PeekBits(maxCodeLength);
1669     if (CODECHAL_DECODE_VC1_EOS == value)
1670     {
1671         CODECHAL_DECODE_ASSERTMESSAGE("Bitstream exhausted.");
1672         return(value);
1673     }
1674 
1675     for (uint32_t entryIndex = 0; entryIndex < tableSize; entryIndex++)
1676     {
1677         uint32_t subtableSize = table[index++];
1678 
1679         if (subtableSize > 0)
1680         {
1681             while (subtableSize--)
1682             {
1683                 if (table[index++] == (value >> (maxCodeLength - codeLength)))
1684                 {
1685                     value = GetBits((uint8_t)codeLength);
1686 
1687                     return(table[index]);
1688                 }
1689 
1690                 index++;
1691             }
1692         }
1693 
1694         codeLength++;
1695     }
1696 
1697     CODECHAL_DECODE_ASSERTMESSAGE("Code is not in VLC table.");
1698 
1699     return(CODECHAL_DECODE_VC1_EOS);
1700 }
1701 
InitialiseBitstream(uint8_t * buffer,uint32_t length,bool isEBDU)1702 MOS_STATUS CodechalDecodeVc1::InitialiseBitstream(
1703     uint8_t*                           buffer,
1704     uint32_t                           length,
1705     bool                               isEBDU)
1706 {
1707     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1708 
1709     MOS_ZeroMemory(&m_bitstream, sizeof(m_bitstream));
1710     CODECHAL_DECODE_CHK_NULL_RETURN(&m_bitstream);
1711     CODECHAL_DECODE_CHK_NULL_RETURN(buffer);
1712 
1713     m_bitstream.pOriginalBitBuffer = buffer;
1714     m_bitstream.pOriginalBufferEnd = buffer + length;
1715     m_bitstream.u32ZeroNum         = 0;
1716     m_bitstream.u32ProcessedBitNum = 0;
1717     m_bitstream.pu32Cache          = (uint32_t *)m_bitstream.CacheBuffer;
1718     m_bitstream.pu32CacheEnd       = (uint32_t *)(m_bitstream.CacheBuffer + CODECHAL_DECODE_VC1_BITSTRM_BUF_LEN);
1719     m_bitstream.pu32CacheDataEnd   = (uint32_t *)m_bitstream.CacheBuffer;
1720     m_bitstream.iBitOffset         = 32;
1721     m_bitstream.iBitOffsetEnd      = 32;
1722     m_bitstream.bIsEBDU            = isEBDU;
1723 
1724     if (UpdateBitstreamBuffer() == CODECHAL_DECODE_VC1_EOS)
1725     {
1726         return MOS_STATUS_UNKNOWN;
1727     }
1728 
1729     return eStatus;
1730 }
1731 
BitplaneNorm2Mode()1732 MOS_STATUS CodechalDecodeVc1::BitplaneNorm2Mode()
1733 {
1734     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1735 
1736     uint16_t frameFieldHeightInMb;
1737     CodecHal_GetFrameFieldHeightInMb(
1738         m_vc1PicParams->CurrPic,
1739         m_picHeightInMb,
1740         frameFieldHeightInMb);
1741     uint16_t frameFieldWidthInMb = m_picWidthInMb;
1742 
1743     uint32_t count = frameFieldWidthInMb * frameFieldHeightInMb;
1744 
1745     uint32_t value = 0;
1746     if ((frameFieldWidthInMb * frameFieldHeightInMb) & 1)
1747     {
1748         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
1749 
1750         count--;
1751     }
1752 
1753     for (uint32_t i = 0; i < count / 2; i++)
1754     {
1755         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
1756         if (value)
1757         {
1758             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
1759             if (value == 0)
1760             {
1761                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
1762             }
1763         }
1764     }
1765 
1766     return eStatus;
1767 }
1768 
BitplaneNorm6Mode()1769 MOS_STATUS CodechalDecodeVc1::BitplaneNorm6Mode()
1770 {
1771     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1772 
1773     uint16_t frameFieldHeightInMb;
1774     CodecHal_GetFrameFieldHeightInMb(
1775         m_vc1PicParams->CurrPic,
1776         m_picHeightInMb,
1777         frameFieldHeightInMb);
1778     uint16_t frameFieldWidthInMb = m_picWidthInMb;
1779 
1780     bool is2x3Tiled = (0 != frameFieldWidthInMb % 3) && (0 == frameFieldHeightInMb % 3);
1781 
1782     uint32_t heightInTiles = 0, widthInTiles = 0;
1783     uint32_t residualX = 0, residualY = 0;
1784     uint32_t value = 0;
1785     if (is2x3Tiled)
1786     {
1787         widthInTiles = frameFieldWidthInMb / 2;
1788         heightInTiles = frameFieldHeightInMb / 3;
1789 
1790         for (uint32_t j = 0; j < heightInTiles; j++)
1791         {
1792             for (uint32_t i = 0; i < widthInTiles; i++)
1793             {
1794                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetVLC(CODECHAL_DECODE_VC1_VldCode3x2Or2x3TilesTable, value));
1795             }
1796         }
1797 
1798         residualX = frameFieldWidthInMb & 1;
1799         residualY = 0;
1800     }
1801     else // 3x2 tiles
1802     {
1803         widthInTiles = frameFieldWidthInMb / 3;
1804         heightInTiles = frameFieldHeightInMb / 2;
1805 
1806         for (uint32_t j = 0; j < heightInTiles; j++)
1807         {
1808             for (uint32_t i = 0; i < widthInTiles; i++)
1809             {
1810                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetVLC(CODECHAL_DECODE_VC1_VldCode3x2Or2x3TilesTable, value));
1811             }
1812         }
1813 
1814         residualX = frameFieldWidthInMb % 3;
1815         residualY = frameFieldHeightInMb & 1;
1816     }
1817 
1818     // ResidualY 0 or 1 or 2
1819     for (uint32_t i = 0; i < residualX; i++)
1820     {
1821         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_BITPLANE_COLSKIP, value));
1822 
1823         if (value)
1824         {
1825             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipWords(frameFieldHeightInMb >> 4, value));
1826             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(frameFieldHeightInMb & 0xF, value));
1827         }
1828     }
1829 
1830     // ResidualY 0 or 1
1831     for (uint32_t j = 0; j < residualY; j++)
1832     {
1833         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_BITPLANE_ROWSKIP, value));
1834 
1835         if (value)
1836         {
1837             uint32_t skipBits = frameFieldWidthInMb - residualX;
1838             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipWords(skipBits >> 4, value));
1839             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(skipBits & 0xF, value));
1840         }
1841     }
1842 
1843     return eStatus;
1844 }
1845 
BitplaneRowskipMode()1846 MOS_STATUS CodechalDecodeVc1::BitplaneRowskipMode()
1847 {
1848     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1849 
1850     uint16_t frameFieldHeightInMb;
1851     CodecHal_GetFrameFieldHeightInMb(
1852         m_vc1PicParams->CurrPic,
1853         m_picHeightInMb,
1854         frameFieldHeightInMb);
1855     uint16_t frameFieldWidthInMb = m_picWidthInMb;
1856 
1857     uint32_t value = 0;
1858     for (uint32_t j = 0; j < frameFieldHeightInMb; j++)
1859     {
1860         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_BITPLANE_ROWSKIP, value));
1861 
1862         if (value)
1863         {
1864             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipWords(frameFieldWidthInMb >> 4, value));
1865             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(frameFieldWidthInMb & 0xF, value));
1866         }
1867     }
1868 
1869     return eStatus;
1870 }
1871 
BitplaneColskipMode()1872 MOS_STATUS CodechalDecodeVc1::BitplaneColskipMode()
1873 {
1874     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1875 
1876     uint16_t meFieldHeightInMb;
1877     CodecHal_GetFrameFieldHeightInMb(
1878         m_vc1PicParams->CurrPic,
1879         m_picHeightInMb,
1880         meFieldHeightInMb);
1881     uint16_t frameFieldWidthInMb = m_picWidthInMb;
1882 
1883     uint32_t value = 0;
1884     uint32_t colSkip = 0;
1885     for (uint32_t i = 0; i < frameFieldWidthInMb; i++)
1886     {
1887         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_BITPLANE_COLSKIP, value));
1888         colSkip = value;
1889 
1890         if (value)
1891         {
1892             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipWords(meFieldHeightInMb >> 4, value));
1893             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(meFieldHeightInMb & 0xF, value));
1894         }
1895     }
1896 
1897     return eStatus;
1898 }
1899 
ParseVopDquant()1900 MOS_STATUS CodechalDecodeVc1::ParseVopDquant()
1901 {
1902     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1903 
1904     uint32_t value = 0;
1905     uint32_t dquantFRM = 0, dqprofile = 0, dqbilevel = 0;
1906     if ((1 == m_vc1PicParams->pic_quantizer_fields.dquant) ||
1907         (3 == m_vc1PicParams->pic_quantizer_fields.dquant))
1908     {
1909         // The DQUANTFRM field is a 1 bit value that is present only
1910         // when DQUANT = 1.  If DQUANTFRM = 0 then the current picture
1911         // is only quantized with PQUANT.
1912         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_DQUANTFRM, value));
1913         dquantFRM = value;
1914 
1915         if (dquantFRM)
1916         {
1917             // The DQPROFILE field is a 2 bits value that is present
1918             // only when DQUANT = 1 and DQUANTFRM = 1.  It indicates
1919             // where we are allowed to change quantization step sizes
1920             // within the current picture.
1921             // Table 15:  Macroblock Quantization Profile (DQPROFILE) Code Table
1922             // FLC    Location
1923             // 00    All four Edges
1924             // 01    Double Edges
1925             // 10    Single Edges
1926             // 11    All Macroblocks
1927             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_DQPROFILE, value));
1928             dqprofile = value;
1929 
1930             switch (dqprofile)
1931             {
1932             case 0: // all 4 edges
1933             {
1934                 break;
1935             }
1936             case 1: // double edges
1937             {
1938                 // The DQSBEDGE field is a 2 bits value that is present
1939                 // when DQPROFILE = Single Edge.  It indicates which edge
1940                 // will be quantized with ALTPQUANT.
1941                 // Table 16:  Single Boundary Edge Selection (DQSBEDGE) Code Table
1942                 // FLC    Boundary Edge
1943                 // 00    Left
1944                 // 01    Top
1945                 // 10    Right
1946                 // 11    Bottom
1947                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_DQDBEDGE, value));
1948                 break;
1949             }
1950             case 2: // single edge
1951             {
1952                 // The DQSBEDGE field is a 2 bits value that is present
1953                 // when DQPROFILE = Single Edge.  It indicates which edge
1954                 // will be quantized with ALTPQUANT.
1955                 // Table 16:  Single Boundary Edge Selection (DQSBEDGE) Code Table
1956                 // FLC    Boundary Edge
1957                 // 00    Left
1958                 // 01    Top
1959                 // 10    Right
1960                 // 11    Bottom
1961                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_DQDBEDGE, value));
1962                 break;
1963             }
1964             case 3: // all MBs
1965             {
1966                 // The DQBILEVEL field is a 1 bit value that is present
1967                 // when DQPROFILE = All Macroblock.  If DQBILEVEL = 1,
1968                 // then each macroblock in the picture can take one of
1969                 // two possible values (PQUANT or ALTPQUANT).  If
1970                 // DQBILEVEL = 0, then each macroblock in the picture
1971                 // can take on any quantization step size.
1972                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_DQBILEVEL, value));
1973                 dqbilevel = value;
1974                 break;
1975             }
1976             }
1977         }
1978     }
1979     else if (2 == m_vc1PicParams->pic_quantizer_fields.dquant)
1980     {
1981         dquantFRM = 1;
1982     }
1983 
1984     // PQDIFF is a 3 bit field that encodes either the PQUANT
1985     // differential or encodes an escape code.
1986     // If PQDIFF does not equal 7 then PQDIFF encodes the
1987     // differential and the ABSPQ field does not follow in
1988     // the bitstream. In this case:
1989     //       ALTPQUANT = PQUANT + PQDIFF + 1
1990     // If PQDIFF equals 7 then the ABSPQ field follows in
1991     // the bitstream and ALTPQUANT is decoded as:
1992     //       ALTPQUANT = ABSPQ
1993     if (dquantFRM)
1994     {
1995         if ((m_vc1PicParams->pic_quantizer_fields.dquant == 2) ||
1996             !(dqprofile == 3 && dqbilevel == 0))
1997         {
1998             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_PQDIFF, value));
1999 
2000             if (7 == value)
2001             {
2002                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_ABSPQ, value));
2003             }
2004         }
2005     }
2006 
2007     return eStatus;
2008 }
2009 
ParseMvRange()2010 MOS_STATUS CodechalDecodeVc1::ParseMvRange()
2011 {
2012     uint32_t    value;
2013     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
2014 
2015     // MVRANGE
2016     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2017 
2018     if (value)
2019     {
2020         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2021 
2022         if (value)
2023         {
2024             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2025         }
2026     }
2027 
2028     return eStatus;
2029 }
2030 
ParseProgressiveMvMode(const uint32_t mvModeTable[],uint32_t * mvMode)2031 MOS_STATUS CodechalDecodeVc1::ParseProgressiveMvMode(
2032     const uint32_t                     mvModeTable[],
2033     uint32_t*                          mvMode)
2034 {
2035     uint32_t    value;
2036     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
2037 
2038     uint32_t bitCount = 1;
2039     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2040     while ((value == 0) && (bitCount < 4))
2041     {
2042         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2043         bitCount++;
2044     }
2045 
2046     uint32_t index = (bitCount < 4) ? bitCount - 1 : bitCount + value - 1;
2047     uint32_t mvModeType = mvModeTable[index];
2048 
2049     if (CODECHAL_VC1_MVMODE_IC == mvModeType)
2050     {
2051         bitCount = 1;
2052         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2053         while ((value == 0) && (bitCount < 3))
2054         {
2055             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2056             bitCount++;
2057         }
2058 
2059         index = (bitCount < 3) ? bitCount - 1 : bitCount + !value - 1;
2060         mvModeType = mvModeTable[index];
2061 
2062         CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(CODECHAL_DECODE_VC1_BITS_LUMSCALE + CODECHAL_DECODE_VC1_BITS_LUMSHIFT, value));
2063     }
2064 
2065     *mvMode = mvModeType;
2066 
2067     return eStatus;
2068 }
2069 
ParseInterlaceMVMode(bool isPPicture,uint32_t * mvmode)2070 MOS_STATUS CodechalDecodeVc1::ParseInterlaceMVMode(
2071     bool                               isPPicture,
2072     uint32_t*                          mvmode)
2073 {
2074     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2075 
2076     CODECHAL_DECODE_CHK_NULL_RETURN(mvmode);
2077 
2078     const uint32_t *mvModeTable;
2079     if (12 < m_vc1PicParams->pic_quantizer_fields.pic_quantizer_scale)
2080     {
2081         mvModeTable = CODECHAL_DECODE_VC1_LowRateMvModeTable;
2082     }
2083     else
2084     {
2085         mvModeTable = CODECHAL_DECODE_VC1_HighRateMvModeTable;
2086     }
2087 
2088     uint32_t bitCount = 1;
2089     uint32_t value = 0;
2090     uint32_t index = 0, mvMode = 0;
2091     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2092 
2093     if (isPPicture)
2094     {
2095         while ((value == 0) && (bitCount < 4))
2096         {
2097             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2098             bitCount++;
2099         }
2100 
2101         index = (bitCount < 4) ? bitCount - 1 : bitCount + value - 1;
2102         mvMode = mvModeTable[index];
2103     }
2104     else // B picture
2105     {
2106         while ((value == 0) && (bitCount < 3))
2107         {
2108             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2109             bitCount++;
2110         }
2111 
2112         index = (bitCount < 3) ? bitCount - 1 : bitCount + !value - 1;
2113     }
2114 
2115     mvMode = mvModeTable[index];
2116 
2117     if (CODECHAL_VC1_MVMODE_IC == value)
2118     {
2119         bitCount = 1;
2120         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2121         while ((value == 0) && (bitCount < 3))
2122         {
2123             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2124             bitCount++;
2125         }
2126 
2127         index = (bitCount < 3) ? bitCount - 1 : bitCount + !value - 1;
2128         mvMode = mvModeTable[index];
2129 
2130         // Intensity compensation flags
2131         uint32_t skipBits = 0;
2132         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2133         if (value == 0)
2134         {
2135             skipBits += 1 + CODECHAL_DECODE_VC1_BITS_LUMSCALE + CODECHAL_DECODE_VC1_BITS_LUMSHIFT;
2136         }
2137 
2138         skipBits += CODECHAL_DECODE_VC1_BITS_LUMSCALE + CODECHAL_DECODE_VC1_BITS_LUMSHIFT;
2139 
2140         CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(skipBits, value));
2141     }
2142 
2143     *mvmode = mvMode;
2144 
2145     return eStatus;
2146 }
2147 
ParseBitplane()2148 MOS_STATUS CodechalDecodeVc1::ParseBitplane()
2149 {
2150     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2151 
2152     uint32_t value = 0;
2153     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_BITPLANE_INVERT, value));
2154 
2155     CODECHAL_DECODE_CHK_STATUS_RETURN(GetVLC(CODECHAL_DECODE_VC1_VldBitplaneModeTable, value));
2156 
2157     switch (value) // Bitplane mode
2158     {
2159     case CODECHAL_VC1_BITPLANE_NORMAL2:
2160         eStatus = BitplaneNorm2Mode();
2161         break;
2162     case CODECHAL_VC1_BITPLANE_NORMAL6:
2163         eStatus = BitplaneNorm6Mode();
2164         break;
2165     case CODECHAL_VC1_BITPLANE_DIFF2:
2166         eStatus = BitplaneNorm2Mode();  // Diff2 is the same as Norm2 mode
2167         break;
2168     case CODECHAL_VC1_BITPLANE_DIFF6:
2169         eStatus = BitplaneNorm6Mode();  // Diff6 is the same as Norm6 mode
2170         break;
2171     case CODECHAL_VC1_BITPLANE_ROWSKIP:
2172         eStatus = BitplaneRowskipMode();
2173         break;
2174     case CODECHAL_VC1_BITPLANE_COLSKIP:
2175         eStatus = BitplaneColskipMode();
2176         break;
2177     case CODECHAL_VC1_BITPLANE_RAW:
2178         // nothing to do
2179         break;
2180     default:
2181         CODECHAL_DECODE_ASSERTMESSAGE("Invalid bitplane mode %d.", value);
2182     }
2183 
2184     return eStatus;
2185 }
2186 
ParsePictureLayerIAdvanced()2187 MOS_STATUS CodechalDecodeVc1::ParsePictureLayerIAdvanced()
2188 {
2189     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2190 
2191     uint32_t value = 0;
2192     if (CodecHal_PictureIsInterlacedFrame(m_vc1PicParams->CurrPic))
2193     {
2194         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2195     }
2196 
2197     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2198 
2199     if (m_vc1PicParams->sequence_fields.overlap &&
2200         (m_vc1PicParams->pic_quantizer_fields.pic_quantizer_scale <= 8))
2201     {
2202         //conditional overlap flag
2203         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2204 
2205         if (1 == value)
2206         {
2207             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2208             if (1 == value)
2209             {
2210                 // CONDOVER == 2
2211                 CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2212             }
2213         }
2214     }
2215 
2216     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_1, value));
2217     if (0 != value)
2218     {
2219         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_2, value));
2220     }
2221 
2222     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM2_1, value));
2223     if (0 != value)
2224     {
2225         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM2_2, value));
2226     }
2227 
2228     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSDCTAB, value));
2229 
2230     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseVopDquant());
2231 
2232     return eStatus;
2233 }
2234 
ParsePictureLayerPAdvanced()2235 MOS_STATUS CodechalDecodeVc1::ParsePictureLayerPAdvanced()
2236 {
2237     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2238 
2239     if (m_vc1PicParams->mv_fields.extended_mv_flag)
2240     {
2241         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseMvRange());
2242     }
2243 
2244     const uint32_t *mvModeTable = nullptr;
2245     mvModeTable                 = (12 < m_vc1PicParams->pic_quantizer_fields.pic_quantizer_scale) ? CODECHAL_DECODE_VC1_LowRateMvModeTable : CODECHAL_DECODE_VC1_HighRateMvModeTable;
2246 
2247     uint32_t mvMode;
2248     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseProgressiveMvMode(mvModeTable, &mvMode));
2249 
2250     if (CODECHAL_VC1_MVMODE_MIXEDMV == mvMode)
2251     {
2252         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2253     }
2254 
2255     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2256 
2257     uint32_t value = 0;
2258     CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(CODECHAL_DECODE_VC1_BITS_MVTAB + CODECHAL_DECODE_VC1_BITS_CBPTAB, value));
2259 
2260     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseVopDquant());
2261 
2262     if (m_vc1PicParams->transform_fields.variable_sized_transform_flag)
2263     {
2264         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TTMBF, value));
2265 
2266         if (1 == value)
2267         {
2268             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TTFRM, value));
2269         }
2270     }
2271 
2272     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_1, value));
2273 
2274     if (0 != value)
2275     {
2276         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_2, value));
2277     }
2278 
2279     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSDCTAB, value));
2280 
2281     return eStatus;
2282 }
2283 
ParsePictureLayerBAdvanced()2284 MOS_STATUS CodechalDecodeVc1::ParsePictureLayerBAdvanced()
2285 {
2286     uint32_t    value;
2287     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
2288 
2289     if (m_vc1PicParams->mv_fields.extended_mv_flag)
2290     {
2291         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseMvRange());
2292     }
2293 
2294     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2295 
2296     // B frame direct mode macroblock bit syntax element
2297     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2298 
2299     // skipped macroblock bit syntax element
2300     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2301 
2302     CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(CODECHAL_DECODE_VC1_BITS_MVTAB + CODECHAL_DECODE_VC1_BITS_CBPTAB, value));
2303 
2304     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseVopDquant());
2305 
2306     if (m_vc1PicParams->transform_fields.variable_sized_transform_flag)
2307     {
2308         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TTMBF, value));
2309 
2310         if (1 == value)
2311         {
2312             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TTFRM, value));
2313         }
2314     }
2315 
2316     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_1, value));
2317 
2318     if (0 != value)
2319     {
2320         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_2, value));
2321     }
2322 
2323     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSDCTAB, value));
2324 
2325     return eStatus;
2326 }
2327 
ParseFieldPictureLayerPAdvanced()2328 MOS_STATUS CodechalDecodeVc1::ParseFieldPictureLayerPAdvanced()
2329 {
2330     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2331 
2332     uint32_t value = 0;
2333     uint32_t numRef = 0;
2334     if (CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
2335     {
2336         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_NUMREF, value));
2337         numRef = value;
2338 
2339         if (0 == value)
2340         {
2341             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_REFFIELD, value));
2342         }
2343     }
2344     else
2345     {
2346         numRef = 0;
2347     }
2348 
2349     if (m_vc1PicParams->mv_fields.extended_mv_flag)
2350     {
2351         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseMvRange());
2352     }
2353 
2354     if (m_vc1PicParams->mv_fields.extended_dmv_flag)
2355     {
2356         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2357         if (value)
2358         {
2359             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2360             if (value)
2361             {
2362                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2363             }
2364         }
2365     }
2366 
2367     uint32_t mvMode;
2368     if (CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
2369     {
2370         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseInterlaceMVMode(true, &mvMode));
2371     }
2372     else
2373     {
2374         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_4MVSWITCH, value));
2375         if (value)
2376         {
2377             mvMode = CODECHAL_VC1_MVMODE_MIXEDMV;
2378         }
2379         else
2380         {
2381             mvMode = CODECHAL_VC1_MVMODE_1MV;
2382         }
2383 
2384         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_INTCOMP, value));
2385 
2386         if (value)
2387         {
2388             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(CODECHAL_DECODE_VC1_BITS_LUMSCALE + CODECHAL_DECODE_VC1_BITS_LUMSHIFT, value));
2389         }
2390 
2391         // skipped macroblock bitplane
2392         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2393     }
2394 
2395     uint32_t skipBits = 0;
2396 
2397     if (CodecHal_PictureIsInterlacedFrame(m_vc1PicParams->CurrPic))
2398     {
2399         skipBits += 2;    // 2-bit MBMODETAB
2400     }
2401     else
2402     {
2403         skipBits += 3;    // 3 bit MBMODETAB
2404     }
2405 
2406     if (0 == numRef)
2407     {
2408         skipBits += 2;    // 2-bit MVTAB
2409     }
2410     else
2411     {
2412         skipBits += 3;    // 3-bit MVTAB
2413     }
2414 
2415     skipBits += CODECHAL_DECODE_VC1_BITS_CBPTAB_INTERLACE;
2416 
2417     if (CodecHal_PictureIsInterlacedFrame(m_vc1PicParams->CurrPic))
2418     {
2419         skipBits += CODECHAL_DECODE_VC1_BITS_2MVBPTAB;
2420     }
2421 
2422     if (CODECHAL_VC1_MVMODE_MIXEDMV == mvMode)
2423     {
2424         skipBits += CODECHAL_DECODE_VC1_BITS_4MVBPTAB;
2425     }
2426 
2427     CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(skipBits, value));
2428 
2429     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseVopDquant());
2430 
2431     if (m_vc1PicParams->transform_fields.variable_sized_transform_flag)
2432     {
2433         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TTMBF, value));
2434 
2435         if (1 == value)
2436         {
2437             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TTFRM, value));
2438         }
2439     }
2440 
2441     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_1, value));
2442 
2443     if (0 != value)
2444     {
2445         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_2, value));
2446     }
2447 
2448     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSDCTAB, value));
2449 
2450     return eStatus;
2451 }
2452 
ParseFieldPictureLayerBAdvanced()2453 MOS_STATUS CodechalDecodeVc1::ParseFieldPictureLayerBAdvanced()
2454 {
2455     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2456 
2457     uint32_t value = 0;
2458     if (CodecHal_PictureIsInterlacedFrame(m_vc1PicParams->CurrPic))
2459     {
2460         CODECHAL_DECODE_CHK_STATUS_RETURN(GetVLC(CODECHAL_DECODE_VC1_VldBFractionTable, value));
2461         m_vc1PicParams->b_picture_fraction = (uint8_t)value;
2462     }
2463 
2464     if (m_vc1PicParams->mv_fields.extended_mv_flag)
2465     {
2466         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseMvRange());
2467     }
2468 
2469     if (m_vc1PicParams->mv_fields.extended_dmv_flag)
2470     {
2471         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2472         if (value)
2473         {
2474             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2475             if (value)
2476             {
2477                 CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2478             }
2479         }
2480     }
2481 
2482     uint32_t mvMode;
2483     if (CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
2484     {
2485         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseInterlaceMVMode(false, &mvMode));
2486     }
2487     else
2488     {
2489         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_INTCOMP, value));
2490 
2491         if (value)
2492         {
2493             CODECHAL_DECODE_VERBOSEMESSAGE("INTCOMP is not false.");
2494         }
2495         mvMode = CODECHAL_VC1_MVMODE_1MV;
2496 
2497         // direct macroblock bitplane
2498         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2499 
2500         // skipped macroblock bitplane
2501         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2502     }
2503 
2504     if (CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
2505     {
2506         // forward macroblock
2507         CODECHAL_DECODE_CHK_STATUS_RETURN(ParseBitplane());
2508     }
2509 
2510     uint32_t skipBits = 0;
2511 
2512     if (CodecHal_PictureIsInterlacedFrame(m_vc1PicParams->CurrPic))
2513     {
2514         skipBits += 2;    // 2-bit MBMODETAB
2515     }
2516     else
2517     {
2518         skipBits += 3;    // 3 bit MBMODETAB
2519     }
2520 
2521     if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
2522     {
2523         skipBits += 2;    // 2-bit MVTAB
2524     }
2525     else
2526     {
2527         skipBits += 3;    // 3-bit MVTAB
2528     }
2529 
2530     skipBits += CODECHAL_DECODE_VC1_BITS_CBPTAB_INTERLACE;
2531 
2532     if (CodecHal_PictureIsInterlacedFrame(m_vc1PicParams->CurrPic))
2533     {
2534         skipBits += CODECHAL_DECODE_VC1_BITS_2MVBPTAB;
2535     }
2536 
2537     if ((CODECHAL_VC1_MVMODE_MIXEDMV == mvMode) ||
2538         CodecHal_PictureIsInterlacedFrame(m_vc1PicParams->CurrPic))
2539     {
2540         skipBits += CODECHAL_DECODE_VC1_BITS_4MVBPTAB;
2541     }
2542 
2543     CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(skipBits, value));
2544 
2545     CODECHAL_DECODE_CHK_STATUS_RETURN(ParseVopDquant());
2546 
2547     if (m_vc1PicParams->transform_fields.variable_sized_transform_flag)
2548     {
2549         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TTMBF, value));
2550 
2551         if (1 == value)
2552         {
2553             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TTFRM, value));
2554         }
2555     }
2556 
2557     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_1, value));
2558 
2559     if (0 != value)
2560     {
2561         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSACFRM_2, value));
2562     }
2563 
2564     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TRANSDCTAB, value));
2565 
2566     return eStatus;
2567 }
2568 
ParsePictureHeaderAdvanced()2569 MOS_STATUS CodechalDecodeVc1::ParsePictureHeaderAdvanced()
2570 {
2571     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
2572 
2573     bool isIPicture = m_mfxInterface->IsVc1IPicture(
2574                           m_vc1PicParams->CurrPic,
2575                           m_vc1PicParams->picture_fields.is_first_field,
2576                           m_vc1PicParams->picture_fields.picture_type)
2577                           ? true
2578                           : false;
2579     bool isPPicture = m_mfxInterface->IsVc1PPicture(
2580                           m_vc1PicParams->CurrPic,
2581                           m_vc1PicParams->picture_fields.is_first_field,
2582                           m_vc1PicParams->picture_fields.picture_type)
2583                           ? true
2584                           : false;
2585     bool isBPicture = m_mfxInterface->IsVc1BPicture(
2586                           m_vc1PicParams->CurrPic,
2587                           m_vc1PicParams->picture_fields.is_first_field,
2588                           m_vc1PicParams->picture_fields.picture_type)
2589                           ? true
2590                           : false;
2591     bool isBIPicture = m_mfxInterface->IsVc1BIPicture(
2592                            m_vc1PicParams->CurrPic,
2593                            m_vc1PicParams->picture_fields.is_first_field,
2594                            m_vc1PicParams->picture_fields.picture_type)
2595                            ? true
2596                            : false;
2597 
2598     uint32_t value = 0;
2599     if (m_vc1PicParams->sequence_fields.interlace)
2600     {
2601         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_FCM_1, value));
2602         if (0 != value)
2603         {
2604             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_FCM_2, value));
2605         }
2606     }
2607 
2608     if (CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
2609     {
2610         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_FPTYPE, value));
2611     }
2612     else
2613     {
2614         CODECHAL_DECODE_CHK_STATUS_RETURN(GetVLC(CODECHAL_DECODE_VC1_VldPictureTypeTable, value));
2615     }
2616 
2617     if (m_vc1PicParams->sequence_fields.tfcntrflag)
2618     {
2619         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TFCNTR, value));
2620     }
2621 
2622     uint32_t repeatFrameCount = 0, numPanScanWindows, skipBits;
2623     uint32_t repeatFirstField = 0;
2624     if (m_vc1PicParams->sequence_fields.pulldown)
2625     {
2626         if (!m_vc1PicParams->sequence_fields.interlace)
2627         {
2628             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_RPTFRM, value));
2629 
2630             repeatFrameCount = value;
2631         }
2632         else
2633         {
2634             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_TFF, value));
2635             CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_RFF, value));
2636 
2637             repeatFirstField = value;
2638         }
2639     }
2640 
2641     if (m_vc1PicParams->entrypoint_fields.panscan_flag)
2642     {
2643         // parse PANSCAN
2644         if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
2645         {
2646             if (!m_vc1PicParams->sequence_fields.pulldown)
2647             {
2648                 numPanScanWindows = 1;
2649             }
2650             else
2651             {
2652                 numPanScanWindows = 1 + repeatFrameCount;
2653             }
2654         }
2655         else
2656         {
2657             if (!m_vc1PicParams->sequence_fields.pulldown)
2658             {
2659                 numPanScanWindows = 2;
2660             }
2661             else
2662             {
2663                 numPanScanWindows = 2 + repeatFirstField;
2664             }
2665         }
2666 
2667         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_PS_PRESENT, value));
2668 
2669         if (value)
2670         {
2671             skipBits = CODECHAL_DECODE_VC1_BITS_PS_HOFFSET + CODECHAL_DECODE_VC1_BITS_PS_VOFFSET;
2672             skipBits += CODECHAL_DECODE_VC1_BITS_PS_WIDTH + CODECHAL_DECODE_VC1_BITS_PS_HEIGHT;
2673             skipBits = skipBits * numPanScanWindows;
2674 
2675             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipWords(skipBits >> 4, value));
2676             CODECHAL_DECODE_CHK_STATUS_RETURN(SkipBits(skipBits & 0xF, value));
2677         }
2678     }
2679 
2680     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_RNDCTRL, value));
2681 
2682     if (isIPicture || isBIPicture)
2683     {
2684         if (value != 0)
2685         {
2686             CODECHAL_DECODE_ASSERTMESSAGE("RNDCTRL is not 0 for I, BI pictures.");
2687             return MOS_STATUS_UNKNOWN;
2688         }
2689     }
2690 
2691     if (m_vc1PicParams->sequence_fields.interlace)
2692     {
2693         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_UVSAMP, value));
2694     }
2695 
2696     if (m_vc1PicParams->sequence_fields.finterpflag && CodecHal_PictureIsFrame(m_vc1PicParams->CurrPic))
2697     {
2698         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_INTERPFRM, value));
2699     }
2700 
2701     if (!CodecHal_PictureIsInterlacedFrame(m_vc1PicParams->CurrPic))
2702     {
2703         if (isBPicture ||
2704             (CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && isBIPicture))
2705         {
2706             CODECHAL_DECODE_CHK_STATUS_RETURN(GetVLC(CODECHAL_DECODE_VC1_VldBFractionTable, value));
2707             m_vc1PicParams->b_picture_fraction = (uint8_t)value;
2708         }
2709     }
2710 
2711     // REFDIST
2712     if (CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
2713         m_vc1PicParams->reference_fields.reference_distance_flag &&
2714         m_vc1PicParams->reference_fields.reference_picture_flag)
2715     {
2716         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(2, value));
2717 
2718         if (value == 3)
2719         {
2720             CODECHAL_DECODE_CHK_STATUS_RETURN(GetVLC(CODECHAL_DECODE_VC1_VldRefDistTable, value));
2721         }
2722 
2723         m_vc1PicParams->reference_fields.reference_distance = value;
2724     }
2725 
2726     // Quantization Params
2727     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_PQINDEX, value));
2728 
2729     if (8 >= value)
2730     {
2731         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_HALFQP, value));
2732     }
2733 
2734     if (1 == m_vc1PicParams->pic_quantizer_fields.quantizer)
2735     {
2736         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_PQUANTIZER, value));
2737     }
2738 
2739     // POSTPROC
2740     if (m_vc1PicParams->post_processing)
2741     {
2742         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_POSTPROC, value));
2743     }
2744 
2745     if (!CodecHal_PictureIsFrame(m_vc1PicParams->CurrPic))
2746     {
2747         if (isIPicture || isBIPicture)
2748         {
2749             eStatus = ParsePictureLayerIAdvanced();
2750         }
2751         else if (isPPicture)
2752         {
2753             eStatus = ParseFieldPictureLayerPAdvanced();
2754         }
2755         else if (isBPicture)
2756         {
2757             eStatus = ParseFieldPictureLayerBAdvanced();
2758         }
2759     }
2760     else
2761     {
2762         if (isIPicture || isBIPicture)
2763         {
2764             eStatus = ParsePictureLayerIAdvanced();
2765         }
2766         else if (isPPicture)
2767         {
2768             eStatus = ParsePictureLayerPAdvanced();
2769         }
2770         else if (isBPicture)
2771         {
2772             eStatus = ParsePictureLayerBAdvanced();
2773         }
2774     }
2775 
2776     return eStatus;
2777 }
2778 
ParsePictureHeaderMainSimple()2779 MOS_STATUS CodechalDecodeVc1::ParsePictureHeaderMainSimple()
2780 {
2781     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2782 
2783     uint32_t value = 0;
2784     if (m_vc1PicParams->sequence_fields.finterpflag)
2785     {
2786         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_INTERPFRM, value));
2787     }
2788 
2789     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_FRMCNT, value));
2790 
2791     if (m_vc1PicParams->sequence_fields.rangered)
2792     {
2793         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_RANGEREDFRM, value));
2794     }
2795 
2796     // picture type
2797     CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2798     if ((0 == value) && (m_vc1PicParams->sequence_fields.max_b_frames > 0))
2799     {
2800         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(1, value));
2801         if (0 == value)
2802         {
2803             // it's B or BI picture, get B fraction
2804             CODECHAL_DECODE_CHK_STATUS_RETURN(GetVLC(CODECHAL_DECODE_VC1_VldBFractionTable, value));
2805             m_vc1PicParams->b_picture_fraction = (uint8_t)value;
2806         }
2807     }
2808 
2809     // we don't need to parse more since we only want B fraction value
2810 
2811     return eStatus;
2812 }
2813 
GetSliceMbDataOffset()2814 MOS_STATUS CodechalDecodeVc1::GetSliceMbDataOffset()
2815 {
2816     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2817 
2818     CODECHAL_DECODE_FUNCTION_ENTER;
2819 
2820     if (m_numSlices == 1)
2821     {
2822         return eStatus;
2823     }
2824 
2825     CodechalResLock ResourceLock(m_osInterface, &m_resDataBuffer);
2826     auto bitstream = (uint8_t*)ResourceLock.Lock(CodechalResLock::readOnly);
2827     CODECHAL_DECODE_CHK_NULL_RETURN(bitstream);
2828 
2829     // start from the second slice since HW only need MB data offset for subsequent slices
2830     uint32_t macroblockOffset = 0;
2831     for (uint32_t slcCount = 1; slcCount < m_numSlices; slcCount++)
2832     {
2833         uint8_t *slice = bitstream + m_vc1SliceParams[slcCount].slice_data_offset;
2834 
2835         // skip start code prefix
2836         slice += m_vldSliceRecord[slcCount].dwOffset;
2837         uint32_t length = m_vldSliceRecord[slcCount].dwLength;
2838 
2839         CODECHAL_DECODE_CHK_STATUS_RETURN(InitialiseBitstream(slice, length, true));
2840 
2841         // parse slice header to get PIC_HEADER_FLAG
2842         uint32_t value = 0;
2843         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_SC_SUFFIX, value));
2844 
2845         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_SLICE_ADDR, value));
2846 
2847         CODECHAL_DECODE_CHK_STATUS_RETURN(GetBits(CODECHAL_DECODE_VC1_BITS_PIC_HEADER_FLAG, value));
2848 
2849         // parse picture header to get MB data offset if PIC_HEADER_FLAG == true
2850         if (value)
2851         {
2852             if (macroblockOffset == 0)
2853             {
2854                 CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeaderAdvanced());
2855 
2856                 macroblockOffset = m_bitstream.u32ProcessedBitNum +
2857                                    (CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH << 3);
2858             }
2859 
2860             m_vc1SliceParams[slcCount].macroblock_offset = macroblockOffset;
2861         }
2862     }
2863 
2864     return eStatus;
2865 }
2866 
ParsePictureHeader()2867 MOS_STATUS CodechalDecodeVc1::ParsePictureHeader()
2868 {
2869     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2870 
2871     CODECHAL_DECODE_FUNCTION_ENTER;
2872 
2873     bool isEBDU = m_vc1PicParams->sequence_fields.AdvancedProfileFlag;
2874 
2875     CodechalResLock ResourceLock(m_osInterface, &m_resDataBuffer);
2876     auto bitstream = (uint8_t*)ResourceLock.Lock(CodechalResLock::readOnly);
2877     CODECHAL_DECODE_CHK_NULL_RETURN(bitstream);
2878 
2879     uint32_t skippedBytes = 0;
2880     if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
2881     {
2882         // skip start code (4-byte)
2883         skippedBytes = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH + (CODECHAL_DECODE_VC1_BITS_SC_SUFFIX >> 3);
2884     }
2885 
2886     bitstream += skippedBytes;
2887     uint32_t length = m_dataSize - skippedBytes;
2888     CODECHAL_DECODE_CHK_STATUS_RETURN(InitialiseBitstream(bitstream, length, isEBDU));
2889 
2890     if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
2891     {
2892         CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeaderAdvanced());
2893     }
2894     else
2895     {
2896         CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeaderMainSimple());
2897     }
2898 
2899     return eStatus;
2900 }
2901 
AllocateResources()2902 MOS_STATUS CodechalDecodeVc1::AllocateResources()
2903 {
2904     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2905 
2906     CODECHAL_DECODE_FUNCTION_ENTER;
2907 
2908     MOS_LOCK_PARAMS lockFlagsWriteOnly;
2909     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
2910     lockFlagsWriteOnly.WriteOnly = 1;
2911 
2912     m_numMacroblocks   = m_picWidthInMb * m_picHeightInMb;
2913     m_numMacroblocksUv = m_picWidthInMb * (MOS_ALIGN_CEIL(m_picHeightInMb, 2) / 2);
2914 
2915     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(m_osInterface, &m_resSyncObject));
2916 
2917     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalAllocateDataList(
2918         m_vc1RefList,
2919         CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1));
2920 
2921     // Second level batch buffer for IT mode
2922     if (m_mode == CODECHAL_DECODE_MODE_VC1IT)
2923     {
2924         MOS_ZeroMemory(&m_itObjectBatchBuffer, sizeof(m_itObjectBatchBuffer));
2925 
2926         // Must reserve at least 8 cachelines after MI_BATCH_BUFFER_END_CMD since HW prefetch max 8 cachelines from BB everytime
2927         uint32_t size = m_standardDecodeSizeNeeded * m_numMacroblocks + m_hwInterface->m_sizeOfCmdBatchBufferEnd + 8 * CODECHAL_CACHELINE_SIZE;
2928 
2929         CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
2930             m_osInterface,
2931             &m_itObjectBatchBuffer,
2932             nullptr,
2933             size));
2934         m_itObjectBatchBuffer.bSecondLevel = true;
2935     }
2936 
2937     // Deblocking Filter Row Store Scratch buffer
2938     //(Num MacroBlock Width) * (Num Cachlines) * (Cachline size)
2939     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
2940                                                   &m_resMfdDeblockingFilterRowStoreScratchBuffer,
2941                                                   m_picWidthInMb * 7 * CODECHAL_CACHELINE_SIZE,
2942                                                   "DeblockingScratchBuffer"),
2943         "Failed to allocate Deblocking Filter Row Store Scratch Buffer.");
2944 
2945     // BSD/MPC Row Store Scratch buffer
2946     // (FrameWidth in MB) * (2) * (CacheLine size per MB)
2947     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
2948                                                   &m_resBsdMpcRowStoreScratchBuffer,
2949                                                   m_picWidthInMb * CODECHAL_CACHELINE_SIZE * 2,
2950                                                   "MpcScratchBuffer"),
2951         "Failed to allocate BSD/MPC Row Store Scratch Buffer.");
2952 
2953     // VC1 MV buffer, 1 cacheline for every MB
2954     for (uint32_t i = 0; i < CODECHAL_DECODE_VC1_DMV_MAX; i++)
2955     {
2956         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
2957                                                       &m_resVc1BsdMvData[i],
2958                                                       CODECHAL_CACHELINE_SIZE * m_numMacroblocks,
2959                                                       "MvBuffer"),
2960             "Failed to allocate VC1 BSD MV Buffer.");
2961     }
2962 
2963     // Bitplane buffer
2964     // (Bitplane buffer pitch) * (Height in Macroblock)
2965     uint32_t size;
2966     if (m_shortFormatInUse)
2967     {
2968         if (m_width <= 2048)
2969         {
2970             size = MHW_VDBOX_VC1_BITPLANE_BUFFER_PITCH_SMALL * m_picHeightInMb;
2971         }
2972         else
2973         {
2974             size = MHW_VDBOX_VC1_BITPLANE_BUFFER_PITCH_LARGE * m_picHeightInMb;
2975         }
2976 
2977         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
2978                                                       &m_resBitplaneBuffer,
2979                                                       size,
2980                                                       "BitplaneBuffer"),
2981             "Failed to allocate Bitplane Buffer.");
2982     }
2983 
2984     // For SP/MP short format
2985     // Private bitstream buffer
2986     // FrameWidth * FrameHeight * 1.5 + CODECHAL_DECODE_VC1_STUFFING_BYTES
2987     if (m_shortFormatInUse)
2988     {
2989         size = m_width * m_height * 3 / 2 + CODECHAL_DECODE_VC1_STUFFING_BYTES;
2990         m_privateBistreamBufferSize = size;
2991         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
2992                                                       &m_resPrivateBistreamBuffer,
2993                                                       size,
2994                                                       "PrivateBistreamBuffer"),
2995             "Failed to allocate BSD/MPC Row Store Scratch Buffer.");
2996     }
2997 
2998     m_unequalFieldWaInUse = (MEDIA_IS_WA(m_waTable, WaVC1UnequalFieldHeights) && (m_picHeightInMb % 2));
2999 
3000     if (m_unequalFieldWaInUse)
3001     {
3002         // Decoded frame surface
3003         for (uint32_t i = 0; i < CODECHAL_DECODE_VC1_UNEQUAL_FIELD_WA_SURFACES; i++)
3004         {
3005             // Error Frame is 1MB x 2MB
3006             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateSurface(
3007                                                           &m_unequalFieldSurface[i],
3008                                                           m_width,
3009                                                           m_height + MOS_YTILE_H_ALIGNMENT,
3010                                                           "Vc1UnequalFieldSurface"),
3011                 "Failed to allocate VC1 Unequal Fields WA decoding ouput surface data buffer.");
3012 
3013             // ensure that no entries are valid
3014             m_unequalFieldRefListIdx[i] = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1;
3015         }
3016 
3017         m_unequalFieldSurfaceForBType = CODECHAL_DECODE_VC1_UNEQUAL_FIELD_WA_SURFACES - 1;
3018         m_currUnequalFieldSurface     = 0;
3019     }
3020 
3021     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
3022         m_osInterface,
3023         &m_resSyncObjectWaContextInUse));
3024 
3025     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
3026         m_osInterface,
3027         &m_resSyncObjectVideoContextInUse));
3028 
3029     return (MOS_STATUS)eStatus;
3030 }
3031 
~CodechalDecodeVc1()3032 CodechalDecodeVc1::~CodechalDecodeVc1()
3033 {
3034     CODECHAL_DECODE_FUNCTION_ENTER;
3035 
3036     m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObject);
3037 
3038     CodecHalFreeDataList(m_vc1RefList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1);
3039 
3040     MOS_FreeMemory(m_vldSliceRecord);
3041     m_vldSliceRecord = nullptr;
3042 
3043     Mhw_FreeBb(m_osInterface, &m_itObjectBatchBuffer, nullptr);
3044 
3045     m_osInterface->pfnFreeResource(
3046         m_osInterface,
3047         &m_resMfdDeblockingFilterRowStoreScratchBuffer);
3048 
3049     m_osInterface->pfnFreeResource(
3050         m_osInterface,
3051         &m_resBsdMpcRowStoreScratchBuffer);
3052 
3053     for (uint32_t i = 0; i < CODECHAL_DECODE_VC1_DMV_MAX; i++)
3054     {
3055         m_osInterface->pfnFreeResource(
3056             m_osInterface,
3057             &m_resVc1BsdMvData[i]);
3058     }
3059 
3060     if (m_shortFormatInUse)
3061     {
3062         m_osInterface->pfnFreeResource(
3063             m_osInterface,
3064             &m_resBitplaneBuffer);
3065     }
3066 
3067     m_osInterface->pfnFreeResource(
3068         m_osInterface,
3069         &m_resPrivateBistreamBuffer);
3070 
3071     if (m_unequalFieldWaInUse)
3072     {
3073         for (uint32_t i = 0; i < CODECHAL_DECODE_VC1_UNEQUAL_FIELD_WA_SURFACES; i++)
3074         {
3075             // Error Frame is 1MB x 2MB
3076             m_osInterface->pfnFreeResource(
3077                 m_osInterface,
3078                 &m_unequalFieldSurface[i].OsResource);
3079             ;
3080         }
3081     }
3082 
3083     m_osInterface->pfnDestroySyncResource(
3084         m_osInterface,
3085         &m_resSyncObjectWaContextInUse);
3086 
3087     m_osInterface->pfnDestroySyncResource(
3088         m_osInterface,
3089         &m_resSyncObjectVideoContextInUse);
3090 }
3091 
SetFrameStates()3092 MOS_STATUS CodechalDecodeVc1::SetFrameStates()
3093 {
3094     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3095 
3096     CODECHAL_DECODE_FUNCTION_ENTER;
3097 
3098     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface);
3099     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer);
3100 
3101     m_dataSize          = m_decodeParams.m_dataSize;
3102     m_dataOffset        = m_decodeParams.m_dataOffset;
3103     m_numSlices         = m_decodeParams.m_numSlices;
3104     m_numMacroblocks    = m_decodeParams.m_numMacroblocks;
3105     m_vc1PicParams      = (PCODEC_VC1_PIC_PARAMS)(m_decodeParams.m_picParams);
3106     m_vc1SliceParams    = (PCODEC_VC1_SLICE_PARAMS)(m_decodeParams.m_sliceParams);
3107     m_vc1MbParams       = (PCODEC_VC1_MB_PARAMS)(m_decodeParams.m_macroblockParams);
3108     m_destSurface       = *(m_decodeParams.m_destSurface);
3109     m_resDataBuffer     = *(m_decodeParams.m_dataBuffer);
3110     m_deblockDataBuffer = m_decodeParams.m_deblockData;
3111 
3112     CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1PicParams);
3113 
3114     if (m_vc1PicParams->coded_width > m_destSurface.dwPitch ||
3115         m_vc1PicParams->coded_height > m_destSurface.dwHeight)
3116     {
3117         return MOS_STATUS_INVALID_PARAMETER;
3118     }
3119 
3120     if (CodecHalIsDecodeModeVLD(m_mode))
3121     {
3122         CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1SliceParams);
3123         uint32_t numSliceRecord  = 0;
3124         bool     invalidSliceNum = false;
3125 
3126         numSliceRecord = m_numMacroblocks;
3127         if (m_numSlices > m_numMacroblocks)
3128         {
3129             numSliceRecord  = m_numSlices;
3130             invalidSliceNum = true;
3131         }
3132 
3133         if (numSliceRecord > m_numVldSliceRecord || m_vldSliceRecord == nullptr)
3134         {
3135             MOS_SafeFreeMemory(m_vldSliceRecord);
3136             m_vldSliceRecord =
3137                 (PCODECHAL_VC1_VLD_SLICE_RECORD)MOS_AllocAndZeroMemory(numSliceRecord * sizeof(CODECHAL_VC1_VLD_SLICE_RECORD));
3138             CODECHAL_DECODE_CHK_NULL_RETURN(m_vldSliceRecord);
3139             m_numVldSliceRecord = numSliceRecord;
3140         }
3141         else
3142         {
3143             MOS_ZeroMemory(m_vldSliceRecord, m_numVldSliceRecord * sizeof(CODECHAL_VC1_VLD_SLICE_RECORD));
3144         }
3145     }
3146     else if (CodecHalIsDecodeModeIT(m_mode))
3147     {
3148         CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1MbParams);
3149 
3150         // Catch the case the codec does not send a deblocking surface, but requests ILDB
3151         if (m_deblockDataBuffer == nullptr)
3152         {
3153             m_vc1PicParams->entrypoint_fields.loopfilter = 0;
3154         }
3155     }
3156 
3157     // For short format, check if it is skipped frame.
3158     if (m_shortFormatInUse)
3159     {
3160         m_numMacroblocks = m_picWidthInMb * m_picHeightInMb;
3161 
3162         if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
3163         {
3164             if ((m_vc1SliceParams->macroblock_offset == 0xFFFF) &&
3165                 (m_vc1SliceParams->number_macroblocks == m_numMacroblocks))
3166             {
3167                 m_vc1PicParams->picture_fields.picture_type = vc1SkippedFrame;
3168             }
3169         }
3170         else // Simple or Main Profiles
3171         {
3172             if (((m_vc1SliceParams->slice_data_size == 0) ||
3173                     (m_vc1SliceParams->slice_data_size == 8)) &&
3174                 (m_vc1SliceParams->number_macroblocks == m_numMacroblocks))
3175             {
3176                 m_vc1PicParams->picture_fields.picture_type = vc1SkippedFrame;
3177             }
3178         }
3179     }
3180 
3181     PCODEC_REF_LIST destEntry = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx];
3182     uint16_t        picType   = (uint16_t)m_vc1PicParams->picture_fields.picture_type;
3183     CODEC_PICTURE   currPic   = m_vc1PicParams->CurrPic;
3184 
3185     if (!CodecHal_PictureIsField(currPic) ||
3186         (CodecHal_PictureIsField(currPic) && m_vc1PicParams->picture_fields.is_first_field))
3187     {
3188         MOS_ZeroMemory(destEntry, sizeof(CODEC_REF_LIST));
3189         destEntry->RefPic = currPic;
3190         destEntry->resRefPic = m_destSurface.OsResource;
3191     }
3192     if (!m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
3193     {
3194         if (m_vc1PicParams->range_mapping_fields.range_mapping_enabled)
3195         {
3196             MOS_BIT_ON(destEntry->dwRefSurfaceFlags, CODECHAL_WMV9_RANGE_ADJUSTMENT);
3197         }
3198         else
3199         {
3200             MOS_BIT_OFF(destEntry->dwRefSurfaceFlags, CODECHAL_WMV9_RANGE_ADJUSTMENT);
3201         }
3202     }
3203 
3204     if (CodecHal_PictureIsFrame(currPic))
3205     {
3206         MOS_BIT_ON(destEntry->dwRefSurfaceFlags, CODECHAL_VC1_PROGRESSIVE);
3207     }
3208 
3209     m_statusReportFeedbackNumber = m_vc1PicParams->StatusReportFeedbackNumber;
3210 
3211     m_deblockingEnabled = m_vc1PicParams->entrypoint_fields.loopfilter;
3212     m_width             = m_vc1PicParams->coded_width;
3213     m_height            = m_vc1PicParams->coded_height;
3214     m_picWidthInMb =
3215         ((uint16_t)m_width + CODECHAL_MACROBLOCK_WIDTH - 1) / CODECHAL_MACROBLOCK_WIDTH;
3216     m_picHeightInMb =
3217         ((uint16_t)m_height + CODECHAL_MACROBLOCK_HEIGHT - 1) / CODECHAL_MACROBLOCK_HEIGHT;
3218 
3219     if (CodecHal_PictureIsField(currPic) && (m_picHeightInMb % 2))
3220     {
3221         m_vc1OddFrameHeight = true;
3222     }
3223     else
3224     {
3225         m_vc1OddFrameHeight = false;
3226     }
3227 
3228     // Overwrite the actual surface height with the coded height and width of the frame
3229     // for VC1 since it's possible for a VC1 frame to change size during playback
3230     m_destSurface.dwWidth  = m_width;
3231     m_destSurface.dwHeight = m_height;
3232 
3233     bool bOLPParamsAvailable =
3234         m_vc1PicParams->range_mapping_fields.range_mapping_enabled || m_vc1PicParams->UpsamplingFlag;
3235 
3236     if (m_decodeParams.m_deblockSurface &&
3237         ((m_vc1PicParams->DeblockedPicIdx != m_vc1PicParams->CurrPic.FrameIdx) || bOLPParamsAvailable) &&
3238         !(CodecHal_PictureIsField(currPic) && m_vc1PicParams->picture_fields.is_first_field))
3239     {
3240         m_olpNeeded      = true;
3241         m_deblockSurface = *(m_decodeParams.m_deblockSurface);
3242     }
3243 
3244     if (m_decodeParams.m_vc1BitplaneSize == 0)
3245     {
3246         m_vc1PicParams->raw_coding.bitplane_present = 0;
3247     }
3248 
3249     if (m_vc1PicParams->raw_coding.bitplane_present)
3250     {
3251         m_resBitplaneBuffer = *(m_decodeParams.m_bitplaneBuffer);
3252     }
3253 
3254     bool pictureIsI = m_mfxInterface->IsVc1IPicture(currPic, m_vc1PicParams->picture_fields.is_first_field, picType);
3255     bool pictureIsP = m_mfxInterface->IsVc1PPicture(currPic, m_vc1PicParams->picture_fields.is_first_field, picType);
3256     bool pictureIsB =
3257         (m_mfxInterface->IsVc1BPicture(currPic, m_vc1PicParams->picture_fields.is_first_field, picType) ||
3258             m_mfxInterface->IsVc1BIPicture(currPic, m_vc1PicParams->picture_fields.is_first_field, picType));
3259 
3260     // Save anchor picture type and field structure (TFF/BFF)
3261     if (!pictureIsB)
3262     {
3263         m_prevAnchorPictureTff = (uint16_t)m_vc1PicParams->picture_fields.top_field_first;
3264         if (CodecHal_PictureIsBottomField(currPic))
3265         {
3266             m_prevOddAnchorPictureIsP = pictureIsP;
3267         }
3268         else
3269         {
3270             m_prevEvenAnchorPictureIsP = pictureIsP;
3271         }
3272     }
3273 
3274     if (m_unequalFieldWaInUse && CodecHal_PictureIsField(currPic))
3275     {
3276         CODECHAL_DECODE_CHK_STATUS_RETURN(InitializeUnequalFieldSurface(
3277             (uint8_t)m_vc1PicParams->CurrPic.FrameIdx,
3278             m_renderContextUsesNullHw));
3279         CODECHAL_DECODE_CHK_STATUS_RETURN(InitializeUnequalFieldSurface(
3280             (uint8_t)m_vc1PicParams->ForwardRefIdx,
3281             m_renderContextUsesNullHw));
3282         CODECHAL_DECODE_CHK_STATUS_RETURN(InitializeUnequalFieldSurface(
3283             (uint8_t)m_vc1PicParams->BackwardRefIdx,
3284             m_renderContextUsesNullHw));
3285     }
3286 
3287     m_perfType = pictureIsI ? I_TYPE : (pictureIsP ? P_TYPE : B_TYPE);
3288 
3289     m_crrPic = currPic;
3290     m_secondField = (m_vc1PicParams->picture_fields.is_first_field == 1) ? false : true;
3291 
3292     CODECHAL_DEBUG_TOOL(
3293         CODECHAL_DECODE_CHK_NULL_RETURN(m_debugInterface);
3294         m_debugInterface->m_currPic     = m_crrPic;
3295         m_debugInterface->m_secondField = m_secondField;
3296         m_debugInterface->m_frameType   = m_perfType;
3297 
3298         if (m_vc1PicParams) {
3299             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpPicParams(
3300                 m_vc1PicParams));
3301         }
3302 
3303         if (m_vc1SliceParams) {
3304             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpSliceParams(
3305                 m_vc1SliceParams));
3306         }
3307 
3308         if (m_vc1MbParams) {
3309             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpMbParams(
3310                 m_vc1MbParams));
3311         }
3312 
3313         if (m_deblockDataBuffer) {
3314             //Dump decode deblocking
3315             CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpData(
3316                 m_deblockDataBuffer,
3317                 m_decodeParams.m_deblockDataSize,
3318                 CodechalDbgAttr::attrDeblocking,
3319                 "_DEC"));
3320         }
3321 
3322         if (m_decodeParams.m_vc1BitplaneSize != 0) {
3323             CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
3324                 &m_resBitplaneBuffer,
3325                 CodechalDbgAttr::attrVc1Bitplane,
3326                 "_DEC",
3327                 m_decodeParams.m_vc1BitplaneSize));
3328 
3329         })
3330 
3331     return eStatus;
3332 }
3333 
DecodeStateLevel()3334 MOS_STATUS CodechalDecodeVc1::DecodeStateLevel()
3335 {
3336     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3337 
3338     CODECHAL_DECODE_FUNCTION_ENTER;
3339 
3340     PCODEC_REF_LIST     *vc1RefList;
3341     vc1RefList = &(m_vc1RefList[0]);
3342 
3343     uint8_t destIdx   = m_vc1PicParams->CurrPic.FrameIdx;
3344     uint8_t fwdRefIdx = (uint8_t)m_vc1PicParams->ForwardRefIdx;
3345     uint8_t bwdRefIdx = (uint8_t)m_vc1PicParams->BackwardRefIdx;
3346 
3347     bool isIPicture = m_mfxInterface->IsVc1IPicture(
3348                           m_vc1PicParams->CurrPic,
3349                           m_vc1PicParams->picture_fields.is_first_field,
3350                           m_vc1PicParams->picture_fields.picture_type)
3351                           ? true
3352                           : false;
3353     bool isPPicture = m_mfxInterface->IsVc1PPicture(
3354                           m_vc1PicParams->CurrPic,
3355                           m_vc1PicParams->picture_fields.is_first_field,
3356                           m_vc1PicParams->picture_fields.picture_type)
3357                           ? true
3358                           : false;
3359     bool isBPicture = m_mfxInterface->IsVc1BPicture(
3360                           m_vc1PicParams->CurrPic,
3361                           m_vc1PicParams->picture_fields.is_first_field,
3362                           m_vc1PicParams->picture_fields.picture_type)
3363                           ? true
3364                           : false;
3365 
3366     PMOS_SURFACE    destSurface;
3367     PMOS_RESOURCE   fwdRefSurface, bwdRefSurface;
3368     if (m_unequalFieldWaInUse && CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
3369     {
3370         destSurface =
3371             &(m_unequalFieldSurface[vc1RefList[destIdx]->dwUnequalFieldSurfaceIdx]);
3372         fwdRefSurface =
3373             &(m_unequalFieldSurface[vc1RefList[fwdRefIdx]->dwUnequalFieldSurfaceIdx].OsResource);
3374         bwdRefSurface =
3375             &(m_unequalFieldSurface[vc1RefList[bwdRefIdx]->dwUnequalFieldSurfaceIdx].OsResource);
3376 
3377         // Overwrite the actual surface height with the coded height and width of the frame
3378         // for VC1 since it's possible for a VC1 frame to change size during playback
3379         destSurface->dwWidth = m_width;
3380         destSurface->dwHeight = m_height;
3381     }
3382     else
3383     {
3384         destSurface   = &m_destSurface;
3385         fwdRefSurface = &(vc1RefList[fwdRefIdx]->resRefPic);
3386         bwdRefSurface = &(vc1RefList[bwdRefIdx]->resRefPic);
3387     }
3388 
3389     // For SP/MP short format
3390     if (m_shortFormatInUse &&
3391         !m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
3392     {
3393         CODECHAL_DECODE_CHK_STATUS_RETURN(ConstructBistreamBuffer());
3394     }
3395 
3396     MOS_COMMAND_BUFFER  cmdBuffer;
3397     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
3398 
3399     auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
3400     HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
3401 
3402     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS   pipeModeSelectParams;
3403     pipeModeSelectParams.Mode = m_mode;
3404     pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled;
3405     pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
3406     pipeModeSelectParams.bPreDeblockOutEnable  = !m_deblockingEnabled;
3407     pipeModeSelectParams.bShortFormatInUse     = m_shortFormatInUse;
3408     pipeModeSelectParams.bVC1OddFrameHeight    = m_vc1OddFrameHeight;
3409 
3410     MHW_VDBOX_SURFACE_PARAMS    surfaceParams;
3411     MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
3412     surfaceParams.Mode = m_mode;
3413     surfaceParams.psSurface = destSurface;
3414 
3415     MHW_VDBOX_PIPE_BUF_ADDR_PARAMS  pipeBufAddrParams;
3416     pipeBufAddrParams.Mode = m_mode;
3417     if (m_deblockingEnabled)
3418     {
3419         pipeBufAddrParams.psPostDeblockSurface = destSurface;
3420     }
3421     else
3422     {
3423         pipeBufAddrParams.psPreDeblockSurface = destSurface;
3424     }
3425 
3426 #ifdef _MMC_SUPPORTED
3427     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
3428 #endif
3429 
3430     // when there is not a forward or backward reference,
3431     // the index is set to the destination frame index
3432     m_presReferences[CodechalDecodeFwdRefTop] =
3433         m_presReferences[CodechalDecodeFwdRefBottom] =
3434             fwdRefSurface;
3435     m_presReferences[CodechalDecodeBwdRefTop] =
3436         m_presReferences[CodechalDecodeBwdRefBottom] =
3437             bwdRefSurface;
3438     // special case for second fields
3439     if (!m_vc1PicParams->picture_fields.is_first_field &&
3440         !m_mfxInterface->IsVc1IPicture(
3441             m_vc1PicParams->CurrPic,
3442             m_vc1PicParams->picture_fields.is_first_field,
3443             m_vc1PicParams->picture_fields.picture_type))
3444     {
3445         if (m_vc1PicParams->picture_fields.top_field_first)
3446         {
3447             m_presReferences[CodechalDecodeFwdRefTop] =
3448                 &destSurface->OsResource;
3449         }
3450         else
3451         {
3452             m_presReferences[CodechalDecodeFwdRefBottom] =
3453                 &destSurface->OsResource;
3454         }
3455     }
3456 
3457     // set all ref pic addresses to valid addresses for error concealment purpose
3458     for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
3459     {
3460         if (m_presReferences[i] == nullptr &&
3461             MEDIA_IS_WA(m_waTable, WaDummyReference) &&
3462             !Mos_ResourceIsNull(&m_dummyReference.OsResource))
3463         {
3464             m_presReferences[i] = &m_dummyReference.OsResource;
3465         }
3466     }
3467 
3468     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(pipeBufAddrParams.presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC, m_presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC));
3469 
3470     pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
3471         &m_resMfdDeblockingFilterRowStoreScratchBuffer;
3472 
3473     if (m_streamOutEnabled)
3474     {
3475         pipeBufAddrParams.presStreamOutBuffer =
3476             &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
3477     }
3478 
3479 #ifdef _MMC_SUPPORTED
3480     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));
3481 
3482     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
3483 #endif
3484 
3485     CODECHAL_DEBUG_TOOL(
3486         for (int i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
3487         {
3488             if (pipeBufAddrParams.presReferences[i])
3489             {
3490                 MOS_SURFACE dstSurface;
3491 
3492                 MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
3493                 dstSurface.Format = Format_NV12;
3494                 dstSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
3495                 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
3496                     m_osInterface,
3497                     &dstSurface));
3498 
3499                 m_debugInterface->m_refIndex = (uint16_t)i;
3500                 std::string refSurfName      = "RefSurf[" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex)) + "]";
3501                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
3502                     &dstSurface,
3503                     CodechalDbgAttr::attrDecodeReferenceSurfaces,
3504                     refSurfName.data()));
3505             }
3506         }
3507     )
3508 
3509     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS      indObjBaseAddrParams;
3510     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
3511     indObjBaseAddrParams.Mode = m_mode;
3512     if (m_shortFormatInUse &&
3513         !m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
3514     {
3515         indObjBaseAddrParams.dwDataSize     = m_dataSize + CODECHAL_DECODE_VC1_STUFFING_BYTES;
3516         indObjBaseAddrParams.presDataBuffer = &m_resPrivateBistreamBuffer;
3517     }
3518     else
3519     {
3520         indObjBaseAddrParams.dwDataSize     = m_dataSize;
3521         indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
3522     }
3523 
3524     MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS  bspBufBaseAddrParams;
3525     MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
3526     bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
3527 
3528     if (m_vc1PicParams->raw_coding.bitplane_present || m_shortFormatInUse)
3529     {
3530         bspBufBaseAddrParams.presBitplaneBuffer = &m_resBitplaneBuffer;
3531     }
3532 
3533     MHW_VDBOX_VC1_PRED_PIPE_PARAMS  vc1PredPipeParams;
3534     vc1PredPipeParams.pVc1PicParams = m_vc1PicParams;
3535     vc1PredPipeParams.ppVc1RefList = vc1RefList;
3536 
3537     MHW_VDBOX_VC1_PIC_STATE vc1PicState;
3538     vc1PicState.pVc1PicParams             = m_vc1PicParams;
3539     vc1PicState.Mode = m_mode;
3540     vc1PicState.ppVc1RefList = vc1RefList;
3541     vc1PicState.wPrevAnchorPictureTFF     = m_prevAnchorPictureTff;
3542     vc1PicState.bPrevEvenAnchorPictureIsP = m_prevEvenAnchorPictureIsP;
3543     vc1PicState.bPrevOddAnchorPictureIsP  = m_prevOddAnchorPictureIsP;
3544 
3545     if (m_shortFormatInUse)
3546     {
3547         // APP does not provide REFDIST for I/P pictures correctly
3548         if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag &&
3549             CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
3550             (isIPicture || isPPicture) &&
3551             m_vc1PicParams->reference_fields.reference_distance_flag)
3552         {
3553             if (m_vc1PicParams->picture_fields.is_first_field)
3554             {
3555                 CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeader());
3556                 m_referenceDistance = m_vc1PicParams->reference_fields.reference_distance;
3557             }
3558             else
3559             {
3560                 m_vc1PicParams->reference_fields.reference_distance = m_referenceDistance;
3561             }
3562         }
3563 
3564         // APP does not provide BFRACTION correctly. So parse picture header to get BFRACTION
3565         if (isBPicture)
3566         {
3567             if (m_vc1PicParams->picture_fields.is_first_field)
3568             {
3569                 CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeader());
3570             }
3571         }
3572     }
3573 
3574     MHW_VDBOX_VC1_DIRECTMODE_PARAMS vc1DirectmodeParams;
3575     if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
3576     {
3577         uint8_t dmvBufferIdx                   = (m_vc1PicParams->CurrPic.PicFlags == PICTURE_BOTTOM_FIELD) ? CODECHAL_DECODE_VC1_DMV_ODD : CODECHAL_DECODE_VC1_DMV_EVEN;
3578         vc1DirectmodeParams.presDmvReadBuffer  = &m_resVc1BsdMvData[dmvBufferIdx];
3579         vc1DirectmodeParams.presDmvWriteBuffer = &m_resVc1BsdMvData[dmvBufferIdx];
3580     }
3581 
3582     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, !m_olpNeeded));
3583 
3584     if (m_statusQueryReportingEnabled)
3585     {
3586         CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
3587     }
3588 
3589     if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
3590         m_vc1PicParams->picture_fields.picture_type == vc1SkippedFrame)
3591     {
3592         // no further picture level commands needed for skipped frames
3593         m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
3594 
3595         return eStatus;
3596     }
3597 
3598     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
3599 
3600     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
3601 
3602     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
3603 
3604     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
3605 
3606     if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
3607     {
3608         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
3609     }
3610 
3611     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1PredPipeCmd(&cmdBuffer, &vc1PredPipeParams));
3612 
3613     if (m_intelEntrypointInUse || m_mode == CODECHAL_DECODE_MODE_VC1IT)
3614     {
3615         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1LongPicCmd(&cmdBuffer, &vc1PicState));
3616     }
3617     else if (m_shortFormatInUse)
3618     {
3619         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ShortPicCmd(&cmdBuffer, &vc1PicState));
3620     }
3621     else
3622     {
3623         CODECHAL_DECODE_ASSERTMESSAGE("Unsupported decode mode.");
3624         eStatus = MOS_STATUS_UNKNOWN;
3625         return eStatus;
3626     }
3627 
3628     if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
3629     {
3630         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1DirectmodeCmd(&cmdBuffer, &vc1DirectmodeParams));
3631     }
3632 
3633     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
3634 
3635     return eStatus;
3636 }
3637 
DecodePrimitiveLevel()3638 MOS_STATUS CodechalDecodeVc1::DecodePrimitiveLevel()
3639 {
3640     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3641 
3642     CODECHAL_DECODE_FUNCTION_ENTER;
3643 
3644     if (m_mode == CODECHAL_DECODE_MODE_VC1IT)
3645     {
3646         CODECHAL_DECODE_CHK_STATUS_RETURN(DecodePrimitiveLevelIT());
3647     }
3648     else if (m_mode == CODECHAL_DECODE_MODE_VC1VLD)
3649     {
3650         CODECHAL_DECODE_CHK_STATUS_RETURN(DecodePrimitiveLevelVLD())
3651     }
3652     else
3653     {
3654         return MOS_STATUS_UNKNOWN;
3655     }
3656 
3657     return eStatus;
3658 }
3659 
DecodePrimitiveLevelVLD()3660 MOS_STATUS CodechalDecodeVc1::DecodePrimitiveLevelVLD()
3661 {
3662     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3663 
3664     CODECHAL_DECODE_FUNCTION_ENTER;
3665 
3666     MOS_SYNC_PARAMS syncParams;
3667 
3668     // static VC1 slice parameters
3669     MHW_VDBOX_VC1_SLICE_STATE vc1SliceState;
3670     vc1SliceState.presDataBuffer = &m_resDataBuffer;
3671 
3672     uint16_t frameFieldHeightInMb;
3673     CodecHal_GetFrameFieldHeightInMb(
3674         m_vc1PicParams->CurrPic,
3675         m_picHeightInMb,
3676         frameFieldHeightInMb);
3677 
3678     MOS_COMMAND_BUFFER cmdBuffer;
3679     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
3680 
3681     if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
3682         m_vc1PicParams->picture_fields.picture_type == vc1SkippedFrame)
3683     {
3684         CODECHAL_DECODE_CHK_STATUS_RETURN(HandleSkipFrame());
3685         goto submit;
3686     }
3687     else
3688     {
3689         PCODEC_VC1_SLICE_PARAMS slc             = m_vc1SliceParams;
3690         bool firstValidSlice = true;
3691         int prevValidSlc = 0;
3692         for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
3693         {
3694             m_vldSliceRecord[slcCount].dwSliceYOffset     = slc->slice_vertical_position;
3695             m_vldSliceRecord[slcCount].dwNextSliceYOffset = frameFieldHeightInMb;  // init to last slice
3696 
3697             int32_t length = slc->slice_data_size >> 3;
3698             int32_t offset = slc->macroblock_offset >> 3;
3699 
3700             CodechalResLock ResourceLock(m_osInterface, &m_resDataBuffer);
3701             auto buf = (uint8_t*)ResourceLock.Lock(CodechalResLock::readOnly);
3702             if (offset > 3 && buf != nullptr &&
3703                 m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
3704             {
3705                 int i = 0;
3706                 int j = 0;
3707                 buf += slc->slice_data_offset;
3708 
3709                 for (i = 0, j = 0; i < offset - 1; i++, j++)
3710                 {
3711                     if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4)
3712                     {
3713                         i++, j += 2;
3714                     }
3715                 }
3716                 if (i == offset - 1)
3717                 {
3718                     if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4)
3719                     {
3720                         buf[j + 2] = 0;
3721                         j++;
3722                     }
3723                     j++;
3724                 }
3725                 offset = (8 * j + slc->macroblock_offset % 8)>>3;
3726             }
3727 
3728             // Check that the slice data does not overrun the bitstream buffer size
3729             if (((uintptr_t)(slc->slice_data_offset) + length) > m_dataSize)
3730             {
3731                 length = m_dataSize - (uintptr_t)(slc->slice_data_offset);
3732 
3733                 if (length < 0)
3734                 {
3735                     length = 0;
3736                 }
3737             }
3738 
3739             // Error handling for garbage data
3740             if (((uintptr_t)(slc->slice_data_offset)) > m_dataSize)
3741             {
3742                 slc++;
3743                 m_vldSliceRecord[slcCount].dwSkip = true;
3744                 continue;
3745             }
3746 
3747             // Check offset not larger than slice length, can have slice length of 0
3748             if (offset > length)
3749             {
3750                 slc++;
3751                 m_vldSliceRecord[slcCount].dwSkip = true;
3752                 continue;
3753             }
3754 
3755             // Check that the slices do not overlap, else do not send the lower slice
3756             if (!firstValidSlice &&
3757                 (m_vldSliceRecord[slcCount].dwSliceYOffset <= m_vldSliceRecord[prevValidSlc].dwSliceYOffset))
3758             {
3759                 slc++;
3760                 m_vldSliceRecord[slcCount].dwSkip = true;
3761                 continue;
3762             }
3763 
3764             if (firstValidSlice)
3765             {
3766                 // Ensure that the first slice starts from 0
3767                 m_vldSliceRecord[slcCount].dwSliceYOffset = 0;
3768                 slc->slice_vertical_position = 0;
3769             }
3770             else
3771             {
3772                 // Set next slice start Y offset of previous slice
3773                 m_vldSliceRecord[prevValidSlc].dwNextSliceYOffset =
3774                     m_vldSliceRecord[slcCount].dwSliceYOffset;
3775             }
3776 
3777             if (m_shortFormatInUse)
3778             {
3779                 if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
3780                 {
3781                     if ((slc->macroblock_offset >> 3) < CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH)
3782                     {
3783                         slc++;
3784                         m_vldSliceRecord[slcCount].dwSkip = true;
3785                         continue;
3786                     }
3787 
3788                     // set macroblock_offset of the first slice to 0 match HW expectations.
3789                     if (slcCount == 0)
3790                     {
3791                         slc->macroblock_offset = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH << 3;
3792                     }
3793 
3794                     offset = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH;
3795                 }
3796                 else // Simple Profile or Main Profile
3797                 {
3798                     {
3799                         offset = CODECHAL_DECODE_VC1_STUFFING_BYTES - 1;
3800                         length += CODECHAL_DECODE_VC1_STUFFING_BYTES;
3801                         slc->macroblock_offset += CODECHAL_DECODE_VC1_STUFFING_BYTES << 3;
3802                         slc->macroblock_offset &= (~0x7); // Clear bit offset of first MB for short format
3803                     }
3804                 }
3805             }
3806 
3807             m_vldSliceRecord[slcCount].dwOffset = offset;
3808             m_vldSliceRecord[slcCount].dwLength = length - offset;
3809             firstValidSlice = false;
3810             prevValidSlc = slcCount;
3811             slc++;
3812         }
3813 
3814         if (m_shortFormatInUse &&
3815             m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
3816         {
3817             CODECHAL_DECODE_CHK_STATUS_RETURN(GetSliceMbDataOffset());
3818         }
3819 
3820         // Reset slc pointer
3821         slc -= m_numSlices;
3822 
3823         //------------------------------------
3824         // Fill BSD Object Commands
3825         //------------------------------------
3826         for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
3827         {
3828             if (m_vldSliceRecord[slcCount].dwSkip)
3829             {
3830                 slc++;
3831                 continue;
3832             }
3833 
3834             vc1SliceState.pSlc = slc;
3835             vc1SliceState.dwOffset               = m_vldSliceRecord[slcCount].dwOffset;
3836             vc1SliceState.dwLength               = m_vldSliceRecord[slcCount].dwLength;
3837             vc1SliceState.dwNextVerticalPosition = m_vldSliceRecord[slcCount].dwNextSliceYOffset;
3838 
3839             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1BsdObjectCmd(&cmdBuffer, &vc1SliceState));
3840 
3841             slc++;
3842         }
3843 
3844         // Free VLD slice record
3845         MOS_ZeroMemory(m_vldSliceRecord, (m_numSlices * sizeof(CODECHAL_VC1_VLD_SLICE_RECORD)));
3846     }
3847 
3848     // Check if destination surface needs to be synchronized
3849     if (m_unequalFieldWaInUse &&
3850         CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
3851         !m_vc1PicParams->picture_fields.is_first_field)
3852     {
3853         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
3854         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
3855 
3856         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
3857     }
3858     else
3859     {
3860         // Check if destination surface needs to be synchronized
3861         syncParams = g_cInitSyncParams;
3862         syncParams.GpuContext = m_videoContext;
3863         syncParams.presSyncResource         = &m_destSurface.OsResource;
3864         syncParams.bReadOnly = false;
3865         syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
3866         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
3867 
3868         if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) ||
3869             m_vc1PicParams->picture_fields.is_first_field)
3870         {
3871             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
3872             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
3873 
3874             // Update the resource tag (s/w tag) for On-Demand Sync
3875             m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
3876         }
3877 
3878         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
3879         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
3880 
3881         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
3882 
3883         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
3884         if (m_osInterface->bTagResourceSync &&
3885             !(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && m_vc1PicParams->picture_fields.is_first_field))
3886         {
3887             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
3888         }
3889     }
3890 
3891 submit:
3892     if (m_statusQueryReportingEnabled)
3893     {
3894         CodechalDecodeStatusReport decodeStatusReport;
3895 
3896         decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
3897         decodeStatusReport.m_currDecodedPic     = m_vc1PicParams->CurrPic;
3898         if (m_olpNeeded)
3899         {
3900             CODECHAL_DEBUG_TOOL(
3901                 decodeStatusReport.m_currDeblockedPic.FrameIdx = (uint8_t)m_vc1PicParams->DeblockedPicIdx;
3902                 decodeStatusReport.m_currDeblockedPic.PicFlags = PICTURE_FRAME;)
3903             decodeStatusReport.m_deblockedPicResOlp = m_deblockSurface.OsResource;
3904         }
3905         else
3906         {
3907             decodeStatusReport.m_currDeblockedPic = m_vc1PicParams->CurrPic;
3908         }
3909         decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
3910         decodeStatusReport.m_currDecodedPicRes = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic;
3911 
3912         CODECHAL_DEBUG_TOOL(
3913             decodeStatusReport.m_secondField =
3914                 (m_vc1PicParams->picture_fields.is_first_field == 1) ? false : true;
3915             decodeStatusReport.m_olpNeeded = m_olpNeeded;
3916             decodeStatusReport.m_frameType = m_perfType;)
3917 
3918         CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
3919     }
3920 
3921     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
3922 
3923     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
3924 
3925     CODECHAL_DEBUG_TOOL(
3926         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
3927             &cmdBuffer,
3928             CODECHAL_NUM_MEDIA_STATES,
3929             "_DEC"));
3930 
3931     //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
3932     //    m_debugInterface,
3933     //    &cmdBuffer));
3934     )
3935 
3936     if (m_huCCopyInUse)
3937     {
3938         syncParams = g_cInitSyncParams;
3939         syncParams.GpuContext = m_videoContextForWa;
3940         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
3941 
3942         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
3943 
3944         syncParams = g_cInitSyncParams;
3945         syncParams.GpuContext = m_videoContext;
3946         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
3947 
3948         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
3949 
3950         m_huCCopyInUse = false;
3951     }
3952 
3953     HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
3954 
3955     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
3956 
3957     CODECHAL_DEBUG_TOOL(
3958         m_mmc->UpdateUserFeatureKey(&m_destSurface);)
3959 
3960     if (m_unequalFieldWaInUse &&
3961         CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
3962         !m_vc1PicParams->picture_fields.is_first_field)
3963     {
3964         CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1RefList);
3965 
3966         uint32_t destFrameIdx = m_vc1PicParams->CurrPic.FrameIdx;
3967 
3968         CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture(
3969             m_unequalFieldSurface[m_vc1RefList[destFrameIdx]->dwUnequalFieldSurfaceIdx],
3970             m_destSurface,
3971             true,
3972             m_videoContextUsesNullHw));
3973     }
3974 
3975     if (m_olpNeeded)
3976     {
3977         CODECHAL_DECODE_CHK_STATUS_RETURN(PerformVc1Olp());
3978     }
3979     else
3980     {
3981         if (m_statusQueryReportingEnabled)
3982         {
3983             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
3984         }
3985     }
3986 
3987     // Needs to be re-set for Linux buffer re-use scenarios
3988     m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
3989 
3990     // Send the signal to indicate decode completion, in case On-Demand Sync is not present
3991     if (!(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
3992             m_vc1PicParams->picture_fields.is_first_field))
3993     {
3994         MOS_SYNC_PARAMS syncParams;
3995         syncParams = g_cInitSyncParams;
3996         syncParams.GpuContext = m_videoContext;
3997         syncParams.presSyncResource = &m_destSurface.OsResource;
3998 
3999         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
4000 
4001         if (m_olpNeeded)
4002         {
4003             syncParams = g_cInitSyncParams;
4004             syncParams.GpuContext = m_renderContext;
4005             syncParams.presSyncResource = &m_deblockSurface.OsResource;
4006 
4007             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
4008         }
4009     }
4010 
4011     m_olpNeeded = false;
4012 
4013     return eStatus;
4014 }
4015 
DecodePrimitiveLevelIT()4016 MOS_STATUS CodechalDecodeVc1::DecodePrimitiveLevelIT()
4017 {
4018     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4019 
4020     CODECHAL_DECODE_FUNCTION_ENTER;
4021 
4022     MOS_SYNC_PARAMS syncParams;
4023 
4024     PCODEC_VC1_MB_PARAMS mb = m_vc1MbParams;
4025 
4026     MHW_VDBOX_VC1_MB_STATE vc1MbState;
4027     MOS_ZeroMemory(&vc1MbState, sizeof(vc1MbState));
4028 
4029     // static VC1 MB parameters
4030     vc1MbState.presDataBuffer     = &m_resDataBuffer;
4031     vc1MbState.pVc1PicParams      = m_vc1PicParams;
4032     vc1MbState.pWaTable = m_waTable;
4033     vc1MbState.pDeblockDataBuffer = m_deblockDataBuffer;
4034     vc1MbState.dwDataSize         = m_dataSize;
4035     vc1MbState.wPicWidthInMb      = m_picWidthInMb;
4036     vc1MbState.wPicHeightInMb     = m_picHeightInMb;
4037     vc1MbState.PicFlags           = m_vc1PicParams->CurrPic.PicFlags;
4038     vc1MbState.bFieldPolarity     = m_fieldPolarity;
4039 
4040     uint16_t frameFieldHeightInMb;
4041     CodecHal_GetFrameFieldHeightInMb(
4042         m_vc1PicParams->CurrPic,
4043         m_picHeightInMb,
4044         frameFieldHeightInMb);
4045 
4046     MOS_COMMAND_BUFFER cmdBuffer;
4047     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4048 
4049     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(&cmdBuffer, &m_itObjectBatchBuffer));
4050 
4051     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(m_osInterface, &m_itObjectBatchBuffer));
4052 
4053     PMHW_BATCH_BUFFER batchBuffer = &m_itObjectBatchBuffer;
4054 
4055     uint32_t mbAddress = 0;
4056     uint32_t mbCount;
4057     for (mbCount = 0; mbCount < m_numMacroblocks; mbCount++)
4058     {
4059         vc1MbState.pMb = mb + mbCount;
4060 
4061         // Skipped MBs before current MB
4062         uint16_t skippedMBs = (mbCount) ?
4063             (mb[mbCount].mb_address - mb[mbCount - 1].mb_address - 1) :
4064             (mb[mbCount].mb_address);
4065 
4066         while (skippedMBs--)
4067         {
4068             vc1MbState.bMbHorizOrigin = (uint8_t)(mbAddress % m_picWidthInMb);
4069             vc1MbState.bMbVertOrigin  = (uint8_t)(mbAddress / m_picWidthInMb);
4070             vc1MbState.bSkipped = true;
4071 
4072             CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
4073 
4074             mbAddress++;
4075         }
4076 
4077         // Current MB
4078         if (mbCount + 1 == m_numMacroblocks)
4079         {
4080             vc1MbState.dwLength = m_dataSize - mb[mbCount].data_offset;
4081         }
4082         else
4083         {
4084             vc1MbState.dwLength = mb[mbCount + 1].data_offset - mb[mbCount].data_offset;
4085         }
4086 
4087         vc1MbState.bMbHorizOrigin = mb[mbCount].mb_address % m_picWidthInMb;
4088         vc1MbState.bMbVertOrigin  = mb[mbCount].mb_address / m_picWidthInMb;
4089         vc1MbState.dwOffset = (vc1MbState.dwLength) ? mb[mbCount].data_offset : 0;
4090         vc1MbState.bSkipped = false;
4091 
4092         if (m_vc1PicParams->entrypoint_fields.loopfilter)
4093         {
4094             eStatus = MOS_SecureMemcpy(vc1MbState.DeblockData,
4095                 CODEC_NUM_BLOCK_PER_MB,
4096                 m_deblockDataBuffer + CODEC_NUM_BLOCK_PER_MB * mb[mbCount].mb_address,
4097                 CODEC_NUM_BLOCK_PER_MB);
4098             if (eStatus != MOS_STATUS_SUCCESS)
4099             {
4100                 CODECHAL_DECODE_ASSERTMESSAGE("Failed to copy memory.");
4101                 m_olpNeeded = false;
4102                 return eStatus;
4103             }
4104         }
4105 
4106         if (!mb[mbCount].mb_type.intra_mb)
4107         {
4108             if (mb[mbCount].mb_type.motion_forward || mb[mbCount].mb_type.motion_backward)
4109             {
4110                 PackMotionVectors(
4111                     &vc1MbState,
4112                     (int16_t *)mb[mbCount].motion_vector,
4113                     (int16_t *)vc1MbState.PackedLumaMvs,
4114                     (int16_t *)&vc1MbState.PackedChromaMv);
4115             }
4116             else
4117             {
4118                 mb[mbCount].mb_type.motion_forward = 1;
4119                 MOS_ZeroMemory(vc1MbState.PackedLumaMvs, sizeof(vc1MbState.PackedLumaMvs)); // MV's of zero
4120                 vc1MbState.bMotionSwitch = 0;
4121             }
4122         }
4123 
4124         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
4125 
4126         mbAddress = mb[mbCount].mb_address;
4127     }
4128 
4129     m_fieldPolarity = vc1MbState.bFieldPolarity;
4130 
4131     // skipped MBs at the end
4132     uint16_t skippedMBs = m_picWidthInMb * frameFieldHeightInMb - mb[mbCount - 1].mb_address - 1;
4133 
4134     while (skippedMBs--)
4135     {
4136         vc1MbState.bSkipped = true;
4137         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState));
4138     }
4139 
4140     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(nullptr, &m_itObjectBatchBuffer));
4141 
4142     CODECHAL_DEBUG_TOOL(
4143         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
4144             batchBuffer,
4145             CODECHAL_NUM_MEDIA_STATES,
4146             "_DEC"));
4147     )
4148 
4149     CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(m_osInterface, &m_itObjectBatchBuffer, true));
4150 
4151     // Check if destination surface needs to be synchronized
4152     if (m_unequalFieldWaInUse &&
4153         CodecHal_PictureIsField(m_vc1PicParams->CurrPic))
4154     {
4155         if (!m_vc1PicParams->picture_fields.is_first_field)
4156         {
4157             MHW_MI_FLUSH_DW_PARAMS flushDwParams;
4158             MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
4159 
4160             CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
4161         }
4162     }
4163     else
4164     {
4165         syncParams = g_cInitSyncParams;
4166         syncParams.GpuContext = m_videoContext;
4167         syncParams.presSyncResource         = &m_destSurface.OsResource;
4168         syncParams.bReadOnly = false;
4169         syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
4170         syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
4171 
4172         if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) ||
4173             m_vc1PicParams->picture_fields.is_first_field)
4174         {
4175             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
4176             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
4177 
4178             // Update the resource tag (s/w tag) for On-Demand Sync
4179             m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
4180         }
4181 
4182         MHW_MI_FLUSH_DW_PARAMS flushDwParams;
4183         MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
4184 
4185         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
4186 
4187         // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
4188         if (m_osInterface->bTagResourceSync &&
4189             !(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && m_vc1PicParams->picture_fields.is_first_field))
4190         {
4191             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
4192         }
4193     }
4194 
4195     if (m_statusQueryReportingEnabled)
4196     {
4197         CodechalDecodeStatusReport decodeStatusReport;
4198 
4199         decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
4200         decodeStatusReport.m_currDecodedPic     = m_vc1PicParams->CurrPic;
4201         if (m_olpNeeded)
4202         {
4203             CODECHAL_DEBUG_TOOL(
4204                 decodeStatusReport.m_currDeblockedPic.FrameIdx = (uint8_t)m_vc1PicParams->DeblockedPicIdx;
4205                 decodeStatusReport.m_currDeblockedPic.PicFlags = PICTURE_FRAME;)
4206             decodeStatusReport.m_deblockedPicResOlp = m_deblockSurface.OsResource;
4207         }
4208         else
4209         {
4210             decodeStatusReport.m_currDeblockedPic = m_vc1PicParams->CurrPic;
4211         }
4212         decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
4213         decodeStatusReport.m_currDecodedPicRes = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic;
4214 
4215         CODECHAL_DEBUG_TOOL(
4216             decodeStatusReport.m_secondField =
4217                 (m_vc1PicParams->picture_fields.is_first_field == 1) ? false : true;
4218             decodeStatusReport.m_olpNeeded = m_olpNeeded;
4219             decodeStatusReport.m_frameType = m_perfType;)
4220 
4221         CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
4222     }
4223 
4224     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
4225 
4226     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4227 
4228     CODECHAL_DEBUG_TOOL(
4229         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
4230             &cmdBuffer,
4231             CODECHAL_NUM_MEDIA_STATES,
4232             "_DEC"));
4233 
4234         //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
4235         //    m_debugInterface,
4236         //    &cmdBuffer));
4237     )
4238 
4239     if (m_huCCopyInUse)
4240     {
4241         syncParams = g_cInitSyncParams;
4242         syncParams.GpuContext = m_videoContextForWa;
4243         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
4244 
4245         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
4246 
4247         syncParams = g_cInitSyncParams;
4248         syncParams.GpuContext = m_videoContext;
4249         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
4250 
4251         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4252 
4253         m_huCCopyInUse = false;
4254     }
4255 
4256     HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
4257 
4258     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
4259 
4260     CODECHAL_DEBUG_TOOL(
4261         m_mmc->UpdateUserFeatureKey(&m_destSurface);)
4262 
4263     if (m_unequalFieldWaInUse &&
4264         CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
4265         !m_vc1PicParams->picture_fields.is_first_field)
4266     {
4267         CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1RefList);
4268 
4269         uint32_t destFrameIdx = m_vc1PicParams->CurrPic.FrameIdx;
4270 
4271         CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture(
4272             m_unequalFieldSurface[m_vc1RefList[destFrameIdx]->dwUnequalFieldSurfaceIdx],
4273             m_destSurface,
4274             true,
4275             m_videoContextUsesNullHw));
4276     }
4277 
4278     if (m_olpNeeded)
4279     {
4280         CODECHAL_DECODE_CHK_STATUS_RETURN(PerformVc1Olp());
4281     }
4282     else
4283     {
4284         if (m_statusQueryReportingEnabled)
4285         {
4286             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
4287         }
4288     }
4289 
4290     // Needs to be re-set for Linux buffer re-use scenarios
4291     m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
4292 
4293     // Send the signal to indicate decode completion, in case On-Demand Sync is not present
4294     if (!(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) &&
4295             m_vc1PicParams->picture_fields.is_first_field))
4296     {
4297         MOS_SYNC_PARAMS syncParams;
4298         syncParams = g_cInitSyncParams;
4299         syncParams.GpuContext = m_videoContext;
4300         syncParams.presSyncResource = &m_destSurface.OsResource;
4301 
4302         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
4303 
4304         if (m_olpNeeded)
4305         {
4306             syncParams = g_cInitSyncParams;
4307             syncParams.GpuContext = m_renderContext;
4308             syncParams.presSyncResource = &m_deblockSurface.OsResource;
4309 
4310             CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
4311         }
4312     }
4313 
4314     m_olpNeeded = false;
4315 
4316     return eStatus;
4317 }
4318 
AddVc1OlpCmd(PCODECHAL_DECODE_VC1_OLP_PARAMS vc1OlpParams)4319 MOS_STATUS CodechalDecodeVc1::AddVc1OlpCmd(
4320     PCODECHAL_DECODE_VC1_OLP_PARAMS vc1OlpParams)
4321 {
4322     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4323 
4324     CODECHAL_DECODE_FUNCTION_ENTER;
4325 
4326     MhwRenderInterface *renderEngineInterface = m_hwInterface->GetRenderInterface();
4327     PMHW_KERNEL_STATE   kernelState           = &m_olpKernelState;
4328 
4329     // Launch media walker to handle Y component
4330     CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
4331     MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
4332     walkerCodecParams.WalkerMode = MHW_WALKER_MODE_SINGLE;
4333     walkerCodecParams.dwResolutionX = m_picWidthInMb;
4334     walkerCodecParams.dwResolutionY = m_picHeightInMb;
4335     walkerCodecParams.bNoDependency = true;     // force raster scan mode
4336 
4337     MHW_WALKER_PARAMS walkerParams;
4338     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
4339         m_hwInterface,
4340         &walkerParams,
4341         &walkerCodecParams));
4342 
4343     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaObjectWalkerCmd(
4344         vc1OlpParams->pCmdBuffer,
4345         &walkerParams));
4346 
4347     vc1OlpParams->pPipeControlParams->dwFlushMode = MHW_FLUSH_READ_CACHE;
4348     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(
4349         vc1OlpParams->pCmdBuffer,
4350         nullptr,
4351         vc1OlpParams->pPipeControlParams));
4352     vc1OlpParams->pPipeControlParams->dwFlushMode = MHW_FLUSH_WRITE_CACHE;
4353     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(
4354         vc1OlpParams->pCmdBuffer,
4355         nullptr,
4356         vc1OlpParams->pPipeControlParams));
4357 
4358     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddStateBaseAddrCmd(
4359         vc1OlpParams->pCmdBuffer,
4360         vc1OlpParams->pStateBaseAddrParams));
4361 
4362     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaVfeCmd(
4363         vc1OlpParams->pCmdBuffer,
4364         vc1OlpParams->pVfeParams));
4365 
4366     kernelState->dwCurbeOffset += kernelState->KernelParams.iCurbeLength;
4367     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaCurbeLoadCmd(
4368         vc1OlpParams->pCmdBuffer,
4369         vc1OlpParams->pCurbeLoadParams));
4370     kernelState->dwCurbeOffset -= kernelState->KernelParams.iCurbeLength;
4371 
4372     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaIDLoadCmd(
4373         vc1OlpParams->pCmdBuffer,
4374         vc1OlpParams->pIdLoadParams));
4375 
4376     // For UV component, block size changed in CURBE static data and keep FrameWidth/HeightInMb unchanged here
4377     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaObjectWalkerCmd(
4378         vc1OlpParams->pCmdBuffer,
4379         &walkerParams));
4380 
4381     return eStatus;
4382 }
4383 
PerformVc1Olp()4384 MOS_STATUS CodechalDecodeVc1::PerformVc1Olp()
4385 {
4386     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4387 
4388     CODECHAL_DECODE_FUNCTION_ENTER;
4389 
4390     MhwRenderInterface *renderEngineInterface = m_hwInterface->GetRenderInterface();
4391     PMHW_KERNEL_STATE         kernelState           = &m_olpKernelState;
4392     PMHW_STATE_HEAP_INTERFACE stateHeapInterface = renderEngineInterface->m_stateHeapInterface;
4393 
4394     CODECHAL_DECODE_CHK_NULL_RETURN(stateHeapInterface);
4395 
4396     MOS_SYNC_PARAMS syncParams;
4397     syncParams = g_cInitSyncParams;
4398     syncParams.GpuContext = m_videoContext;
4399     syncParams.presSyncResource = &m_resSyncObject;
4400 
4401     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
4402 
4403     syncParams = g_cInitSyncParams;
4404     syncParams.GpuContext = m_renderContext;
4405     syncParams.presSyncResource = &m_resSyncObject;
4406 
4407     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4408 
4409     // Initialize DSH kernel region
4410     m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext);
4411     m_osInterface->pfnResetOsStates(m_osInterface);
4412 
4413     m_osInterface->pfnSetPerfTag(
4414         m_osInterface,
4415         (uint16_t)(((m_mode << 4) & 0xF0) | OLP_TYPE));
4416     m_osInterface->pfnResetPerfBufferID(m_osInterface);
4417 
4418     CodecHalGetResourceInfo(m_osInterface, &m_deblockSurface);  // DstSurface
4419 
4420 #ifdef _MMC_SUPPORTED
4421     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->DisableSurfaceMmcState(&m_deblockSurface));
4422 #endif
4423 
4424     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
4425         stateHeapInterface,
4426         kernelState->KernelParams.iBTCount));
4427 
4428     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
4429         stateHeapInterface,
4430         kernelState,
4431         false,
4432         m_olpDshSize,
4433         false,
4434         m_decodeStatusBuf.m_swStoreData));
4435 
4436     MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
4437     MOS_ZeroMemory(&idParams, sizeof(idParams));
4438     idParams.pKernelState = kernelState;
4439     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetInterfaceDescriptor(
4440         stateHeapInterface,
4441         1,
4442         &idParams));
4443     CODECHAL_DECODE_CHK_STATUS_RETURN(SetCurbeOlp());
4444 
4445     // Send HW commands (including SSH)
4446     MOS_COMMAND_BUFFER cmdBuffer;
4447     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4448 
4449     MHW_PIPE_CONTROL_PARAMS pipeControlParams;
4450     MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
4451 
4452     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetDefaultSSEuSetting(CODECHAL_MEDIA_STATE_OLP, false, false, false));
4453 
4454     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
4455         &cmdBuffer, true));
4456 
4457     if (renderEngineInterface->GetL3CacheConfig()->bL3CachingEnabled)
4458     {
4459         CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->SetL3Cache(&cmdBuffer));
4460     }
4461 
4462     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->EnablePreemption(&cmdBuffer));
4463 
4464     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddPipelineSelectCmd(&cmdBuffer, false));
4465 
4466     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetBindingTable(
4467         stateHeapInterface,
4468         kernelState));
4469 
4470     // common function for codec needed when we make change for AVC
4471     MHW_RCS_SURFACE_PARAMS surfaceParamsSrc;
4472     MOS_ZeroMemory(&surfaceParamsSrc, sizeof(surfaceParamsSrc));
4473     surfaceParamsSrc.dwNumPlanes = 2;    // Y, UV
4474     surfaceParamsSrc.psSurface          = &m_destSurface;
4475     surfaceParamsSrc.psSurface->dwDepth = 1;    // depth needs to be 0 for codec 2D surface
4476                                                 // Y Plane
4477     surfaceParamsSrc.dwBindingTableOffset[MHW_Y_PLANE] = CODECHAL_DECODE_VC1_OLP_SRC_Y;
4478     surfaceParamsSrc.ForceSurfaceFormat[MHW_Y_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM;
4479     // UV Plane
4480     surfaceParamsSrc.dwBindingTableOffset[MHW_U_PLANE] = CODECHAL_DECODE_VC1_OLP_SRC_UV;
4481     surfaceParamsSrc.ForceSurfaceFormat[MHW_U_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R16_UINT;
4482     surfaceParamsSrc.dwBaseAddrOffset[MHW_U_PLANE] =
4483         m_destSurface.dwPitch *
4484         MOS_ALIGN_FLOOR(m_destSurface.UPlaneOffset.iYOffset, MOS_YTILE_H_ALIGNMENT);
4485     surfaceParamsSrc.dwHeightToUse[MHW_U_PLANE] = surfaceParamsSrc.psSurface->dwHeight / 2;
4486     surfaceParamsSrc.dwYOffset[MHW_U_PLANE] =
4487         (m_destSurface.UPlaneOffset.iYOffset % MOS_YTILE_H_ALIGNMENT);
4488 
4489 #ifdef _MMC_SUPPORTED
4490     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->GetSurfaceMmcState(surfaceParamsSrc.psSurface));
4491 #endif
4492 
4493     MHW_RCS_SURFACE_PARAMS surfaceParamsDst;
4494     MOS_ZeroMemory(&surfaceParamsDst, sizeof(surfaceParamsDst));
4495     surfaceParamsDst = surfaceParamsSrc;
4496     surfaceParamsDst.bIsWritable = true;
4497     surfaceParamsDst.psSurface                         = &m_deblockSurface;
4498     surfaceParamsDst.psSurface->dwDepth = 1;    // depth needs to be 0 for codec 2D surface
4499     surfaceParamsDst.dwBindingTableOffset[MHW_Y_PLANE] = CODECHAL_DECODE_VC1_OLP_DST_Y;
4500     surfaceParamsDst.dwBindingTableOffset[MHW_U_PLANE] = CODECHAL_DECODE_VC1_OLP_DST_UV;
4501 
4502     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState(
4503         stateHeapInterface,
4504         kernelState,
4505         &cmdBuffer,
4506         1,
4507         &surfaceParamsSrc));
4508     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState(
4509         stateHeapInterface,
4510         kernelState,
4511         &cmdBuffer,
4512         1,
4513         &surfaceParamsDst));
4514 
4515     MHW_STATE_BASE_ADDR_PARAMS stateBaseAddrParams;
4516     MOS_ZeroMemory(&stateBaseAddrParams, sizeof(stateBaseAddrParams));
4517     MOS_RESOURCE *dsh = nullptr, *ish = nullptr;
4518     CODECHAL_DECODE_CHK_NULL_RETURN(dsh = kernelState->m_dshRegion.GetResource());
4519     CODECHAL_DECODE_CHK_NULL_RETURN(ish = kernelState->m_ishRegion.GetResource());
4520     stateBaseAddrParams.presDynamicState = dsh;
4521     stateBaseAddrParams.dwDynamicStateSize = kernelState->m_dshRegion.GetHeapSize();
4522     stateBaseAddrParams.presInstructionBuffer = ish;
4523     stateBaseAddrParams.dwInstructionBufferSize = kernelState->m_ishRegion.GetHeapSize();
4524     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddStateBaseAddrCmd(&cmdBuffer, &stateBaseAddrParams));
4525 
4526     MHW_VFE_PARAMS vfeParams = {};
4527     vfeParams.pKernelState = kernelState;
4528     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaVfeCmd(&cmdBuffer, &vfeParams));
4529 
4530     MHW_CURBE_LOAD_PARAMS curbeLoadParams;
4531     MOS_ZeroMemory(&curbeLoadParams, sizeof(curbeLoadParams));
4532     curbeLoadParams.pKernelState = kernelState;
4533     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaCurbeLoadCmd(&cmdBuffer, &curbeLoadParams));
4534 
4535     MHW_ID_LOAD_PARAMS idLoadParams;
4536     MOS_ZeroMemory(&idLoadParams, sizeof(idLoadParams));
4537     idLoadParams.pKernelState = kernelState;
4538     idLoadParams.dwNumKernelsLoaded = 1;
4539     CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaIDLoadCmd(&cmdBuffer, &idLoadParams));
4540 
4541     CODECHAL_DEBUG_TOOL(
4542         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
4543             CODECHAL_MEDIA_STATE_OLP,
4544             MHW_DSH_TYPE,
4545             kernelState));
4546         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
4547             CODECHAL_MEDIA_STATE_OLP,
4548             MHW_SSH_TYPE,
4549             kernelState));
4550     )
4551 
4552         CODECHAL_DECODE_VC1_OLP_PARAMS vc1OlpParams;
4553     vc1OlpParams.pCmdBuffer = &cmdBuffer;
4554     vc1OlpParams.pPipeControlParams = &pipeControlParams;
4555     vc1OlpParams.pStateBaseAddrParams = &stateBaseAddrParams;
4556     vc1OlpParams.pVfeParams = &vfeParams;
4557     vc1OlpParams.pCurbeLoadParams = &curbeLoadParams;
4558     vc1OlpParams.pIdLoadParams = &idLoadParams;
4559     CODECHAL_DECODE_CHK_STATUS_RETURN(AddVc1OlpCmd(&vc1OlpParams));
4560 
4561     // Check if destination surface needs to be synchronized, before command buffer submission
4562     syncParams = g_cInitSyncParams;
4563     syncParams.GpuContext = m_renderContext;
4564     syncParams.presSyncResource         = &m_deblockSurface.OsResource;
4565     syncParams.bReadOnly = false;
4566     syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
4567     syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
4568 
4569     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
4570     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
4571 
4572     // Update the resource tag (s/w tag) for On-Demand Sync
4573     m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
4574 
4575     // Update GPU Sync tag for on demand synchronization
4576     if (m_osInterface->bTagResourceSync)
4577     {
4578 
4579         pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
4580         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams));
4581         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
4582     }
4583     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSubmitBlocks(
4584         stateHeapInterface,
4585         kernelState));
4586     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnUpdateGlobalCmdBufId(
4587         stateHeapInterface));
4588 
4589     // Add PipeControl to invalidate ISP and MediaState to avoid PageFault issue
4590     // This code is temporal and it will be moved to batch buffer end in short
4591     if (GFX_IS_GEN_9_OR_LATER(m_hwInterface->GetPlatform()))
4592     {
4593         MHW_PIPE_CONTROL_PARAMS pipeControlParams;
4594 
4595         MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
4596         pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
4597         pipeControlParams.bGenericMediaStateClear = true;
4598         pipeControlParams.bIndirectStatePointersDisable = true;
4599         pipeControlParams.bDisableCSStall = false;
4600         CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams));
4601 
4602         if (MEDIA_IS_WA(m_hwInterface->GetWaTable(), WaSendDummyVFEafterPipelineSelect))
4603         {
4604             MHW_VFE_PARAMS vfeStateParams = {};
4605             vfeStateParams.dwNumberofURBEntries = 1;
4606             CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaVfeCmd(&cmdBuffer, &vfeStateParams));
4607         }
4608     }
4609 
4610     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
4611 
4612     // To clear the SSEU values in the hw interface struct, so next kernel can be programmed correctly
4613     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, false, true));
4614 
4615     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4616 
4617     CODECHAL_DEBUG_TOOL(
4618         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
4619             &cmdBuffer,
4620             CODECHAL_MEDIA_STATE_OLP,
4621             "_DEC"));
4622     )
4623 
4624     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw));
4625 
4626     if (m_statusQueryReportingEnabled)
4627     {
4628         CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_renderContextUsesNullHw));
4629     }
4630 
4631     m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext);
4632 
4633     return eStatus;
4634 }
4635 
UpdateVc1KernelState()4636 MOS_STATUS CodechalDecodeVc1::UpdateVc1KernelState()
4637 {
4638     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4639 
4640     CODECHAL_DECODE_FUNCTION_ENTER;
4641 
4642     PMHW_STATE_HEAP_INTERFACE stateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface;
4643     PCODECHAL_DECODE_VC1_KERNEL_HEADER_CM  decodeKernel;
4644     PMHW_KERNEL_STATE                      kernelState = &m_olpKernelState;
4645 
4646     decodeKernel = (PCODECHAL_DECODE_VC1_KERNEL_HEADER_CM)kernelState->KernelParams.pBinary;
4647     CODECHAL_DECODE_CHK_NULL_RETURN(decodeKernel);
4648     kernelState->dwKernelBinaryOffset =
4649         decodeKernel->OLP.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT;
4650     m_olpDshSize =
4651         stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData() +
4652         (MOS_ALIGN_CEIL(m_olpCurbeStaticDataLength,
4653              stateHeapInterface->pStateHeapInterface->GetCurbeAlignment()) *
4654             2);
4655 
4656     return eStatus;
4657 }
4658 
InitKernelStateVc1Olp()4659 MOS_STATUS CodechalDecodeVc1::InitKernelStateVc1Olp()
4660 {
4661     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
4662 
4663     CODECHAL_DECODE_FUNCTION_ENTER;
4664 
4665     MhwRenderInterface *renderEngineInterface = m_hwInterface->GetRenderInterface();
4666     PMHW_STATE_HEAP_INTERFACE stateHeapInterface = renderEngineInterface->m_stateHeapInterface;
4667     CODECHAL_DECODE_CHK_NULL_RETURN(stateHeapInterface);
4668     PMHW_KERNEL_STATE kernelState = &m_olpKernelState;
4669 
4670     kernelState->KernelParams.pBinary      = m_olpKernelBase;
4671     kernelState->KernelParams.iSize        = m_olpKernelSize;
4672     kernelState->KernelParams.iBTCount = CODECHAL_DECODE_VC1_OLP_NUM_SURFACES;
4673     kernelState->KernelParams.iThreadCount = renderEngineInterface->GetHwCaps()->dwMaxThreads;
4674     kernelState->KernelParams.iCurbeLength = m_olpCurbeStaticDataLength;
4675     kernelState->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
4676     kernelState->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
4677     kernelState->KernelParams.iIdCount = 1;
4678 
4679     kernelState->dwCurbeOffset = stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
4680     CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
4681         stateHeapInterface,
4682         kernelState->KernelParams.iBTCount,
4683         &kernelState->dwSshSize,
4684         &kernelState->dwBindingTableSize));
4685 
4686     CODECHAL_DECODE_CHK_STATUS_RETURN(UpdateVc1KernelState());
4687 
4688     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(
4689         stateHeapInterface,
4690         &m_olpKernelState));
4691 
4692     return eStatus;
4693 }
4694 
SetCurbeOlp()4695 MOS_STATUS CodechalDecodeVc1::SetCurbeOlp()
4696 {
4697     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4698 
4699     CODECHAL_DECODE_FUNCTION_ENTER;
4700 
4701     CODECHAL_DECODE_CHK_NULL_RETURN(m_hwInterface->GetRenderInterface());
4702     CODECHAL_DECODE_CHK_NULL_RETURN(m_hwInterface->GetRenderInterface()->m_stateHeapInterface);
4703 
4704     PMHW_STATE_HEAP_INTERFACE stateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface;
4705 
4706     // Configure Curbe data for Y component
4707     CODECHAL_DECODE_VC1_OLP_STATIC_DATA cmd = g_cInit_CODECHAL_DECODE_VC1_OLP_STATIC_DATA;
4708 
4709     cmd.DW2.InterlaceFieldFlag      = CodecHal_PictureIsField(m_vc1PicParams->CurrPic);
4710     cmd.DW2.PictureUpsamplingFlag   = m_vc1PicParams->UpsamplingFlag;
4711     cmd.DW2.RangeExpansionFlag      = (m_vc1PicParams->range_mapping_fields.range_mapping_enabled != 0);
4712     cmd.DW2.Profile                 = m_vc1PicParams->sequence_fields.AdvancedProfileFlag;
4713     cmd.DW2.ComponentFlag           = 0;
4714 
4715     if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
4716     {
4717         cmd.DW2.RangeMapUV     = m_vc1PicParams->range_mapping_fields.chroma;
4718         cmd.DW2.RangeMapUVFlag = m_vc1PicParams->range_mapping_fields.chroma_flag;
4719         cmd.DW2.RangeMapY      = m_vc1PicParams->range_mapping_fields.luma;
4720         cmd.DW2.RangeMapYFlag  = m_vc1PicParams->range_mapping_fields.luma_flag;
4721     }
4722 
4723     CODECHAL_DECODE_CHK_STATUS_RETURN(m_olpKernelState.m_dshRegion.AddData(
4724         &cmd,
4725         m_olpKernelState.dwCurbeOffset,
4726         sizeof(cmd)));
4727 
4728     // Configure Curbe data for UV component
4729     cmd = g_cInit_CODECHAL_DECODE_VC1_OLP_STATIC_DATA;
4730 
4731     cmd.DW2.InterlaceFieldFlag      = CodecHal_PictureIsField(m_vc1PicParams->CurrPic);
4732     cmd.DW2.PictureUpsamplingFlag   = m_vc1PicParams->UpsamplingFlag;
4733     cmd.DW2.RangeExpansionFlag      = (m_vc1PicParams->range_mapping_fields.range_mapping_enabled != 0);
4734     cmd.DW2.Profile                 = m_vc1PicParams->sequence_fields.AdvancedProfileFlag;
4735     cmd.DW2.ComponentFlag           = 1;
4736 
4737     if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
4738     {
4739         cmd.DW2.RangeMapUV     = m_vc1PicParams->range_mapping_fields.chroma;
4740         cmd.DW2.RangeMapUVFlag = m_vc1PicParams->range_mapping_fields.chroma_flag;
4741         cmd.DW2.RangeMapY      = m_vc1PicParams->range_mapping_fields.luma;
4742         cmd.DW2.RangeMapYFlag  = m_vc1PicParams->range_mapping_fields.luma_flag;
4743     }
4744 
4745     cmd.DW4.SourceDataBindingIndex  = CODECHAL_DECODE_VC1_OLP_SRC_UV;
4746     cmd.DW5.DestDataBindingIndex    = CODECHAL_DECODE_VC1_OLP_DST_UV;
4747 
4748     CODECHAL_DECODE_CHK_STATUS_RETURN(m_olpKernelState.m_dshRegion.AddData(
4749         &cmd,
4750         m_olpKernelState.dwCurbeOffset +
4751             MOS_ALIGN_CEIL(m_olpCurbeStaticDataLength, stateHeapInterface->pStateHeapInterface->GetCurbeAlignment()),
4752         sizeof(cmd)));
4753 
4754     return eStatus;
4755 }
4756 
InitMmcState()4757 MOS_STATUS CodechalDecodeVc1::InitMmcState()
4758 {
4759 #ifdef _MMC_SUPPORTED
4760     m_mmc = MOS_New(CodechalMmcDecodeVc1, m_hwInterface, this);
4761     CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
4762 #endif
4763     return MOS_STATUS_SUCCESS;
4764 }
4765 
AllocateStandard(CodechalSetting * settings)4766 MOS_STATUS CodechalDecodeVc1::AllocateStandard(
4767     CodechalSetting *settings)
4768 {
4769     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4770 
4771     CODECHAL_DECODE_FUNCTION_ENTER;
4772 
4773     CODECHAL_DECODE_CHK_NULL_RETURN(settings);
4774 
4775     CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
4776 
4777     bool isComputeContextEnabled = false;
4778     MOS_GPUCTX_CREATOPTIONS createOption;
4779 
4780 #if (_DEBUG || _RELEASE_INTERNAL)
4781     MOS_USER_FEATURE_VALUE_DATA userFeatureData;
4782     MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
4783     MOS_UserFeature_ReadValue_ID(
4784         nullptr,
4785         __MEDIA_USER_FEATURE_VALUE_DECODE_ENABLE_COMPUTE_CONTEXT_ID,
4786         &userFeatureData,
4787         m_osInterface->pOsContext);
4788     isComputeContextEnabled = (userFeatureData.u32Data) ? true : false;
4789 #endif
4790 
4791     if (!MEDIA_IS_SKU(m_skuTable, FtrCCSNode))
4792     {
4793         isComputeContextEnabled = false;
4794     }
4795 
4796     if (isComputeContextEnabled)
4797     {
4798         // Create Render Context for field scaling
4799         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
4800             m_osInterface,
4801             MOS_GPU_CONTEXT_COMPUTE,
4802             MOS_GPU_NODE_COMPUTE,
4803             &createOption));
4804         m_renderContext = MOS_GPU_CONTEXT_COMPUTE;
4805     }
4806     else
4807     {
4808         // Create Render Context for field scaling
4809         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
4810             m_osInterface,
4811             MOS_GPU_CONTEXT_RENDER,
4812             MOS_GPU_NODE_3D,
4813             &createOption));
4814         m_renderContext = MOS_GPU_CONTEXT_RENDER;
4815     }
4816 
4817     m_intelEntrypointInUse = settings->intelEntrypointInUse;
4818     m_width = settings->width;
4819     m_height = settings->height;
4820     m_picWidthInMb         = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width);
4821     m_picHeightInMb        = (uint16_t)CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_height);
4822     m_shortFormatInUse     = settings->shortFormatInUse;
4823     m_huCCopyInUse         = false;
4824 
4825     CODECHAL_DECODE_CHK_STATUS_RETURN(InitKernelStateVc1Olp());
4826 
4827     CODECHAL_DEBUG_TOOL(
4828         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
4829             CODECHAL_MEDIA_STATE_OLP,
4830             MHW_ISH_TYPE,
4831             &m_olpKernelState));)
4832 
4833     // Picture Level Commands
4834     m_hwInterface->GetMfxStateCommandsDataSize(
4835         m_mode,
4836         &m_commandBufferSizeNeeded,
4837         &m_commandPatchListSizeNeeded,
4838         m_shortFormatInUse);
4839 
4840     // Primitive Level Commands
4841     m_hwInterface->GetMfxPrimitiveCommandsDataSize(
4842         m_mode,
4843         &m_standardDecodeSizeNeeded,
4844         &m_standardDecodePatchListSizeNeeded,
4845         m_shortFormatInUse);
4846 
4847     CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResources());
4848 
4849     return eStatus;
4850 }
4851 
CodechalDecodeVc1(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)4852 CodechalDecodeVc1::CodechalDecodeVc1(
4853     CodechalHwInterface   *hwInterface,
4854     CodechalDebugInterface* debugInterface,
4855     PCODECHAL_STANDARD_INFO standardInfo) :
4856     CodechalDecode(hwInterface, debugInterface, standardInfo),
4857     m_huCCopyInUse(0)
4858 {
4859     CODECHAL_DECODE_FUNCTION_ENTER;
4860 
4861     MOS_ZeroMemory(&m_resMfdDeblockingFilterRowStoreScratchBuffer, sizeof(m_resMfdDeblockingFilterRowStoreScratchBuffer));
4862     MOS_ZeroMemory(&m_resBsdMpcRowStoreScratchBuffer, sizeof(m_resBsdMpcRowStoreScratchBuffer));
4863     MOS_ZeroMemory(m_resVc1BsdMvData, sizeof(m_resVc1BsdMvData));
4864     MOS_ZeroMemory(&m_resSyncObject, sizeof(m_resSyncObject));
4865     MOS_ZeroMemory(&m_resPrivateBistreamBuffer, sizeof(m_resPrivateBistreamBuffer));
4866     MOS_ZeroMemory(&m_bitstream, sizeof(m_bitstream));
4867     MOS_ZeroMemory(&m_itObjectBatchBuffer, sizeof(m_itObjectBatchBuffer));
4868     MOS_ZeroMemory(m_unequalFieldSurface, sizeof(m_unequalFieldSurface));
4869     MOS_ZeroMemory(m_unequalFieldRefListIdx, sizeof(m_unequalFieldRefListIdx));
4870     MOS_ZeroMemory(&m_destSurface, sizeof(m_destSurface));
4871     MOS_ZeroMemory(&m_deblockSurface, sizeof(m_deblockSurface));
4872     MOS_ZeroMemory(&m_resDataBuffer, sizeof(m_resDataBuffer));
4873     MOS_ZeroMemory(&m_resBitplaneBuffer, sizeof(m_resBitplaneBuffer));
4874     MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(m_resSyncObjectWaContextInUse));
4875     MOS_ZeroMemory(&m_resSyncObjectVideoContextInUse, sizeof(m_resSyncObjectVideoContextInUse));
4876     MOS_ZeroMemory(m_presReferences, (sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC));
4877     MOS_ZeroMemory(m_vc1RefList, (sizeof(PCODEC_REF_LIST) * CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1));
4878 #if (_DEBUG || _RELEASE_INTERNAL)
4879     m_reportFrameCrc = true;
4880 #endif
4881     m_hwInterface = hwInterface;
4882 
4883 }
4884 
4885 #if USE_CODECHAL_DEBUG_TOOL
DumpPicParams(PCODEC_VC1_PIC_PARAMS vc1PicParams)4886 MOS_STATUS CodechalDecodeVc1::DumpPicParams(
4887     PCODEC_VC1_PIC_PARAMS           vc1PicParams)
4888 {
4889     CODECHAL_DEBUG_FUNCTION_ENTER;
4890 
4891     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
4892     {
4893         return MOS_STATUS_SUCCESS;
4894     }
4895 
4896     CODECHAL_DEBUG_CHK_NULL(vc1PicParams);
4897 
4898     std::ostringstream oss;
4899     oss.setf(std::ios::showbase | std::ios::uppercase);
4900     oss.setf(std::ios::hex, std::ios::basefield);
4901 
4902     oss<< "CurrPic FrameIdx: "<< +vc1PicParams->CurrPic.FrameIdx<<std::endl;
4903     oss<< "CurrPic PicFlags: "<< +vc1PicParams->CurrPic.PicFlags<<std::endl;
4904     oss<< "DeblockedPicIdx: "<< +vc1PicParams->DeblockedPicIdx<<std::endl;
4905     oss<< "ForwardRefIdx: "<< +vc1PicParams->ForwardRefIdx<<std::endl;
4906     oss<< "BackwardRefIdx: "<< +vc1PicParams->BackwardRefIdx<<std::endl;
4907 
4908     //Dump sequence_fields
4909     oss<< "sequence_fields value: "<< +vc1PicParams->sequence_fields.value<<std::endl;
4910     oss<< "pulldown: "<< +vc1PicParams->sequence_fields.pulldown<<std::endl;
4911     oss<< "interlace: "<< +vc1PicParams->sequence_fields.interlace<<std::endl;
4912     oss<< "tfcntrflag: "<< +vc1PicParams->sequence_fields.tfcntrflag<<std::endl;
4913     oss<< "finterpflag: "<< +vc1PicParams->sequence_fields.finterpflag<<std::endl;
4914     oss<< "psf: "<< +vc1PicParams->sequence_fields.psf<<std::endl;
4915     oss<< "multires: "<< +vc1PicParams->sequence_fields.multires<<std::endl;
4916     oss<< "overlap: "<< +vc1PicParams->sequence_fields.overlap<<std::endl;
4917     oss<< "syncmarker: "<< +vc1PicParams->sequence_fields.syncmarker<<std::endl;
4918     oss<< "rangered: "<< +vc1PicParams->sequence_fields.rangered<<std::endl;
4919     oss<< "max_b_frames: "<< +vc1PicParams->sequence_fields.max_b_frames<<std::endl;
4920     oss<< "AdvancedProfileFlag: "<< +vc1PicParams->sequence_fields.AdvancedProfileFlag<<std::endl;
4921     oss<< "coded_width: "<< +vc1PicParams->coded_width<<std::endl;
4922     oss<< "coded_height: "<< +vc1PicParams->coded_height<<std::endl;
4923 
4924     //Dump entrypoint_fields
4925     oss<< "broken_link: "<< +vc1PicParams->entrypoint_fields.broken_link<<std::endl;
4926     oss<< "closed_entry: "<< +vc1PicParams->entrypoint_fields.closed_entry<<std::endl;
4927     oss<< "panscan_flag: "<< +vc1PicParams->entrypoint_fields.panscan_flag<<std::endl;
4928     oss<< "loopfilter: "<< +vc1PicParams->entrypoint_fields.loopfilter<<std::endl;
4929     oss<< "conditional_overlap_flag: "<< +vc1PicParams->conditional_overlap_flag<<std::endl;
4930     oss<< "fast_uvmc_flag: "<< +vc1PicParams->fast_uvmc_flag<<std::endl;
4931 
4932     //Dump range_mapping_fields
4933     oss<< "range_mapping_fields range_mapping_enabled: "<< +vc1PicParams->range_mapping_fields.range_mapping_enabled<<std::endl;
4934     oss<< "luma_flag: "<< +vc1PicParams->range_mapping_fields.luma_flag<<std::endl;
4935     oss<< "luma: "<< +vc1PicParams->range_mapping_fields.luma<<std::endl;
4936     oss<< "chroma_flag: "<< +vc1PicParams->range_mapping_fields.chroma_flag<<std::endl;
4937     oss<< "chroma: "<< +vc1PicParams->range_mapping_fields.chroma<<std::endl;
4938     oss<< "UpsamplingFlag: "<< +vc1PicParams->UpsamplingFlag<<std::endl;
4939     oss<< "ScaleFactor: "<< +vc1PicParams->ScaleFactor<<std::endl;
4940     oss<< "b_picture_fraction: "<< +vc1PicParams->b_picture_fraction<<std::endl;
4941     oss<< "cbp_table: "<< +vc1PicParams->cbp_table<<std::endl;
4942     oss<< "mb_mode_table: "<< +vc1PicParams->mb_mode_table<<std::endl;
4943     oss<< "range_reduction_frame: "<< +vc1PicParams->range_reduction_frame<<std::endl;
4944     oss<< "rounding_control: "<< +vc1PicParams->rounding_control<<std::endl;
4945     oss<< "post_processing: "<< +vc1PicParams->post_processing<<std::endl;
4946     oss<< "picture_resolution_index: "<< +vc1PicParams->picture_resolution_index<<std::endl;
4947     oss<< "luma_scale: "<< +vc1PicParams->luma_scale<<std::endl;
4948     oss<< "luma_shift: "<< +vc1PicParams->luma_shift<<std::endl;
4949 
4950     //Dump picture_fields
4951     oss<< "picture_fields value: "<< +vc1PicParams->picture_fields.value<<std::endl;
4952     oss<< "picture_type: "<< +vc1PicParams->picture_fields.picture_type<<std::endl;
4953     oss<< "frame_coding_mode: "<< +vc1PicParams->picture_fields.frame_coding_mode<<std::endl;
4954     oss<< "top_field_first: "<< +vc1PicParams->picture_fields.top_field_first<<std::endl;
4955     oss<< "is_first_field: "<< +vc1PicParams->picture_fields.is_first_field<<std::endl;
4956     oss<< "intensity_compensation: "<< +vc1PicParams->picture_fields.intensity_compensation<<std::endl;
4957 
4958     //Dump raw_coding
4959     oss<< "raw_coding value: "<< +vc1PicParams->raw_coding.value<<std::endl;
4960     oss<< "bitplane_present: "<< +vc1PicParams->raw_coding.bitplane_present<<std::endl;
4961     oss<< "mv_type_mb: "<< +vc1PicParams->raw_coding.mv_type_mb<<std::endl;
4962     oss<< "direct_mb: "<< +vc1PicParams->raw_coding.direct_mb<<std::endl;
4963     oss<< "skip_mb: "<< +vc1PicParams->raw_coding.skip_mb<<std::endl;
4964     oss<< "field_tx: "<< +vc1PicParams->raw_coding.field_tx<<std::endl;
4965     oss<< "forward_mb: "<< +vc1PicParams->raw_coding.forward_mb<<std::endl;
4966     oss<< "ac_pred: "<< +vc1PicParams->raw_coding.ac_pred<<std::endl;
4967     oss<< "overflags: "<< +vc1PicParams->raw_coding.overflags<<std::endl;
4968 
4969     //Dump reference_fields
4970     oss<< "reference_fields value: "<< +vc1PicParams->reference_fields.value<<std::endl;
4971     oss<< "reference_distance_flag: "<< +vc1PicParams->reference_fields.reference_distance_flag<<std::endl;
4972     oss<< "reference_distance: "<< +vc1PicParams->reference_fields.reference_distance<<std::endl;
4973     oss<< "BwdReferenceDistance: "<< +vc1PicParams->reference_fields.BwdReferenceDistance<<std::endl;
4974     oss<< "num_reference_pictures: "<< +vc1PicParams->reference_fields.num_reference_pictures<<std::endl;
4975     oss<< "reference_field_pic_indicator: "<< +vc1PicParams->reference_fields.reference_field_pic_indicator<<std::endl;
4976 
4977     //Dump mv_fields
4978     oss<< "mv_fields value: "<< +vc1PicParams->mv_fields.value<<std::endl;
4979     oss<< "MvMode: "<< +vc1PicParams->mv_fields.MvMode<<std::endl;
4980     oss<< "UnifiedMvMode: "<< +vc1PicParams->mv_fields.UnifiedMvMode<<std::endl;
4981     oss<< "mv_table: "<< +vc1PicParams->mv_fields.mv_table<<std::endl;
4982     oss<< "two_mv_block_pattern_table: "<< +vc1PicParams->mv_fields.two_mv_block_pattern_table<<std::endl;
4983     oss<< "four_mv_switch: "<< +vc1PicParams->mv_fields.four_mv_switch<<std::endl;
4984     oss<< "four_mv_block_pattern_table: "<< +vc1PicParams->mv_fields.four_mv_block_pattern_table<<std::endl;
4985     oss<< "extended_mv_flag: "<< +vc1PicParams->mv_fields.extended_mv_flag<<std::endl;
4986     oss<< "extended_mv_range: "<< +vc1PicParams->mv_fields.extended_mv_range<<std::endl;
4987     oss<< "extended_dmv_flag: "<< +vc1PicParams->mv_fields.extended_dmv_flag<<std::endl;
4988     oss<< "extended_dmv_range: "<< +vc1PicParams->mv_fields.extended_dmv_range<<std::endl;
4989 
4990     //Dump pic_quantizer_fields
4991     oss<< "pic_quantizer_fields value: "<< +vc1PicParams->pic_quantizer_fields.value<<std::endl;
4992     oss<< "dquant: "<< +vc1PicParams->pic_quantizer_fields.dquant<<std::endl;
4993     oss<< "quantizer: "<< +vc1PicParams->pic_quantizer_fields.quantizer<<std::endl;
4994     oss<< "half_qp: "<< +vc1PicParams->pic_quantizer_fields.half_qp<<std::endl;
4995     oss<< "AltPQuantEdgeMask: "<< +vc1PicParams->pic_quantizer_fields.AltPQuantEdgeMask<<std::endl;
4996     oss<< "AltPQuantConfig: "<< +vc1PicParams->pic_quantizer_fields.AltPQuantConfig<<std::endl;
4997     oss<< "pic_quantizer_scale: "<< +vc1PicParams->pic_quantizer_fields.pic_quantizer_scale<<std::endl;
4998     oss<< "pic_quantizer_type: "<< +vc1PicParams->pic_quantizer_fields.pic_quantizer_type<<std::endl;
4999     oss<< "alt_pic_quantizer: "<< +vc1PicParams->pic_quantizer_fields.alt_pic_quantizer<<std::endl;
5000 
5001     //Dump transform_fields
5002     oss<< "transform_fields value: "<< +vc1PicParams->transform_fields.value<<std::endl;
5003     oss<< "variable_sized_transform_flag: "<< +vc1PicParams->transform_fields.variable_sized_transform_flag<<std::endl;
5004     oss<< "mb_level_transform_type_flag: "<< +vc1PicParams->transform_fields.mb_level_transform_type_flag<<std::endl;
5005     oss<< "frame_level_transform_type: "<< +vc1PicParams->transform_fields.frame_level_transform_type<<std::endl;
5006     oss<< "transform_ac_codingset_idx1: "<< +vc1PicParams->transform_fields.transform_ac_codingset_idx1<<std::endl;
5007     oss<< "transform_ac_codingset_idx2: "<< +vc1PicParams->transform_fields.transform_ac_codingset_idx2<<std::endl;
5008     oss<< "intra_transform_dc_table: "<< +vc1PicParams->transform_fields.intra_transform_dc_table<<std::endl;
5009     oss<< "StatusReportFeedbackNumber : "<< +vc1PicParams->StatusReportFeedbackNumber<<std::endl;
5010 
5011     const char* fileName = m_debugInterface->CreateFileName(
5012         "_DEC",
5013         CodechalDbgBufferType::bufPicParams,
5014         CodechalDbgExtType::txt);
5015 
5016     std::ofstream ofs(fileName, std::ios::out);
5017     ofs << oss.str();
5018     ofs.close();
5019     return MOS_STATUS_SUCCESS;
5020 }
5021 
DumpSliceParams(PCODEC_VC1_SLICE_PARAMS sliceControl)5022 MOS_STATUS CodechalDecodeVc1::DumpSliceParams(
5023     PCODEC_VC1_SLICE_PARAMS         sliceControl)
5024 {
5025     CODECHAL_DEBUG_FUNCTION_ENTER;
5026 
5027     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
5028     {
5029         return MOS_STATUS_SUCCESS;
5030     }
5031 
5032     CODECHAL_DEBUG_CHK_NULL(sliceControl);
5033 
5034     std::ostringstream oss;
5035     oss.setf(std::ios::showbase | std::ios::uppercase);
5036     oss.setf(std::ios::hex, std::ios::basefield);
5037 
5038     oss<< "slice_data_size: "<< +sliceControl->slice_data_size<<std::endl;
5039     oss<< "slice_data_offset: "<< +sliceControl->slice_data_offset<<std::endl;
5040     oss<< "macroblock_offset: "<< +sliceControl->macroblock_offset<<std::endl;
5041     oss<< "slice_vertical_position: "<< +sliceControl->slice_vertical_position<<std::endl;
5042 
5043     const char* fileName = m_debugInterface->CreateFileName(
5044         "_DEC",
5045         CodechalDbgBufferType::bufSlcParams,
5046         CodechalDbgExtType::txt);
5047 
5048     std::ofstream ofs(fileName, std::ios::out);
5049     ofs << oss.str();
5050     ofs.close();
5051     return MOS_STATUS_SUCCESS;
5052 }
5053 
DumpMbParams(PCODEC_VC1_MB_PARAMS mbParams)5054 MOS_STATUS CodechalDecodeVc1::DumpMbParams(
5055     PCODEC_VC1_MB_PARAMS            mbParams)
5056 {
5057     CODECHAL_DEBUG_FUNCTION_ENTER;
5058 
5059     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrMbParams))
5060     {
5061         return MOS_STATUS_SUCCESS;
5062     }
5063 
5064     CODECHAL_DEBUG_CHK_NULL(mbParams);
5065 
5066     std::ostringstream oss;
5067     oss.setf(std::ios::showbase | std::ios::uppercase);
5068     oss.setf(std::ios::hex, std::ios::basefield);
5069 
5070     oss<< "mb_address: "<< +mbParams->mb_address<<std::endl;
5071     oss<< "mb_skips_following: "<< +mbParams->mb_skips_following<<std::endl;
5072     oss<< "data_offset: "<< +mbParams->data_offset<<std::endl;
5073     oss<< "data_length: "<< +mbParams->data_length<<std::endl;
5074 
5075     //Dump num_coef[CODEC_NUM_BLOCK_PER_MB]
5076     for(uint16_t i=0;i<CODEC_NUM_BLOCK_PER_MB;++i)
5077     {
5078         oss<< "num_coef["<<+i<<"]: "<< +mbParams->num_coef[i]<<std::endl;
5079     }
5080     //Dump union mb_type
5081     oss<< "mb_type.value: "<< +mbParams->mb_type.value<<std::endl;
5082     oss<< "mb_type.intra_mb: "<< +mbParams->mb_type.intra_mb<<std::endl;
5083     oss<< "mb_type.motion_forward: "<< +mbParams->mb_type.motion_forward<<std::endl;
5084     oss<< "mb_type.motion_backward: "<< +mbParams->mb_type.motion_backward<<std::endl;
5085     oss<< "mb_type.motion_4mv: "<< +mbParams->mb_type.motion_4mv<<std::endl;
5086     oss<< "mb_type.h261_loopfilter: "<<+mbParams->mb_type.h261_loopfilter<<std::endl;
5087     oss<< "mb_type.field_residual: "<< +mbParams->mb_type.field_residual<<std::endl;
5088     oss<< "mb_type.mb_scan_method: "<< +mbParams->mb_type.mb_scan_method<<std::endl;
5089     oss<< "mb_type.motion_type: "<< +mbParams->mb_type.motion_type<<std::endl;
5090     oss<< "mb_type.host_resid_diff: "<< +mbParams->mb_type.host_resid_diff<<std::endl;
5091     oss<< "mb_type.reserved: "<< +mbParams->mb_type.reserved<<std::endl;
5092     oss<< "mb_type.mvert_field_sel_0: "<< +mbParams->mb_type.mvert_field_sel_0<<std::endl;
5093     oss<< "mb_type.mvert_field_sel_1: "<< +mbParams->mb_type.mvert_field_sel_1<<std::endl;
5094     oss<< "mb_type.mvert_field_sel_2: "<< +mbParams->mb_type.mvert_field_sel_2<<std::endl;
5095     oss<< "mb_type.mvert_field_sel_3: "<< +mbParams->mb_type.mvert_field_sel_3<<std::endl;
5096 
5097     //Dump union pattern_code
5098     oss<< "pattern_code.value: "<< +mbParams->pattern_code.value<<std::endl;
5099     oss<< "pattern_code.block_coded_pattern: "<< +mbParams->pattern_code.block_coded_pattern<<std::endl;
5100     oss<< "pattern_code.block_luma_intra: "<< +mbParams->pattern_code.block_luma_intra<<std::endl;
5101     oss<< "pattern_code.block_chroma_intra: "<< +mbParams->pattern_code.block_chroma_intra<<std::endl;
5102 
5103     //Dump union motion_vector[4]
5104     for(uint8_t i=0;i<4;++i)
5105     {
5106         oss<< "motion_vector["<<+i<<"].value: "<< +mbParams->motion_vector[i].value<<std::endl;
5107         oss<< "motion_vector["<<+i<<"].mv_x: "<< +mbParams->motion_vector[i].mv_x<<std::endl;
5108         oss<< "motion_vector["<<+i<<"].mv_y: "<< +mbParams->motion_vector[i].mv_y<<std::endl;
5109     }
5110 
5111     const char* fileName = m_debugInterface->CreateFileName(
5112         "_DEC",
5113         CodechalDbgBufferType::bufMbParams,
5114         CodechalDbgExtType::txt);
5115 
5116     std::ofstream ofs(fileName, std::ios::out);
5117     ofs << oss.str();
5118     ofs.close();
5119     return MOS_STATUS_SUCCESS;
5120 }
5121 
5122 #endif
5123