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