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