1 /*
2 * Copyright (c) 2017-2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file codechal_decode_vp8.cpp
24 //! \brief Implements the decode interface extension for VP8.
25 //! \details Implements all functions required by CodecHal for VP8 decoding.
26 //!
27
28 #include "codechal_decoder.h"
29 #include "codechal_decode_vp8.h"
30 #include "codec_def_vp8_probs.h"
31 #include "codechal_mmc_decode_vp8.h"
32 #include "hal_oca_interface.h"
33 #if USE_CODECHAL_DEBUG_TOOL
34 #include <sstream>
35 #include <fstream>
36 #include "codechal_debug.h"
37 #endif
38
DecodeFill()39 void Vp8EntropyState::DecodeFill()
40 {
41 int32_t shift = m_bdValueSize - 8 - (m_count + 8);
42 uint32_t bytesLeft = (uint32_t)(m_bufferEnd - m_buffer);
43 uint32_t bitsLeft = bytesLeft * CHAR_BIT;
44 int32_t num = (int32_t)(shift + CHAR_BIT - bitsLeft);
45 int32_t loopEnd = 0;
46
47 if (num >= 0)
48 {
49 m_count += m_lotsOfBits;
50 loopEnd = num;
51 }
52
53 if (num < 0 || bitsLeft)
54 {
55 while (shift >= loopEnd)
56 {
57 m_count += CHAR_BIT;
58 m_value |= (uint32_t)*m_buffer << shift;
59 ++m_buffer;
60 shift -= CHAR_BIT;
61 }
62 }
63 }
64
DecodeBool(int32_t probability)65 uint32_t Vp8EntropyState::DecodeBool(int32_t probability)
66 {
67 uint32_t split = 1 + (((m_range - 1) * probability) >> 8);
68 uint32_t bigSplit = (uint32_t)split << (m_bdValueSize - 8);
69 uint32_t origRange = m_range;
70 m_range = split;
71
72 uint32_t bit = 0;
73 if (m_value >= bigSplit)
74 {
75 m_range = origRange - split;
76 m_value = m_value - bigSplit;
77 bit = 1;
78 }
79
80 int32_t shift = Norm[m_range];
81 m_range <<= shift;
82 m_value <<= shift;
83 m_count -= shift;
84
85 if (m_count < 0)
86 {
87 DecodeFill();
88 }
89
90 return bit;
91 }
92
DecodeValue(int32_t bits)93 int32_t Vp8EntropyState::DecodeValue(int32_t bits)
94 {
95 int32_t retValue = 0;
96
97 for (int32_t iBit = bits - 1; iBit >= 0; iBit--)
98 {
99 retValue |= (DecodeBool(0x80) << iBit);
100 }
101
102 return retValue;
103 }
104
ParseFrameHeadInit()105 void Vp8EntropyState::ParseFrameHeadInit()
106 {
107 if (m_frameHead->iFrameType == m_keyFrame)
108 {
109 MOS_SecureMemcpy(m_frameHead->FrameContext.MvContext, sizeof(DefaultMvContext), DefaultMvContext, sizeof(DefaultMvContext));
110 MOS_SecureMemcpy(m_frameHead->FrameContext.YModeProb, sizeof(KfYModeProb), KfYModeProb, sizeof(KfYModeProb));
111 MOS_SecureMemcpy(m_frameHead->FrameContext.UVModeProb, sizeof(KfUVModeProb), KfUVModeProb, sizeof(KfUVModeProb));
112 MOS_SecureMemcpy(m_frameHead->FrameContext.CoefProbs, sizeof(DefaultCoefProbs), DefaultCoefProbs, sizeof(DefaultCoefProbs));
113
114 MOS_SecureMemcpy(m_frameHead->YModeProbs, sizeof(KfYModeProb), KfYModeProb, sizeof(KfYModeProb));
115 MOS_SecureMemcpy(m_frameHead->UVModeProbs, sizeof(KfUVModeProb), KfUVModeProb, sizeof(KfUVModeProb));
116 MOS_SecureMemcpy(m_frameHead->YModeProbs, sizeof(YModeProb), YModeProb, sizeof(YModeProb));
117 MOS_SecureMemcpy(m_frameHead->UVModeProbs, sizeof(UVModeProb), UVModeProb, sizeof(UVModeProb));
118
119 memset(m_frameHead->SegmentFeatureData, 0, sizeof(m_frameHead->SegmentFeatureData));
120 m_frameHead->u8MbSegementAbsDelta = 0;
121
122 memset(m_frameHead->RefLFDeltas, 0, sizeof(m_frameHead->RefLFDeltas));
123 memset(m_frameHead->ModeLFDeltas, 0, sizeof(m_frameHead->ModeLFDeltas));
124
125 m_frameHead->iRefreshGoldenFrame = 1;
126 m_frameHead->iRefreshAltFrame = 1;
127 m_frameHead->iCopyBufferToGolden = 0;
128 m_frameHead->iCopyBufferToAlt = 0;
129
130 m_frameHead->iLastFrameBufferCurrIdx = m_frameHead->iNewFrameBufferIdx;
131 m_frameHead->iGoldenFrameBufferCurrIdx = m_frameHead->iNewFrameBufferIdx;
132 m_frameHead->iAltFrameBufferCurrIdx = m_frameHead->iNewFrameBufferIdx;
133
134 m_frameHead->RefFrameSignBias[VP8_GOLDEN_FRAME] = 0;
135 m_frameHead->RefFrameSignBias[VP8_ALTREF_FRAME] = 0;
136 }
137 }
138
StartEntropyDecode()139 int32_t Vp8EntropyState::StartEntropyDecode()
140 {
141 m_bufferEnd = m_dataBufferEnd;
142 m_buffer = m_dataBuffer;
143 m_value = 0;
144 m_count = -8;
145 m_range = 255;
146
147 if ((m_bufferEnd - m_buffer) > 0 && m_buffer == nullptr)
148 {
149 return 1;
150 }
151
152 DecodeFill();
153
154 return 0;
155 }
156
SegmentationEnabled()157 void Vp8EntropyState::SegmentationEnabled()
158 {
159 m_frameHead->u8SegmentationEnabled = (uint8_t)DecodeBool(m_probHalf);
160
161 if (m_frameHead->u8SegmentationEnabled)
162 {
163 m_frameHead->u8UpdateMbSegmentationMap = (uint8_t)DecodeBool(m_probHalf);
164 m_frameHead->u8UpdateMbSegmentationData = (uint8_t)DecodeBool(m_probHalf);
165
166 if (m_frameHead->u8UpdateMbSegmentationData)
167 {
168 m_frameHead->u8MbSegementAbsDelta = (uint8_t)DecodeBool(m_probHalf);
169
170 memset(m_frameHead->SegmentFeatureData, 0, sizeof(m_frameHead->SegmentFeatureData));
171
172 for (int32_t i = 0; i < VP8_MB_LVL_MAX; i++)
173 {
174 for (int32_t j = 0; j < VP8_MAX_MB_SEGMENTS; j++)
175 {
176 if (DecodeBool(m_probHalf))
177 {
178 m_frameHead->SegmentFeatureData[i][j] = (int8_t)DecodeValue(MbFeatureDataBits[i]);
179
180 if (DecodeBool(m_probHalf))
181 {
182 m_frameHead->SegmentFeatureData[i][j] = -m_frameHead->SegmentFeatureData[i][j];
183 }
184 }
185 else
186 {
187 m_frameHead->SegmentFeatureData[i][j] = 0;
188 }
189 }
190 }
191 }
192
193 if (m_frameHead->u8UpdateMbSegmentationMap)
194 {
195 memset(m_frameHead->MbSegmentTreeProbs, 255, sizeof(m_frameHead->MbSegmentTreeProbs));
196
197 for (int32_t i = 0; i < VP8_MB_SEGMENT_TREE_PROBS; i++)
198 {
199 if (DecodeBool(m_probHalf))
200 {
201 m_frameHead->MbSegmentTreeProbs[i] = (uint8_t)DecodeValue(8);
202 }
203 }
204 }
205 }
206 else
207 {
208 m_frameHead->u8UpdateMbSegmentationMap = 0;
209 m_frameHead->u8UpdateMbSegmentationData = 0;
210 }
211 }
212
LoopFilterInit(int32_t defaultFilterLvl)213 void Vp8EntropyState::LoopFilterInit(int32_t defaultFilterLvl)
214 {
215 for (int32_t segmentNum = 0; segmentNum < VP8_MAX_MB_SEGMENTS; segmentNum++)
216 {
217 int32_t segmentLvl = defaultFilterLvl;
218
219 if (m_frameHead->u8SegmentationEnabled)
220 {
221 if (m_frameHead->u8MbSegementAbsDelta == 1)
222 {
223 m_frameHead->LoopFilterLevel[segmentNum] = segmentLvl = m_frameHead->SegmentFeatureData[VP8_MB_LVL_ALT_LF][segmentNum];
224 }
225 else
226 {
227 segmentLvl += m_frameHead->SegmentFeatureData[VP8_MB_LVL_ALT_LF][segmentNum];
228 m_frameHead->LoopFilterLevel[segmentNum] = segmentLvl = (segmentLvl > 0) ? ((segmentLvl > 63) ? 63 : segmentLvl) : 0;
229 }
230 }
231 }
232 }
233
LoopFilterEnabled()234 void Vp8EntropyState::LoopFilterEnabled()
235 {
236 m_frameHead->FilterType = (VP8_LF_TYPE)DecodeBool(m_probHalf);
237 m_frameHead->iFilterLevel = DecodeValue(6);
238 m_frameHead->iSharpnessLevel = DecodeValue(3);
239
240 m_frameHead->u8ModeRefLfDeltaUpdate = 0;
241 m_frameHead->u8ModeRefLfDeltaEnabled = (uint8_t)DecodeBool(m_probHalf);
242
243 if (m_frameHead->u8ModeRefLfDeltaEnabled)
244 {
245 m_frameHead->u8ModeRefLfDeltaUpdate = (uint8_t)DecodeBool(m_probHalf);
246
247 if (m_frameHead->u8ModeRefLfDeltaUpdate)
248 {
249 for (int32_t i = 0; i < VP8_MAX_REF_LF_DELTAS; i++)
250 {
251 if (DecodeBool(m_probHalf))
252 {
253 m_frameHead->RefLFDeltas[i] = (int8_t)DecodeValue(6);
254
255 if (DecodeBool(m_probHalf))
256 {
257 m_frameHead->RefLFDeltas[i] = m_frameHead->RefLFDeltas[i] * (-1);
258 }
259 }
260 }
261
262 for (int32_t i = 0; i < VP8_MAX_MODE_LF_DELTAS; i++)
263 {
264 if (DecodeBool(m_probHalf))
265 {
266 m_frameHead->ModeLFDeltas[i] = (int8_t)DecodeValue(6);
267
268 if (DecodeBool(m_probHalf))
269 {
270 m_frameHead->ModeLFDeltas[i] = m_frameHead->ModeLFDeltas[i] * (-1);
271 }
272 }
273 }
274 }
275 }
276
277 if (m_frameHead->iFilterLevel)
278 {
279 LoopFilterInit(m_frameHead->iFilterLevel);
280 }
281 }
282
GetDeltaQ(int32_t prevVal,int32_t * qupdate)283 int32_t Vp8EntropyState::GetDeltaQ(int32_t prevVal, int32_t *qupdate)
284 {
285 int32_t retVal = 0;
286
287 if (DecodeBool(m_probHalf))
288 {
289 retVal = DecodeValue(4);
290
291 if (DecodeBool(m_probHalf))
292 {
293 retVal = -retVal;
294 }
295 }
296
297 if (retVal != prevVal)
298 {
299 *qupdate = 1;
300 }
301
302 return retVal;
303 }
304
DcQuant(int32_t qindex,int32_t delta)305 int32_t Vp8EntropyState::DcQuant(int32_t qindex, int32_t delta)
306 {
307 int32_t retVal;
308
309 qindex = qindex + delta;
310
311 if (qindex > 127)
312 {
313 qindex = 127;
314 }
315 else if (qindex < 0)
316 {
317 qindex = 0;
318 }
319
320 retVal = DcQLookup[qindex];
321 return retVal;
322 }
323
Dc2Quant(int32_t qindex,int32_t delta)324 int32_t Vp8EntropyState::Dc2Quant(int32_t qindex, int32_t delta)
325 {
326 int32_t retVal;
327
328 qindex = qindex + delta;
329
330 if (qindex > 127)
331 {
332 qindex = 127;
333 }
334 else if (qindex < 0)
335 {
336 qindex = 0;
337 }
338
339 retVal = DcQLookup[qindex] * 2;
340 return retVal;
341 }
342
DcUVQuant(int32_t qindex,int32_t delta)343 int32_t Vp8EntropyState::DcUVQuant(int32_t qindex, int32_t delta)
344 {
345 int32_t retVal;
346
347 qindex = qindex + delta;
348
349 if (qindex > 127)
350 {
351 qindex = 127;
352 }
353 else if (qindex < 0)
354 {
355 qindex = 0;
356 }
357
358 retVal = DcQLookup[qindex];
359
360 if (retVal > 132)
361 {
362 retVal = 132;
363 }
364
365 return retVal;
366 }
367
AcYQuant(int32_t qindex)368 int32_t Vp8EntropyState::AcYQuant(int32_t qindex)
369 {
370 int32_t retVal;
371
372 if (qindex > 127)
373 {
374 qindex = 127;
375 }
376 else if (qindex < 0)
377 {
378 qindex = 0;
379 }
380
381 retVal = AcQLookup[qindex];
382 return retVal;
383 }
384
Ac2Quant(int32_t qindex,int32_t delta)385 int32_t Vp8EntropyState::Ac2Quant(int32_t qindex, int32_t delta)
386 {
387 int32_t retVal;
388
389 qindex = qindex + delta;
390
391 if (qindex > 127)
392 {
393 qindex = 127;
394 }
395 else if (qindex < 0)
396 {
397 qindex = 0;
398 }
399
400 retVal = (AcQLookup[qindex] * 101581) >> 16;
401
402 if (retVal < 8)
403 {
404 retVal = 8;
405 }
406
407 return retVal;
408 }
AcUVQuant(int32_t qindex,int32_t delta)409 int32_t Vp8EntropyState::AcUVQuant(int32_t qindex, int32_t delta)
410 {
411 int32_t retVal;
412
413 qindex = qindex + delta;
414
415 if (qindex > 127)
416 {
417 qindex = 127;
418 }
419 else if (qindex < 0)
420 {
421 qindex = 0;
422 }
423
424 retVal = AcQLookup[qindex];
425 return retVal;
426 }
427
QuantInit()428 void Vp8EntropyState::QuantInit()
429 {
430 for (int32_t i = 0; i < VP8_Q_INDEX_RANGE; i++)
431 {
432 m_frameHead->Y1DeQuant[i][0] = (int16_t)DcQuant(i, m_frameHead->iY1DcDeltaQ);
433 m_frameHead->Y2DeQuant[i][0] = (int16_t)Dc2Quant(i, m_frameHead->iY2DcDeltaQ);
434 m_frameHead->UVDeQuant[i][0] = (int16_t)DcUVQuant(i, m_frameHead->iUVDcDeltaQ);
435
436 m_frameHead->Y1DeQuant[i][1] = (int16_t)AcYQuant(i);
437 m_frameHead->Y2DeQuant[i][1] = (int16_t)Ac2Quant(i, m_frameHead->iY2AcDeltaQ);
438 m_frameHead->UVDeQuant[i][1] = (int16_t)AcUVQuant(i, m_frameHead->iUVAcDeltaQ);
439 }
440 }
441
QuantSetup()442 void Vp8EntropyState::QuantSetup()
443 {
444 int32_t qupdate = 0;
445
446 m_frameHead->iBaseQIndex = DecodeValue(7);
447 m_frameHead->iY1DcDeltaQ = GetDeltaQ(m_frameHead->iY1DcDeltaQ, &qupdate);
448 m_frameHead->iY2DcDeltaQ = GetDeltaQ(m_frameHead->iY2DcDeltaQ, &qupdate);
449 m_frameHead->iY2AcDeltaQ = GetDeltaQ(m_frameHead->iY2AcDeltaQ, &qupdate);
450 m_frameHead->iUVDcDeltaQ = GetDeltaQ(m_frameHead->iUVDcDeltaQ, &qupdate);
451 m_frameHead->iUVAcDeltaQ = GetDeltaQ(m_frameHead->iUVAcDeltaQ, &qupdate);
452
453 if (qupdate)
454 {
455 QuantInit();
456 }
457 }
458
ReadMvContexts(MV_CONTEXT * mvContext)459 void Vp8EntropyState::ReadMvContexts(MV_CONTEXT *mvContext)
460 {
461 int32_t i = 0;
462
463 do
464 {
465 const uint8_t *upProb = MvUpdateProbs[i].MvProb;
466 uint8_t *prob = (uint8_t *)(mvContext + i);
467 uint8_t *const stopProb = prob + 19;
468
469 do
470 {
471 if (DecodeBool(*upProb++))
472 {
473 const uint8_t x = (uint8_t)DecodeValue(7);
474
475 *prob = x ? x << 1 : 1;
476 }
477 } while (++prob < stopProb);
478
479 } while (++i < 2);
480 }
481
ParseFrameHead(PCODEC_VP8_PIC_PARAMS vp8PicParams)482 MOS_STATUS Vp8EntropyState::ParseFrameHead(PCODEC_VP8_PIC_PARAMS vp8PicParams)
483 {
484 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
485
486 CODECHAL_DECODE_FUNCTION_ENTER;
487
488 ParseFrameHeadInit();
489
490 StartEntropyDecode();
491
492 if (m_frameHead->iFrameType == m_keyFrame)
493 {
494 DecodeBool(m_probHalf); // Color Space
495 DecodeBool(m_probHalf); // Clamp Type
496 }
497
498 SegmentationEnabled();
499
500 LoopFilterEnabled();
501
502 m_frameHead->MultiTokenPartition = (VP8_TOKEN_PARTITION)DecodeValue(2);
503
504 if (!m_frameHead->bNotFirstCall)
505 {
506 QuantInit();
507 }
508
509 QuantSetup();
510
511 if (m_frameHead->iFrameType != m_keyFrame)
512 {
513 m_frameHead->iRefreshGoldenFrame = DecodeBool(m_probHalf);
514
515 m_frameHead->iRefreshAltFrame = DecodeBool(m_probHalf);
516
517 m_frameHead->iCopyBufferToGolden = 0;
518
519 if (!m_frameHead->iRefreshGoldenFrame)
520 {
521 m_frameHead->iCopyBufferToGolden = DecodeValue(2);
522 }
523
524 m_frameHead->iCopyBufferToAlt = 0;
525
526 if (!m_frameHead->iRefreshAltFrame)
527 {
528 m_frameHead->iCopyBufferToAlt = DecodeValue(2);
529 }
530
531 m_frameHead->RefFrameSignBias[VP8_GOLDEN_FRAME] = DecodeBool(m_probHalf);
532 m_frameHead->RefFrameSignBias[VP8_ALTREF_FRAME] = DecodeBool(m_probHalf);
533 }
534
535 if (m_frameHead->bNotFirstCall && m_frameHead->iRefreshEntropyProbs == 0)
536 {
537 MOS_SecureMemcpy(&m_frameHead->FrameContext, sizeof(m_frameHead->FrameContext), &m_frameHead->LastFrameContext, sizeof(m_frameHead->LastFrameContext));
538 }
539
540 m_frameHead->iRefreshEntropyProbs = DecodeBool(m_probHalf);
541
542 if (m_frameHead->iRefreshEntropyProbs == 0)
543 {
544 MOS_SecureMemcpy(&m_frameHead->LastFrameContext, sizeof(m_frameHead->LastFrameContext), &m_frameHead->FrameContext, sizeof(m_frameHead->FrameContext));
545 }
546
547 if (m_frameHead->iFrameType == m_keyFrame || DecodeBool(m_probHalf))
548 {
549 m_frameHead->iRefreshLastFrame = true;
550 }
551 else
552 {
553 m_frameHead->iRefreshLastFrame = false;
554 }
555
556 for (int32_t i = 0; i < VP8_BLOCK_TYPES; i++)
557 for (int32_t j = 0; j < VP8_COEF_BANDS; j++)
558 for (int32_t k = 0; k < VP8_PREV_COEF_CONTEXTS; k++)
559 for (int32_t l = 0; l < VP8_ENTROPY_NODES; l++)
560 {
561 uint8_t *const p = m_frameHead->FrameContext.CoefProbs[i][j][k] + l;
562
563 if (DecodeBool(CoefUpdateProbs[i][j][k][l]))
564 {
565 *p = (uint8_t)DecodeValue(8);
566 }
567 }
568
569 m_frameHead->iMbNoCoeffSkip = (int32_t)DecodeBool(m_probHalf);
570 m_frameHead->iProbSkipFalse = 0;
571 if (m_frameHead->iMbNoCoeffSkip)
572 {
573 m_frameHead->iProbSkipFalse = (uint8_t)DecodeValue(8);
574 }
575
576 if (m_frameHead->iFrameType != m_keyFrame)
577 {
578 m_frameHead->ProbIntra = (uint8_t)DecodeValue(8);
579 m_frameHead->ProbLast = (uint8_t)DecodeValue(8);
580 m_frameHead->ProbGf = (uint8_t)DecodeValue(8);
581
582 if (DecodeBool(m_probHalf))
583 {
584 int32_t i = 0;
585
586 do
587 {
588 m_frameHead->YModeProbs[i] = m_frameHead->FrameContext.YModeProb[i] =
589 (uint8_t)DecodeValue(8);
590 } while (++i < 4);
591 }
592
593 if (DecodeBool(m_probHalf))
594 {
595 int32_t i = 0;
596
597 do
598 {
599 m_frameHead->UVModeProbs[i] = m_frameHead->FrameContext.UVModeProb[i] =
600 (uint8_t)DecodeValue(8);
601 } while (++i < 3);
602 }
603
604 MV_CONTEXT MVContext[2];
605 for (int32_t i = 0; i < 2; i++)
606 {
607 for (int32_t j = 0; j < 19; j++)
608 {
609 MVContext[i].MvProb[j] = vp8PicParams->ucMvUpdateProb[i][j];
610 }
611 }
612
613 ReadMvContexts(MVContext);
614 }
615
616 vp8PicParams->ucP0EntropyCount = 8 - (m_count & 0x07);
617 vp8PicParams->ucP0EntropyValue = (uint8_t)(m_value >> 24);
618 vp8PicParams->uiP0EntropyRange = m_range;
619
620 uint32_t firstPartitionAndUncompSize;
621 if (m_frameHead->iFrameType == m_keyFrame)
622 {
623 firstPartitionAndUncompSize = vp8PicParams->uiFirstPartitionSize + 10;
624 }
625 else
626 {
627 firstPartitionAndUncompSize = vp8PicParams->uiFirstPartitionSize + 3;
628 }
629
630 // Partition Size
631 uint32_t partitionNum = 1 << m_frameHead->MultiTokenPartition;
632 uint32_t partitionSizeSum = 0;
633 m_dataBuffer = m_bitstreamBuffer + firstPartitionAndUncompSize;
634 if (partitionNum > 1)
635 {
636 for (int32_t i = 1; i < (int32_t)partitionNum; i++)
637 {
638 vp8PicParams->uiPartitionSize[i] = m_dataBuffer[0] + (m_dataBuffer[1] << 8) + (m_dataBuffer[2] << 16);
639 m_dataBuffer += 3;
640 partitionSizeSum += vp8PicParams->uiPartitionSize[i];
641 }
642 }
643
644 uint32_t offsetCounter = ((m_count & 0x18) >> 3) + (((m_count & 0x07) != 0) ? 1 : 0);
645 vp8PicParams->uiFirstMbByteOffset = (uint32_t)(m_buffer - m_bitstreamBuffer) - offsetCounter;
646 vp8PicParams->uiPartitionSize[0] = firstPartitionAndUncompSize - (uint32_t)(m_buffer - m_bitstreamBuffer) + offsetCounter;
647 vp8PicParams->uiPartitionSize[partitionNum] = m_bitstreamBufferSize - firstPartitionAndUncompSize - (partitionNum - 1) * 3 - partitionSizeSum;
648
649 return eStatus;
650 }
651
FrameHeadQuantUpdate(PCODEC_VP8_PIC_PARAMS vp8PicParams)652 void Vp8EntropyState::FrameHeadQuantUpdate(
653 PCODEC_VP8_PIC_PARAMS vp8PicParams)
654 {
655 for (int32_t i = 0; i < VP8_Q_INDEX_RANGE; i++)
656 {
657 m_frameHead->Y1DeQuant[i][0] = (int16_t)DcQuant(i, vp8PicParams->cY1DcDeltaQ);
658 m_frameHead->Y2DeQuant[i][0] = (int16_t)Dc2Quant(i, vp8PicParams->cY2DcDeltaQ);
659 m_frameHead->UVDeQuant[i][0] = (int16_t)DcUVQuant(i, vp8PicParams->cUVDcDeltaQ);
660
661 m_frameHead->Y1DeQuant[i][1] = (int16_t)AcYQuant(i);
662 m_frameHead->Y2DeQuant[i][1] = (int16_t)Ac2Quant(i, vp8PicParams->cY2AcDeltaQ);
663 m_frameHead->UVDeQuant[i][1] = (int16_t)AcUVQuant(i, vp8PicParams->cUVAcDeltaQ);
664 }
665 }
666
Initialize(PCODECHAL_DECODE_VP8_FRAME_HEAD vp8FrameHeadIn,uint8_t * bitstreamBufferIn,uint32_t bitstreamBufferSizeIn)667 void Vp8EntropyState::Initialize(
668 PCODECHAL_DECODE_VP8_FRAME_HEAD vp8FrameHeadIn,
669 uint8_t* bitstreamBufferIn,
670 uint32_t bitstreamBufferSizeIn)
671 {
672 m_frameHead = vp8FrameHeadIn;
673 m_dataBuffer = bitstreamBufferIn;
674 m_dataBufferEnd = bitstreamBufferIn + bitstreamBufferSizeIn;
675 m_bitstreamBuffer = bitstreamBufferIn;
676 m_bitstreamBufferSize = bitstreamBufferSizeIn;
677
678 m_frameHead->iFrameType = m_dataBuffer[0] & 1;
679 m_frameHead->iVersion = (m_dataBuffer[0] >> 1) & 7;
680 m_frameHead->iShowframe = (m_dataBuffer[0] >> 4) & 1;
681 m_frameHead->uiFirstPartitionLengthInBytes = (m_dataBuffer[0] | (m_dataBuffer[1] << 8) | (m_dataBuffer[2] << 16)) >> 5;
682
683 m_dataBuffer += 3;
684
685 if (m_frameHead->iFrameType == m_keyFrame)
686 {
687 m_dataBuffer += 7;
688 }
689 }
690
ParseFrameHead(uint8_t * bitstreamBuffer,uint32_t bitstreamBufferSize)691 MOS_STATUS CodechalDecodeVp8::ParseFrameHead(uint8_t* bitstreamBuffer, uint32_t bitstreamBufferSize)
692 {
693 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
694
695 CODECHAL_DECODE_FUNCTION_ENTER;
696
697 CODECHAL_DECODE_CHK_NULL_RETURN(bitstreamBuffer);
698
699 m_vp8EntropyState.Initialize(&m_vp8FrameHead, bitstreamBuffer, bitstreamBufferSize);
700
701 eStatus = m_vp8EntropyState.ParseFrameHead(m_vp8PicParams);
702
703 if (eStatus != MOS_STATUS_SUCCESS)
704 {
705 CODECHAL_DECODE_ASSERTMESSAGE("Fail to parse VP8 Frame Head");
706 return eStatus;
707 }
708
709 //------------------------------------------------------Temporary Separator
710
711 // Loop Filter
712 for (int32_t i = 0; i < VP8_MAX_MB_SEGMENTS; i++)
713 {
714 int32_t segmentLvl = m_vp8PicParams->ucFilterLevel;
715
716 if (m_vp8PicParams->segmentation_enabled)
717 {
718 if (m_vp8PicParams->mb_segement_abs_delta == 1)
719 {
720 m_vp8PicParams->ucLoopFilterLevel[i] = segmentLvl = m_vp8PicParams->cSegmentFeatureData[VP8_MB_LVL_ALT_LF][i];
721 }
722 else
723 {
724 segmentLvl += m_vp8PicParams->cSegmentFeatureData[VP8_MB_LVL_ALT_LF][i];
725 m_vp8PicParams->ucLoopFilterLevel[i] = segmentLvl = (segmentLvl > 0) ? ((segmentLvl > 63) ? 63 : segmentLvl) : 0;
726 }
727 }
728 else
729 {
730 m_vp8PicParams->ucLoopFilterLevel[i] = m_vp8PicParams->ucFilterLevel;
731 }
732 }
733
734 // Quant Matrix
735 int32_t vp8QIndex[VP8_MAX_MB_SEGMENTS];
736 if (m_vp8PicParams->segmentation_enabled)
737 {
738 for (int32_t i = 0; i < 4; i++)
739 {
740 if (m_vp8PicParams->mb_segement_abs_delta == 1)
741 {
742 vp8QIndex[i] = (int32_t)m_vp8PicParams->cSegmentFeatureData[VP8_MB_LVL_ALT_Q][i];
743 }
744 else
745 {
746 vp8QIndex[i] = (int32_t)m_vp8PicParams->ucBaseQIndex + (int32_t)m_vp8PicParams->cSegmentFeatureData[VP8_MB_LVL_ALT_Q][i];
747 vp8QIndex[i] = (vp8QIndex[i] >= 0) ? ((vp8QIndex[i] <= VP8_MAX_Q) ? vp8QIndex[i] : VP8_MAX_Q) : 0; // Clamp to valid range
748 }
749 }
750 }
751 else
752 {
753 vp8QIndex[0] = (int32_t)m_vp8PicParams->ucBaseQIndex;
754 vp8QIndex[1] = 0;
755 vp8QIndex[2] = 0;
756 vp8QIndex[3] = 0;
757 }
758
759 m_vp8EntropyState.FrameHeadQuantUpdate(m_vp8PicParams);
760
761 m_vp8IqMatrixParams->quantization_values[0][0] = m_vp8FrameHead.Y1DeQuant[vp8QIndex[0]][0];
762 m_vp8IqMatrixParams->quantization_values[0][1] = m_vp8FrameHead.Y1DeQuant[vp8QIndex[0]][1];
763 m_vp8IqMatrixParams->quantization_values[0][2] = m_vp8FrameHead.UVDeQuant[vp8QIndex[0]][0];
764 m_vp8IqMatrixParams->quantization_values[0][3] = m_vp8FrameHead.UVDeQuant[vp8QIndex[0]][1];
765 m_vp8IqMatrixParams->quantization_values[0][4] = m_vp8FrameHead.Y2DeQuant[vp8QIndex[0]][0];
766 m_vp8IqMatrixParams->quantization_values[0][5] = m_vp8FrameHead.Y2DeQuant[vp8QIndex[0]][1];
767
768 if (m_vp8FrameHead.u8SegmentationEnabled)
769 {
770 for (int32_t i = 1; i < 4; i++)
771 {
772 m_vp8IqMatrixParams->quantization_values[i][0] = m_vp8FrameHead.Y1DeQuant[vp8QIndex[i]][0];
773 m_vp8IqMatrixParams->quantization_values[i][1] = m_vp8FrameHead.Y1DeQuant[vp8QIndex[i]][1];
774 m_vp8IqMatrixParams->quantization_values[i][2] = m_vp8FrameHead.UVDeQuant[vp8QIndex[i]][0];
775 m_vp8IqMatrixParams->quantization_values[i][3] = m_vp8FrameHead.UVDeQuant[vp8QIndex[i]][1];
776 m_vp8IqMatrixParams->quantization_values[i][4] = m_vp8FrameHead.Y2DeQuant[vp8QIndex[i]][0];
777 m_vp8IqMatrixParams->quantization_values[i][5] = m_vp8FrameHead.Y2DeQuant[vp8QIndex[i]][1];
778 }
779 }
780 else
781 {
782 for (int32_t i = 1; i < 4; i++)
783 {
784 for (int32_t j = 0; j < 6; j++)
785 {
786 m_vp8IqMatrixParams->quantization_values[i][j] = 0;
787 }
788 }
789 }
790
791 // Coef Prob
792 if (!Mos_ResourceIsNull(&m_resCoefProbBuffer))
793 {
794 m_osInterface->pfnFreeResource(
795 m_osInterface,
796 &m_resCoefProbBuffer);
797 }
798
799 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
800 &m_resCoefProbBuffer,
801 sizeof(m_vp8FrameHead.FrameContext.CoefProbs),
802 "VP8_Coef_Prob"),
803 "Failed to allocate VP8 CoefProb Buffer.");
804
805 CodechalResLock ResourceLock(m_osInterface, &m_resCoefProbBuffer);
806 auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
807
808 CODECHAL_DECODE_CHK_NULL_RETURN(data);
809
810 MOS_SecureMemcpy(
811 data,
812 sizeof(m_vp8FrameHead.FrameContext.CoefProbs),
813 (void *)&(m_vp8FrameHead.FrameContext.CoefProbs),
814 sizeof(m_vp8FrameHead.FrameContext.CoefProbs));
815
816 m_vp8FrameHead.bNotFirstCall = true;
817
818 return eStatus;
819 }
820
CopyBitstreamBuffer(MOS_RESOURCE srcBitstreamBuffer,PMOS_RESOURCE dstBitstreamBuffer,uint32_t size)821 MOS_STATUS CodechalDecodeVp8::CopyBitstreamBuffer(
822 MOS_RESOURCE srcBitstreamBuffer,
823 PMOS_RESOURCE dstBitstreamBuffer,
824 uint32_t size)
825 {
826 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
827
828 CODECHAL_DECODE_FUNCTION_ENTER;
829
830 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
831 m_osInterface,
832 m_videoContextForWa));
833 m_osInterface->pfnResetOsStates(m_osInterface);
834
835 m_osInterface->pfnSetPerfTag(
836 m_osInterface,
837 (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE));
838 m_osInterface->pfnResetPerfBufferID(m_osInterface);
839
840 MOS_COMMAND_BUFFER cmdBuffer;
841 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
842
843 // Send command buffer header at the beginning (OS dependent)
844 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
845
846 CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
847 &cmdBuffer, // pCmdBuffer
848 &srcBitstreamBuffer, // presSrc
849 dstBitstreamBuffer, // presDst
850 MOS_ALIGN_CEIL(size, 16), // u32CopyLength
851 0, // u32CopyInputOffset
852 0)); // u32CopyOutputOffset
853
854 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
855 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
856 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
857 &cmdBuffer,
858 &flushDwParams));
859
860 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
861 &cmdBuffer,
862 nullptr));
863
864 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
865
866 m_huCCopyInUse = true;
867
868 MOS_SYNC_PARAMS syncParams;
869
870 syncParams = g_cInitSyncParams;
871 syncParams.GpuContext = m_videoContext;
872 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
873
874 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
875
876 syncParams = g_cInitSyncParams;
877 syncParams.GpuContext = m_videoContextForWa;
878 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
879
880 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
881
882 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
883 m_osInterface,
884 &cmdBuffer,
885 m_videoContextUsesNullHw));
886
887 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext));
888
889 return eStatus;
890 }
891
AllocateResourcesFixedSizes()892 MOS_STATUS CodechalDecodeVp8::AllocateResourcesFixedSizes()
893 {
894 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
895
896 CODECHAL_DECODE_FUNCTION_ENTER;
897
898 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(m_osInterface, &m_resSyncObject));
899
900 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalAllocateDataList(
901 m_vp8RefList,
902 CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP8));
903
904 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
905 m_osInterface,
906 &m_resSyncObjectWaContextInUse));
907
908 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
909 m_osInterface,
910 &m_resSyncObjectVideoContextInUse));
911
912 return eStatus;
913 }
914
AllocateResourcesVariableSizes()915 MOS_STATUS CodechalDecodeVp8::AllocateResourcesVariableSizes()
916 {
917 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
918
919 CODECHAL_DECODE_FUNCTION_ENTER;
920
921 if (m_decodeParams.m_bitstreamLockingInUse && (!m_decodeParams.m_bitstreamLockable))
922 {
923 if (!Mos_ResourceIsNull(&m_resTmpBitstreamBuffer))
924 {
925 m_osInterface->pfnFreeResource(
926 m_osInterface,
927 &m_resTmpBitstreamBuffer);
928 }
929
930 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
931 &m_resTmpBitstreamBuffer,
932 m_dataSize,
933 "VP8_BitStream"),
934 "Failed to allocate Bitstream Buffer.");
935 }
936
937 uint16_t picWidthInMB = MOS_MAX(m_picWidthInMbLastMaxAlloced, (m_vp8PicParams->wFrameWidthInMbsMinus1 + 1));
938 uint16_t picHeightInMB = MOS_MAX(m_picHeightInMbLastMaxAlloced, (m_vp8PicParams->wFrameHeightInMbsMinus1 + 1));
939 uint32_t maxWidth = picWidthInMB * CODECHAL_MACROBLOCK_WIDTH;
940 uint32_t maxHeight = picHeightInMB * CODECHAL_MACROBLOCK_HEIGHT;
941 uint32_t numMacroblocks = picWidthInMB * picHeightInMB;
942
943 if (m_mfxInterface->IsDeblockingFilterRowstoreCacheEnabled() == false)
944 {
945 uint16_t maxMfdDFRowStoreScratchBufferPicWidthInMB;
946 maxMfdDFRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_mfdDeblockingFilterRowStoreScratchBufferPicWidthInMb,
947 (m_vp8PicParams->wFrameWidthInMbsMinus1 + 1));
948
949 if ((maxMfdDFRowStoreScratchBufferPicWidthInMB > m_mfdDeblockingFilterRowStoreScratchBufferPicWidthInMb) ||
950 Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer))
951 {
952 if (!Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer))
953 {
954 m_osInterface->pfnFreeResource(
955 m_osInterface,
956 &m_resMfdDeblockingFilterRowStoreScratchBuffer);
957 }
958 // Deblocking Filter Row Store Scratch buffer
959 //(Num MacroBlock Width) * (Num Cachlines) * (Cachline size)
960 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
961 &m_resMfdDeblockingFilterRowStoreScratchBuffer,
962 maxMfdDFRowStoreScratchBufferPicWidthInMB * 2 * CODECHAL_CACHELINE_SIZE,
963 "DeblockingScratchBuffer"),
964 "Failed to allocate Deblocking Filter Row Store Scratch Buffer.");
965 }
966
967 //record the width and height used for allocation internal resources.
968 m_mfdDeblockingFilterRowStoreScratchBufferPicWidthInMb = maxMfdDFRowStoreScratchBufferPicWidthInMB;
969 }
970
971 if (m_mfxInterface->IsIntraRowstoreCacheEnabled() == false)
972 {
973 uint16_t maxMfdIntraRowStoreScratchBufferPicWidthInMB;
974 maxMfdIntraRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_mfdIntraRowStoreScratchBufferPicWidthInMb, (m_vp8PicParams->wFrameWidthInMbsMinus1 + 1));
975
976 if ((maxMfdIntraRowStoreScratchBufferPicWidthInMB > m_mfdIntraRowStoreScratchBufferPicWidthInMb) ||
977 Mos_ResourceIsNull(&m_resMfdIntraRowStoreScratchBuffer))
978 {
979 if (!Mos_ResourceIsNull(&m_resMfdIntraRowStoreScratchBuffer))
980 {
981 m_osInterface->pfnFreeResource(
982 m_osInterface,
983 &m_resMfdIntraRowStoreScratchBuffer);
984 }
985
986 // Intra Row Store Scratch buffer
987 // (FrameWidth in MB) * (CacheLine size per MB)
988 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
989 &m_resMfdIntraRowStoreScratchBuffer,
990 maxMfdIntraRowStoreScratchBufferPicWidthInMB * CODECHAL_CACHELINE_SIZE,
991 "IntraScratchBuffer"),
992 "Failed to allocate VP8 BSD Intra Row Store Scratch Buffer.");
993 }
994
995 //record the width and height used for allocation internal resources.
996 m_mfdIntraRowStoreScratchBufferPicWidthInMb = maxMfdIntraRowStoreScratchBufferPicWidthInMB;
997 }
998
999 if (m_mfxInterface->IsBsdMpcRowstoreCacheEnabled() == false)
1000 {
1001 uint16_t maxBsdMpcRowStoreScratchBufferPicWidthInMB;
1002 maxBsdMpcRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_bsdMpcRowStoreScratchBufferPicWidthInMb, (m_vp8PicParams->wFrameWidthInMbsMinus1 + 1));
1003
1004 if ((maxBsdMpcRowStoreScratchBufferPicWidthInMB > m_bsdMpcRowStoreScratchBufferPicWidthInMb) ||
1005 Mos_ResourceIsNull(&m_resBsdMpcRowStoreScratchBuffer))
1006 {
1007 if (!Mos_ResourceIsNull(&m_resBsdMpcRowStoreScratchBuffer))
1008 {
1009 m_osInterface->pfnFreeResource(
1010 m_osInterface,
1011 &m_resBsdMpcRowStoreScratchBuffer);
1012 }
1013 // BSD/MPC Row Store Scratch buffer
1014 // (FrameWidth in MB) * (2) * (CacheLine size per MB)
1015 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
1016 &m_resBsdMpcRowStoreScratchBuffer,
1017 maxBsdMpcRowStoreScratchBufferPicWidthInMB * CODECHAL_CACHELINE_SIZE * 2,
1018 "MpcScratchBuffer"),
1019 "Failed to allocate BSD/MPC Row Store Scratch Buffer.");
1020 }
1021
1022 //record the width and height used for allocation internal resources.
1023 m_bsdMpcRowStoreScratchBufferPicWidthInMb = maxBsdMpcRowStoreScratchBufferPicWidthInMB;
1024 }
1025
1026 if ((picWidthInMB > m_picWidthInMbLastMaxAlloced) ||
1027 Mos_ResourceIsNull(&m_resMprRowStoreScratchBuffer))
1028 {
1029 if (!Mos_ResourceIsNull(&m_resMprRowStoreScratchBuffer))
1030 {
1031 m_osInterface->pfnFreeResource(
1032 m_osInterface,
1033 &m_resMprRowStoreScratchBuffer);
1034 }
1035 // MPR Row Store Scratch buffer
1036 // (FrameWidth in MB) * (2) * (CacheLine size per MB)
1037 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
1038 &m_resMprRowStoreScratchBuffer,
1039 picWidthInMB * CODECHAL_CACHELINE_SIZE * 22,
1040 "MprScratchBuffer"),
1041 "Failed to allocate MPR Row Store Scratch Buffer.");
1042 }
1043
1044 if ((numMacroblocks > (uint32_t)m_picWidthInMbLastMaxAlloced * m_picHeightInMbLastMaxAlloced) ||
1045 Mos_ResourceIsNull(&m_resSegmentationIdStreamBuffer))
1046 {
1047 if (!Mos_ResourceIsNull(&m_resSegmentationIdStreamBuffer))
1048 {
1049 m_osInterface->pfnFreeResource(
1050 m_osInterface,
1051 &m_resSegmentationIdStreamBuffer);
1052 }
1053 // Segmentation ID Stream buffer
1054 //(Num MacroBlocks) * (Cachline size) * (2 bit)
1055 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
1056 &m_resSegmentationIdStreamBuffer,
1057 MOS_MAX(numMacroblocks * CODECHAL_CACHELINE_SIZE * 2 / 8, 64),
1058 "SegmentationIdStreamBuffer"),
1059 "Failed to allocate Segmentation ID Stream Buffer.");
1060 }
1061
1062 m_picWidthInMbLastMaxAlloced = picWidthInMB;
1063 m_picHeightInMbLastMaxAlloced = picHeightInMB;
1064
1065 return eStatus;
1066 }
1067
~CodechalDecodeVp8()1068 CodechalDecodeVp8::~CodechalDecodeVp8()
1069 {
1070 CODECHAL_DECODE_FUNCTION_ENTER;
1071
1072 m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObject);
1073
1074 CodecHalFreeDataList(m_vp8RefList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP8);
1075
1076 // indicate resCoefProbBuffer is allocated internal, not from m_decodeParams.m_coefProbBuffer
1077 if (m_vp8FrameHead.bNotFirstCall == true)
1078 {
1079 m_osInterface->pfnFreeResource(
1080 m_osInterface,
1081 &m_resCoefProbBuffer);
1082 }
1083
1084 m_osInterface->pfnFreeResource(
1085 m_osInterface,
1086 &m_resTmpBitstreamBuffer);
1087
1088 m_osInterface->pfnFreeResource(
1089 m_osInterface,
1090 &m_resMfdDeblockingFilterRowStoreScratchBuffer);
1091
1092 m_osInterface->pfnFreeResource(
1093 m_osInterface,
1094 &m_resMfdIntraRowStoreScratchBuffer);
1095
1096 m_osInterface->pfnFreeResource(
1097 m_osInterface,
1098 &m_resBsdMpcRowStoreScratchBuffer);
1099
1100 m_osInterface->pfnFreeResource(
1101 m_osInterface,
1102 &m_resMprRowStoreScratchBuffer);
1103
1104 m_osInterface->pfnFreeResource(
1105 m_osInterface,
1106 &m_resSegmentationIdStreamBuffer);
1107
1108 m_osInterface->pfnDestroySyncResource(
1109 m_osInterface,
1110 &m_resSyncObjectWaContextInUse);
1111
1112 m_osInterface->pfnDestroySyncResource(
1113 m_osInterface,
1114 &m_resSyncObjectVideoContextInUse);
1115
1116 return;
1117 }
1118
SetFrameStates()1119 MOS_STATUS CodechalDecodeVp8::SetFrameStates()
1120 {
1121 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1122
1123 CODECHAL_DECODE_FUNCTION_ENTER;
1124
1125 CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface);
1126 CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer);
1127
1128 m_dataSize = m_decodeParams.m_dataSize;
1129 m_dataOffset = m_decodeParams.m_dataOffset;
1130 m_destSurface = *(m_decodeParams.m_destSurface);
1131 m_presLastRefSurface = m_decodeParams.m_presNoneRegLastRefFrame;
1132 m_presAltRefSurface = m_decodeParams.m_presNoneRegAltRefFrame;
1133 m_presGoldenRefSurface = m_decodeParams.m_presNoneRegGoldenRefFrame;
1134
1135 m_resDataBuffer = *(m_decodeParams.m_dataBuffer);
1136 m_vp8PicParams = (PCODEC_VP8_PIC_PARAMS)m_decodeParams.m_picParams;
1137 m_vp8IqMatrixParams = (PCODEC_VP8_IQ_MATRIX_PARAMS)m_decodeParams.m_iqMatrixBuffer;
1138
1139 CODECHAL_DECODE_CHK_NULL_RETURN(m_vp8PicParams);
1140
1141 PCODEC_REF_LIST destEntry = m_vp8RefList[m_vp8PicParams->CurrPic.FrameIdx];
1142 CODEC_PICTURE currPic = m_vp8PicParams->CurrPic;
1143
1144 MOS_ZeroMemory(destEntry, sizeof(CODEC_REF_LIST));
1145 destEntry->RefPic = currPic;
1146 destEntry->resRefPic = m_destSurface.OsResource;
1147
1148 m_statusReportFeedbackNumber = m_vp8PicParams->uiStatusReportFeedbackNumber;
1149
1150 m_deblockingEnabled = !m_vp8PicParams->LoopFilterDisable ? true : false;
1151
1152 if (m_mfxInterface->IsRowStoreCachingSupported())
1153 {
1154 MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
1155 MOS_ZeroMemory(&rowstoreParams, sizeof(rowstoreParams));
1156 rowstoreParams.dwPicWidth = m_width;
1157 rowstoreParams.bMbaff = false;
1158 rowstoreParams.Mode = CODECHAL_DECODE_MODE_VP8VLD;
1159 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams));
1160 }
1161
1162 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesVariableSizes());
1163
1164 if (m_decodeParams.m_bitstreamLockingInUse)
1165 {
1166 if (m_decodeParams.m_bitstreamLockable)
1167 {
1168 CodechalResLock ResourceLock(m_osInterface, &m_resDataBuffer);
1169 auto bitstreamBuffer = (uint8_t*)ResourceLock.Lock(CodechalResLock::readOnly);
1170 CODECHAL_DECODE_CHK_NULL_RETURN(bitstreamBuffer);
1171
1172 CODECHAL_DECODE_CHK_STATUS_RETURN(ParseFrameHead(bitstreamBuffer + m_dataOffset, m_dataSize));
1173 }
1174 else
1175 {
1176 CODECHAL_DECODE_CHK_STATUS_RETURN(CopyBitstreamBuffer(m_resDataBuffer, &m_resTmpBitstreamBuffer, m_dataSize));
1177
1178 CodechalResLock ResourceLock(m_osInterface, &m_resTmpBitstreamBuffer);
1179 auto bitstreamBuffer = (uint8_t*)ResourceLock.Lock(CodechalResLock::readOnly);
1180 CODECHAL_DECODE_CHK_NULL_RETURN(bitstreamBuffer);
1181
1182 CODECHAL_DECODE_CHK_STATUS_RETURN(ParseFrameHead(bitstreamBuffer, m_dataSize));
1183 }
1184
1185 m_decodeParams.m_coefProbSize = sizeof(m_vp8FrameHead.FrameContext.CoefProbs);
1186 }
1187 else
1188 {
1189 m_resCoefProbBuffer = *(m_decodeParams.m_coefProbBuffer);
1190 }
1191
1192 m_width = (m_vp8PicParams->wFrameWidthInMbsMinus1 + 1) * CODECHAL_MACROBLOCK_WIDTH;
1193 m_height = (m_vp8PicParams->wFrameHeightInMbsMinus1 + 1) * CODECHAL_MACROBLOCK_HEIGHT;
1194
1195 // Overwrite the actual surface height with the coded height and width of the frame
1196 // for VP8 since it's possible for a VP8 frame to change size during playback
1197 m_destSurface.dwWidth = m_width;
1198 m_destSurface.dwHeight = m_height;
1199
1200 m_perfType = m_vp8PicParams->key_frame ? I_TYPE : P_TYPE;
1201
1202 m_crrPic = m_vp8PicParams->CurrPic;
1203
1204 CODECHAL_DEBUG_TOOL(
1205 CODECHAL_DECODE_CHK_NULL_RETURN(m_debugInterface);
1206 m_vp8PicParams->CurrPic.PicFlags = PICTURE_FRAME;
1207 m_debugInterface->m_currPic = m_crrPic;
1208 m_debugInterface->m_frameType = m_perfType;
1209
1210 if (m_vp8PicParams) {
1211 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpPicParams(
1212 m_vp8PicParams));
1213 }
1214
1215 if (m_vp8IqMatrixParams) {
1216 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpIQParams(
1217 m_vp8IqMatrixParams));
1218 }
1219
1220 // Dump Vp8CoefProb
1221 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1222 &(m_resCoefProbBuffer),
1223 CodechalDbgAttr::attrCoeffProb,
1224 "_DEC",
1225 m_decodeParams.m_coefProbSize));)
1226
1227 return eStatus;
1228 }
1229
DecodeStateLevel()1230 MOS_STATUS CodechalDecodeVp8::DecodeStateLevel()
1231 {
1232 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1233
1234 CODECHAL_DECODE_FUNCTION_ENTER;
1235
1236 if (m_vp8PicParams->key_frame) // reference surface should be nullptr when key_frame == true
1237 {
1238 m_presLastRefSurface = nullptr;
1239 m_presGoldenRefSurface = nullptr;
1240 m_presAltRefSurface = nullptr;
1241 }
1242 else
1243 {
1244 if((Mos_ResourceIsNull(&m_vp8RefList[m_vp8PicParams->ucLastRefPicIndex]->resRefPic)) && (m_presLastRefSurface))
1245 {
1246 m_vp8RefList[m_vp8PicParams->ucLastRefPicIndex]->resRefPic = *m_presLastRefSurface;
1247 }
1248 else
1249 {
1250 m_presLastRefSurface = &(m_vp8RefList[m_vp8PicParams->ucLastRefPicIndex]->resRefPic);
1251 }
1252 if((Mos_ResourceIsNull(&m_vp8RefList[m_vp8PicParams->ucGoldenRefPicIndex]->resRefPic)) && (m_presGoldenRefSurface))
1253 {
1254 m_vp8RefList[m_vp8PicParams->ucGoldenRefPicIndex]->resRefPic = *m_presGoldenRefSurface;
1255 }
1256 else
1257 {
1258 m_presGoldenRefSurface = &(m_vp8RefList[m_vp8PicParams->ucGoldenRefPicIndex]->resRefPic);
1259 }
1260 if((Mos_ResourceIsNull(&m_vp8RefList[m_vp8PicParams->ucAltRefPicIndex]->resRefPic)) && (m_presAltRefSurface))
1261 {
1262 m_vp8RefList[m_vp8PicParams->ucAltRefPicIndex]->resRefPic = *m_presAltRefSurface;
1263 }
1264 else
1265 {
1266 m_presAltRefSurface = &(m_vp8RefList[m_vp8PicParams->ucAltRefPicIndex]->resRefPic);
1267 }
1268 }
1269
1270 MOS_COMMAND_BUFFER cmdBuffer;
1271 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1272
1273 auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
1274 HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
1275
1276 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
1277 pipeModeSelectParams.Mode = m_mode;
1278 pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled;
1279 pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
1280 pipeModeSelectParams.bPreDeblockOutEnable = !m_deblockingEnabled;
1281 pipeModeSelectParams.bShortFormatInUse = m_shortFormatInUse;
1282
1283 MHW_VDBOX_SURFACE_PARAMS surfaceParams;
1284 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
1285 surfaceParams.Mode = m_mode;
1286 surfaceParams.psSurface = &m_destSurface;
1287
1288 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
1289 pipeBufAddrParams.Mode = m_mode;
1290
1291 if (m_deblockingEnabled)
1292 {
1293 pipeBufAddrParams.psPostDeblockSurface = &m_destSurface;
1294 }
1295 else
1296 {
1297 pipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
1298 }
1299
1300 #ifdef _MMC_SUPPORTED
1301 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
1302 #endif
1303
1304 // when there is no last, golden and alternate reference,
1305 // the index is set to the destination frame index
1306 pipeBufAddrParams.presReferences[CodechalDecodeLastRef] = m_presLastRefSurface;
1307 pipeBufAddrParams.presReferences[CodechalDecodeGoldenRef] = m_presGoldenRefSurface;
1308 pipeBufAddrParams.presReferences[CodechalDecodeAlternateRef] = m_presAltRefSurface;
1309
1310 pipeBufAddrParams.presMfdIntraRowStoreScratchBuffer = &m_resMfdIntraRowStoreScratchBuffer;
1311 pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resMfdDeblockingFilterRowStoreScratchBuffer;
1312 if (m_streamOutEnabled)
1313 {
1314 pipeBufAddrParams.presStreamOutBuffer =
1315 &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
1316 }
1317
1318 // set all ref pic addresses to valid addresses for error concealment purpose
1319 for (uint32_t i = 0; i <= CodechalDecodeAlternateRef; i++)
1320 {
1321 if (pipeBufAddrParams.presReferences[i] == nullptr &&
1322 MEDIA_IS_WA(m_waTable, WaDummyReference) &&
1323 !Mos_ResourceIsNull(&m_dummyReference.OsResource))
1324 {
1325 pipeBufAddrParams.presReferences[i] = &m_dummyReference.OsResource;
1326 }
1327 }
1328
1329 #ifdef _MMC_SUPPORTED
1330 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams));
1331
1332 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
1333 #endif
1334
1335 MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
1336 MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
1337 indObjBaseAddrParams.Mode = m_mode;
1338
1339 indObjBaseAddrParams.dwDataSize = m_dataSize;
1340 indObjBaseAddrParams.dwDataOffset = m_dataOffset;
1341 indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
1342
1343 MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
1344 MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
1345 bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
1346 bspBufBaseAddrParams.presMprRowStoreScratchBuffer = &m_resMprRowStoreScratchBuffer;
1347
1348 MHW_VDBOX_VP8_PIC_STATE vp8PicState;
1349 vp8PicState.pVp8PicParams = m_vp8PicParams;
1350 vp8PicState.pVp8IqMatrixParams = m_vp8IqMatrixParams;
1351 vp8PicState.presSegmentationIdStreamBuffer = &m_resSegmentationIdStreamBuffer;
1352 vp8PicState.dwCoefProbTableOffset = 0;
1353 vp8PicState.presCoefProbBuffer = &m_resCoefProbBuffer;
1354
1355 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1356 &cmdBuffer, true));
1357
1358 if (m_statusQueryReportingEnabled)
1359 {
1360 CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
1361 }
1362
1363 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
1364
1365 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
1366
1367 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
1368
1369 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
1370
1371 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
1372
1373 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVp8PicCmd(&cmdBuffer, &vp8PicState));
1374
1375 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1376
1377 return eStatus;
1378 }
1379
DecodePrimitiveLevel()1380 MOS_STATUS CodechalDecodeVp8::DecodePrimitiveLevel()
1381 {
1382 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1383
1384 CODECHAL_DECODE_FUNCTION_ENTER;
1385
1386 MOS_COMMAND_BUFFER cmdBuffer;
1387 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1388
1389 // Fill BSD Object Commands
1390 MHW_VDBOX_VP8_BSD_PARAMS vp8BsdParams;
1391 vp8BsdParams.pVp8PicParams = m_vp8PicParams;
1392
1393 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVp8BsdObjectCmd(&cmdBuffer, &vp8BsdParams));
1394
1395 // Check if destination surface needs to be synchronized
1396 MOS_SYNC_PARAMS syncParams;
1397 syncParams = g_cInitSyncParams;
1398 syncParams.GpuContext = m_videoContext;
1399 syncParams.presSyncResource = &m_destSurface.OsResource;
1400 syncParams.bReadOnly = false;
1401 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1402 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1403
1404 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1405 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1406
1407 // Update the resource tag (s/w tag) for On-Demand Sync
1408 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1409
1410 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1411 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1412
1413 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
1414
1415 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1416 if (m_osInterface->bTagResourceSync)
1417 {
1418 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
1419 }
1420
1421 if (m_statusQueryReportingEnabled)
1422 {
1423 CodechalDecodeStatusReport decodeStatusReport;
1424
1425 decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
1426 decodeStatusReport.m_currDecodedPic = m_vp8PicParams->CurrPic;
1427 decodeStatusReport.m_currDeblockedPic = m_vp8PicParams->CurrPic;
1428 decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
1429 decodeStatusReport.m_currDecodedPicRes = m_vp8RefList[m_vp8PicParams->CurrPic.FrameIdx]->resRefPic;
1430 CODECHAL_DEBUG_TOOL(
1431 decodeStatusReport.m_secondField = CodecHal_PictureIsBottomField(m_vp8PicParams->CurrPic);
1432 decodeStatusReport.m_frameType = m_perfType;)
1433 CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
1434 }
1435
1436 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1437
1438 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1439
1440 CODECHAL_DEBUG_TOOL(
1441 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1442 &cmdBuffer,
1443 CODECHAL_NUM_MEDIA_STATES,
1444 "_DEC"));
1445 )
1446
1447 if (m_huCCopyInUse)
1448 {
1449 syncParams = g_cInitSyncParams;
1450 syncParams.GpuContext = m_videoContextForWa;
1451 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1452
1453 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1454
1455 syncParams = g_cInitSyncParams;
1456 syncParams.GpuContext = m_videoContext;
1457 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1458
1459 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1460
1461 m_huCCopyInUse = false;
1462 }
1463
1464 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
1465
1466 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
1467
1468 CODECHAL_DEBUG_TOOL(
1469 m_mmc->UpdateUserFeatureKey(&m_destSurface);)
1470
1471 if (m_statusQueryReportingEnabled)
1472 {
1473 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
1474 }
1475
1476 // Needs to be re-set for Linux buffer re-use scenarios
1477 m_vp8RefList[m_vp8PicParams->ucCurrPicIndex]->resRefPic =
1478 m_destSurface.OsResource;
1479
1480 // Send the signal to indicate decode completion, in case On-Demand Sync is not present
1481 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
1482
1483 return eStatus;
1484 }
1485
InitMmcState()1486 MOS_STATUS CodechalDecodeVp8::InitMmcState()
1487 {
1488 #ifdef _MMC_SUPPORTED
1489 m_mmc = MOS_New(CodechalMmcDecodeVp8, m_hwInterface, this);
1490 CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
1491 #endif
1492 return MOS_STATUS_SUCCESS;
1493 }
1494
AllocateStandard(CodechalSetting * settings)1495 MOS_STATUS CodechalDecodeVp8::AllocateStandard(
1496 CodechalSetting *settings)
1497 {
1498 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1499
1500 CODECHAL_DECODE_FUNCTION_ENTER;
1501
1502 CODECHAL_DECODE_CHK_NULL_RETURN(settings);
1503
1504 CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
1505
1506 m_width = settings->width;
1507 m_height = settings->height;
1508 m_shortFormatInUse = settings->shortFormatInUse ? true : false;
1509 m_huCCopyInUse = false;
1510
1511 // Picture Level Commands
1512 m_hwInterface->GetMfxStateCommandsDataSize(
1513 m_mode,
1514 &m_commandBufferSizeNeeded,
1515 &m_commandPatchListSizeNeeded,
1516 m_shortFormatInUse);
1517
1518 // Primitive Level Commands
1519 m_hwInterface->GetMfxPrimitiveCommandsDataSize(
1520 m_mode,
1521 &m_standardDecodeSizeNeeded,
1522 &m_standardDecodePatchListSizeNeeded,
1523 m_shortFormatInUse);
1524
1525 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesFixedSizes());
1526
1527 return eStatus;
1528 }
1529
CodechalDecodeVp8(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1530 CodechalDecodeVp8::CodechalDecodeVp8(
1531 CodechalHwInterface * hwInterface,
1532 CodechalDebugInterface *debugInterface,
1533 PCODECHAL_STANDARD_INFO standardInfo) : CodechalDecode(hwInterface, debugInterface, standardInfo),
1534 m_picWidthInMbLastMaxAlloced(0),
1535 m_picHeightInMbLastMaxAlloced(0),
1536 m_shortFormatInUse(false),
1537 m_dataSize(0),
1538 m_dataOffset(0),
1539 m_vp8PicParams(nullptr),
1540 m_vp8IqMatrixParams(nullptr),
1541 m_presLastRefSurface(nullptr),
1542 m_presGoldenRefSurface(nullptr),
1543 m_presAltRefSurface(nullptr),
1544 m_mfdDeblockingFilterRowStoreScratchBufferPicWidthInMb(0),
1545 m_mfdIntraRowStoreScratchBufferPicWidthInMb(0),
1546 m_bsdMpcRowStoreScratchBufferPicWidthInMb(0),
1547 m_privateInputBufferSize(0),
1548 m_coeffProbTableOffset(0),
1549 m_deblockingEnabled(false),
1550 m_huCCopyInUse(false)
1551 {
1552 CODECHAL_DECODE_FUNCTION_ENTER;
1553
1554 MOS_ZeroMemory(&m_destSurface, sizeof(m_destSurface));
1555 MOS_ZeroMemory(&m_resDataBuffer, sizeof(m_resDataBuffer));
1556 MOS_ZeroMemory(&m_resCoefProbBuffer, sizeof(m_resCoefProbBuffer));
1557 MOS_ZeroMemory(&m_resTmpBitstreamBuffer, sizeof(m_resTmpBitstreamBuffer));
1558 MOS_ZeroMemory(&m_resMfdIntraRowStoreScratchBuffer, sizeof(m_resMfdIntraRowStoreScratchBuffer));
1559 MOS_ZeroMemory(&m_resMfdDeblockingFilterRowStoreScratchBuffer, sizeof(m_resMfdDeblockingFilterRowStoreScratchBuffer));
1560 MOS_ZeroMemory(&m_resBsdMpcRowStoreScratchBuffer, sizeof(m_resBsdMpcRowStoreScratchBuffer));
1561 MOS_ZeroMemory(&m_resMprRowStoreScratchBuffer, sizeof(m_resMprRowStoreScratchBuffer));
1562 MOS_ZeroMemory(&m_resSegmentationIdStreamBuffer, sizeof(m_resSegmentationIdStreamBuffer));
1563 MOS_ZeroMemory(&m_resSyncObject, sizeof(m_resSyncObject));
1564 MOS_ZeroMemory(&m_resPrivateInputBuffer, sizeof(m_resPrivateInputBuffer));
1565 MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(m_resSyncObjectWaContextInUse));
1566 MOS_ZeroMemory(&m_resSyncObjectVideoContextInUse, sizeof(m_resSyncObjectVideoContextInUse));
1567 MOS_ZeroMemory(&m_vp8FrameHead, sizeof(m_vp8FrameHead));
1568 m_hwInterface = hwInterface;
1569 }
1570
1571 #if USE_CODECHAL_DEBUG_TOOL
DumpPicParams(PCODEC_VP8_PIC_PARAMS picParams)1572 MOS_STATUS CodechalDecodeVp8::DumpPicParams(
1573 PCODEC_VP8_PIC_PARAMS picParams)
1574 {
1575 CODECHAL_DEBUG_FUNCTION_ENTER;
1576
1577 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
1578 {
1579 return MOS_STATUS_SUCCESS;
1580 }
1581
1582 CODECHAL_DEBUG_CHK_NULL(picParams);
1583
1584 std::ostringstream oss;
1585 oss.setf(std::ios::showbase | std::ios::uppercase);
1586
1587 oss<< "CurrPic FrameIdx: "<<std::hex<< +picParams->CurrPic.FrameIdx<<std::endl;
1588 oss<< "CurrPic PicFlags: "<<std::hex<< +picParams->CurrPic.PicFlags<<std::endl;
1589 oss<< "wFrameWidthInMbsMinus1: "<<std::hex<< +picParams->wFrameWidthInMbsMinus1<<std::endl;
1590 oss<< "wFrameHeightInMbsMinus1: "<<std::hex<< +picParams->wFrameHeightInMbsMinus1<<std::endl;
1591 oss<< "ucCurrPicIndex: "<<std::hex<< +picParams->ucCurrPicIndex<<std::endl;
1592 oss<< "ucLastRefPicIndex: "<<std::hex<< +picParams->ucLastRefPicIndex<<std::endl;
1593 oss<< "ucGoldenRefPicIndex: "<<std::hex<< +picParams->ucGoldenRefPicIndex<<std::endl;
1594 oss<< "ucAltRefPicIndex: "<<std::hex<< +picParams->ucAltRefPicIndex<<std::endl;
1595 oss<< "ucDeblockedPicIndex: "<<std::hex<< +picParams->ucDeblockedPicIndex<<std::endl;
1596 oss<< "ucReserved8Bits: "<<std::hex<< +picParams->ucReserved8Bits<<std::endl;
1597 oss<< "wPicFlags: "<<std::hex<< +picParams->wPicFlags<<std::endl;
1598 oss<< "key_frame: "<<std::hex<< +picParams->key_frame<<std::endl;
1599 oss<< "version: "<<std::hex<< +picParams->version<<std::endl;
1600 oss<< "segmentation_enabled: "<<std::hex<< +picParams->segmentation_enabled<<std::endl;
1601 oss<< "update_mb_segmentation_map: "<<std::hex<< +picParams->update_mb_segmentation_map<<std::endl;
1602 oss<< "update_segment_feature_data: "<<std::hex<< +picParams->update_segment_feature_data<<std::endl;
1603 oss<< "filter_type: "<<std::hex<< +picParams->filter_type<<std::endl;
1604 oss<< "sign_bias_golden: "<<std::hex<< +picParams->sign_bias_golden<<std::endl;
1605 oss<< "sign_bias_alternate: "<<std::hex<< +picParams->sign_bias_alternate<<std::endl;
1606 oss<< "mb_no_coeff_skip: "<<std::hex<< +picParams->mb_no_coeff_skip<<std::endl;
1607 oss<< "mode_ref_lf_delta_update: "<<std::hex<< +picParams->mode_ref_lf_delta_update<<std::endl;
1608 oss<< "CodedCoeffTokenPartition: "<<std::hex<< +picParams->CodedCoeffTokenPartition<<std::endl;
1609 oss<< "LoopFilterDisable: "<<std::hex<< +picParams->LoopFilterDisable<<std::endl;
1610 oss<< "loop_filter_adj_enable: "<<std::hex<< +picParams->loop_filter_adj_enable<<std::endl;
1611
1612 for(uint8_t i=0;i<4;++i)
1613 {
1614 oss<< "ucLoopFilterLevel[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->ucLoopFilterLevel[i]<<std::endl;
1615 }
1616
1617 for(uint8_t i=0;i<4;++i)
1618 {
1619 oss<< "cRefLfDelta["<<std::dec<<+i<<"]: "<<std::hex<< +picParams->cRefLfDelta[i]<<std::endl;
1620 }
1621
1622 for(uint8_t i=0;i<4;++i)
1623 {
1624 oss<< "cModeLfDelta[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->cModeLfDelta[i]<<std::endl;
1625 }
1626 oss<< "ucSharpnessLevel: " <<std::dec<<std::hex<< +picParams->ucSharpnessLevel<<std::endl;
1627
1628 for(uint8_t i=0;i<3;++i)
1629 {
1630 oss<< "cMbSegmentTreeProbs[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->cMbSegmentTreeProbs[i]<<std::endl;
1631 }
1632 oss<< "ucProbSkipFalse: "<<std::hex<< +picParams->ucProbSkipFalse<<std::endl;
1633 oss<< "ucProbIntra: "<<std::hex<< +picParams->ucProbIntra<<std::endl;
1634 oss<< "ucProbLast: "<<std::hex<< +picParams->ucProbLast<<std::endl;
1635 oss<< "ucProbGolden: "<<std::hex<< +picParams->ucProbGolden<<std::endl;
1636
1637 for(uint8_t i=0;i<4;++i)
1638 {
1639 oss<< "ucYModeProbs[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->ucYModeProbs[i]<<std::endl;
1640 }
1641
1642 for(uint8_t i=0;i<3;++i)
1643 {
1644 oss<< "ucUvModeProbs[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->ucUvModeProbs[i]<<std::endl;
1645 }
1646 oss<< "ucReserved8Bits1: "<<std::hex<< +picParams->ucReserved8Bits1<<std::endl;
1647 oss<< "ucP0EntropyCount: "<<std::hex<< +picParams->ucP0EntropyCount<<std::endl;
1648 oss<< "ucP0EntropyValue: "<<std::hex<< +picParams->ucP0EntropyValue<<std::endl;
1649 oss<< "uiP0EntropyRange: "<<std::hex<< +picParams->uiP0EntropyRange<<std::endl;
1650 oss<< "uiFirstMbByteOffset: "<<std::hex<< +picParams->uiFirstMbByteOffset<<std::endl;
1651
1652 for(uint8_t i=0;i<2;++i)
1653 {
1654 for(uint8_t j=0;j<CODEC_VP8_MVP_COUNT;++j)
1655 {
1656 oss<< "ucMvUpdateProb["<<std::dec<<+i<<"]["<<std::dec<<+j<<"]: "<<std::hex<< +picParams->ucMvUpdateProb[i][j]<<std::endl;
1657 }
1658 }
1659 for(uint8_t i=0;i<CODEC_VP8_MAX_PARTITION_NUMBER;++i)
1660 {
1661 oss<< "uiPartitionSize["<<std::dec<<+i<<"]: "<<std::hex<< +picParams->uiPartitionSize[i]<<std::endl;
1662 }
1663 oss<< "uiStatusReportFeedbackNumber: "<<std::hex<< +picParams->uiStatusReportFeedbackNumber<<std::endl;
1664
1665 const char* fileName = m_debugInterface->CreateFileName(
1666 "_DEC",
1667 CodechalDbgBufferType::bufPicParams,
1668 CodechalDbgExtType::txt);
1669
1670 std::ofstream ofs(fileName, std::ios::out);
1671 ofs << oss.str();
1672 ofs.close();
1673 return MOS_STATUS_SUCCESS;
1674 }
1675
DumpIQParams(PCODEC_VP8_IQ_MATRIX_PARAMS matrixData)1676 MOS_STATUS CodechalDecodeVp8::DumpIQParams(
1677 PCODEC_VP8_IQ_MATRIX_PARAMS matrixData)
1678 {
1679 CODECHAL_DEBUG_FUNCTION_ENTER;
1680
1681 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
1682 {
1683 return MOS_STATUS_SUCCESS;
1684 }
1685
1686 CODECHAL_DEBUG_CHK_NULL(matrixData);
1687
1688 std::ostringstream oss;
1689 oss.setf(std::ios::showbase | std::ios::uppercase);
1690
1691 for(uint8_t i=0;i<4;++i)
1692 {
1693 for(uint8_t j=0;j<6;++j)
1694 {
1695 oss<< "quantization_values["<< std::dec<< +i <<"]["<<+j<<"]: "<<std::hex<< +matrixData->quantization_values[i][j]<<std::endl;
1696 }
1697 }
1698
1699 const char* fileName = m_debugInterface->CreateFileName(
1700 "_DEC",
1701 CodechalDbgBufferType::bufIqParams,
1702 CodechalDbgExtType::txt);
1703
1704 std::ofstream ofs(fileName, std::ios::out);
1705 ofs << oss.str();
1706 ofs.close();
1707 return MOS_STATUS_SUCCESS;
1708 }
1709
1710 #endif
1711