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 }
1569 
1570 #if USE_CODECHAL_DEBUG_TOOL
DumpPicParams(PCODEC_VP8_PIC_PARAMS picParams)1571 MOS_STATUS CodechalDecodeVp8::DumpPicParams(
1572     PCODEC_VP8_PIC_PARAMS           picParams)
1573 {
1574     CODECHAL_DEBUG_FUNCTION_ENTER;
1575 
1576     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
1577     {
1578         return MOS_STATUS_SUCCESS;
1579     }
1580 
1581     CODECHAL_DEBUG_CHK_NULL(picParams);
1582 
1583     std::ostringstream oss;
1584     oss.setf(std::ios::showbase | std::ios::uppercase);
1585 
1586     oss<< "CurrPic FrameIdx: "<<std::hex<< +picParams->CurrPic.FrameIdx<<std::endl;
1587     oss<< "CurrPic PicFlags: "<<std::hex<< +picParams->CurrPic.PicFlags<<std::endl;
1588     oss<< "wFrameWidthInMbsMinus1: "<<std::hex<< +picParams->wFrameWidthInMbsMinus1<<std::endl;
1589     oss<< "wFrameHeightInMbsMinus1: "<<std::hex<< +picParams->wFrameHeightInMbsMinus1<<std::endl;
1590     oss<< "ucCurrPicIndex: "<<std::hex<< +picParams->ucCurrPicIndex<<std::endl;
1591     oss<< "ucLastRefPicIndex: "<<std::hex<< +picParams->ucLastRefPicIndex<<std::endl;
1592     oss<< "ucGoldenRefPicIndex: "<<std::hex<< +picParams->ucGoldenRefPicIndex<<std::endl;
1593     oss<< "ucAltRefPicIndex: "<<std::hex<< +picParams->ucAltRefPicIndex<<std::endl;
1594     oss<< "ucDeblockedPicIndex: "<<std::hex<< +picParams->ucDeblockedPicIndex<<std::endl;
1595     oss<< "ucReserved8Bits: "<<std::hex<< +picParams->ucReserved8Bits<<std::endl;
1596     oss<< "wPicFlags: "<<std::hex<< +picParams->wPicFlags<<std::endl;
1597     oss<< "key_frame: "<<std::hex<< +picParams->key_frame<<std::endl;
1598     oss<< "version: "<<std::hex<< +picParams->version<<std::endl;
1599     oss<< "segmentation_enabled: "<<std::hex<< +picParams->segmentation_enabled<<std::endl;
1600     oss<< "update_mb_segmentation_map: "<<std::hex<< +picParams->update_mb_segmentation_map<<std::endl;
1601     oss<< "update_segment_feature_data: "<<std::hex<< +picParams->update_segment_feature_data<<std::endl;
1602     oss<< "filter_type: "<<std::hex<< +picParams->filter_type<<std::endl;
1603     oss<< "sign_bias_golden: "<<std::hex<< +picParams->sign_bias_golden<<std::endl;
1604     oss<< "sign_bias_alternate: "<<std::hex<< +picParams->sign_bias_alternate<<std::endl;
1605     oss<< "mb_no_coeff_skip: "<<std::hex<< +picParams->mb_no_coeff_skip<<std::endl;
1606     oss<< "mode_ref_lf_delta_update: "<<std::hex<< +picParams->mode_ref_lf_delta_update<<std::endl;
1607     oss<< "CodedCoeffTokenPartition: "<<std::hex<< +picParams->CodedCoeffTokenPartition<<std::endl;
1608     oss<< "LoopFilterDisable: "<<std::hex<< +picParams->LoopFilterDisable<<std::endl;
1609     oss<< "loop_filter_adj_enable: "<<std::hex<< +picParams->loop_filter_adj_enable<<std::endl;
1610 
1611     for(uint8_t i=0;i<4;++i)
1612     {
1613         oss<< "ucLoopFilterLevel[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->ucLoopFilterLevel[i]<<std::endl;
1614     }
1615 
1616     for(uint8_t i=0;i<4;++i)
1617     {
1618         oss<< "cRefLfDelta["<<std::dec<<+i<<"]: "<<std::hex<< +picParams->cRefLfDelta[i]<<std::endl;
1619     }
1620 
1621     for(uint8_t i=0;i<4;++i)
1622     {
1623         oss<< "cModeLfDelta[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->cModeLfDelta[i]<<std::endl;
1624     }
1625     oss<< "ucSharpnessLevel: " <<std::dec<<std::hex<< +picParams->ucSharpnessLevel<<std::endl;
1626 
1627     for(uint8_t i=0;i<3;++i)
1628     {
1629         oss<< "cMbSegmentTreeProbs[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->cMbSegmentTreeProbs[i]<<std::endl;
1630     }
1631     oss<< "ucProbSkipFalse: "<<std::hex<< +picParams->ucProbSkipFalse<<std::endl;
1632     oss<< "ucProbIntra: "<<std::hex<< +picParams->ucProbIntra<<std::endl;
1633     oss<< "ucProbLast: "<<std::hex<< +picParams->ucProbLast<<std::endl;
1634     oss<< "ucProbGolden: "<<std::hex<< +picParams->ucProbGolden<<std::endl;
1635 
1636     for(uint8_t i=0;i<4;++i)
1637     {
1638         oss<< "ucYModeProbs[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->ucYModeProbs[i]<<std::endl;
1639     }
1640 
1641     for(uint8_t i=0;i<3;++i)
1642     {
1643         oss<< "ucUvModeProbs[" <<std::dec<<+i<<"]: "<<std::hex<< +picParams->ucUvModeProbs[i]<<std::endl;
1644     }
1645     oss<< "ucReserved8Bits1: "<<std::hex<< +picParams->ucReserved8Bits1<<std::endl;
1646     oss<< "ucP0EntropyCount: "<<std::hex<< +picParams->ucP0EntropyCount<<std::endl;
1647     oss<< "ucP0EntropyValue: "<<std::hex<< +picParams->ucP0EntropyValue<<std::endl;
1648     oss<< "uiP0EntropyRange: "<<std::hex<< +picParams->uiP0EntropyRange<<std::endl;
1649     oss<< "uiFirstMbByteOffset: "<<std::hex<< +picParams->uiFirstMbByteOffset<<std::endl;
1650 
1651     for(uint8_t i=0;i<2;++i)
1652     {
1653         for(uint8_t j=0;j<CODEC_VP8_MVP_COUNT;++j)
1654         {
1655             oss<< "ucMvUpdateProb["<<std::dec<<+i<<"]["<<std::dec<<+j<<"]: "<<std::hex<< +picParams->ucMvUpdateProb[i][j]<<std::endl;
1656         }
1657     }
1658     for(uint8_t i=0;i<CODEC_VP8_MAX_PARTITION_NUMBER;++i)
1659     {
1660         oss<< "uiPartitionSize["<<std::dec<<+i<<"]: "<<std::hex<< +picParams->uiPartitionSize[i]<<std::endl;
1661     }
1662     oss<< "uiStatusReportFeedbackNumber: "<<std::hex<< +picParams->uiStatusReportFeedbackNumber<<std::endl;
1663 
1664     const char* fileName = m_debugInterface->CreateFileName(
1665         "_DEC",
1666         CodechalDbgBufferType::bufPicParams,
1667         CodechalDbgExtType::txt);
1668 
1669     std::ofstream ofs(fileName, std::ios::out);
1670     ofs << oss.str();
1671     ofs.close();
1672     return MOS_STATUS_SUCCESS;
1673 }
1674 
DumpIQParams(PCODEC_VP8_IQ_MATRIX_PARAMS matrixData)1675 MOS_STATUS CodechalDecodeVp8::DumpIQParams(
1676     PCODEC_VP8_IQ_MATRIX_PARAMS          matrixData)
1677 {
1678     CODECHAL_DEBUG_FUNCTION_ENTER;
1679 
1680     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
1681     {
1682         return MOS_STATUS_SUCCESS;
1683     }
1684 
1685     CODECHAL_DEBUG_CHK_NULL(matrixData);
1686 
1687     std::ostringstream oss;
1688     oss.setf(std::ios::showbase | std::ios::uppercase);
1689 
1690     for(uint8_t i=0;i<4;++i)
1691     {
1692         for(uint8_t j=0;j<6;++j)
1693         {
1694             oss<< "quantization_values["<< std::dec<< +i <<"]["<<+j<<"]: "<<std::hex<< +matrixData->quantization_values[i][j]<<std::endl;
1695         }
1696     }
1697 
1698     const char* fileName = m_debugInterface->CreateFileName(
1699         "_DEC",
1700         CodechalDbgBufferType::bufIqParams,
1701         CodechalDbgExtType::txt);
1702 
1703     std::ofstream ofs(fileName, std::ios::out);
1704     ofs << oss.str();
1705     ofs.close();
1706     return MOS_STATUS_SUCCESS;
1707 }
1708 
1709 #endif
1710