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