1 /*
2 * Copyright (c) 2012-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_vp9.cpp
24 //! \brief    Implements the decode interface extension for VP9.
25 //! \details  Implements all functions required by CodecHal for VP9 decoding.
26 //!
27 
28 #include "codechal_decoder.h"
29 #include "codechal_secure_decode_interface.h"
30 #include "codechal_decode_vp9.h"
31 #include "codechal_mmc_decode_vp9.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 
~CodechalDecodeVp9()39 CodechalDecodeVp9 :: ~CodechalDecodeVp9 ()
40 {
41     CODECHAL_DECODE_FUNCTION_ENTER;
42 
43     m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObject);
44     m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectWaContextInUse);
45     m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectVideoContextInUse);
46 
47     CodecHalFreeDataList(m_vp9RefList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9);
48 
49     if (!Mos_ResourceIsNull(&m_resDeblockingFilterLineRowStoreScratchBuffer))
50     {
51         m_osInterface->pfnFreeResource(
52             m_osInterface,
53             &m_resDeblockingFilterLineRowStoreScratchBuffer);
54     }
55 
56     m_osInterface->pfnFreeResource(
57         m_osInterface,
58         &m_resDeblockingFilterTileRowStoreScratchBuffer);
59 
60     m_osInterface->pfnFreeResource(
61         m_osInterface,
62         &m_resDeblockingFilterColumnRowStoreScratchBuffer);
63 
64     m_osInterface->pfnFreeResource(
65         m_osInterface,
66         &m_resMetadataLineBuffer);
67 
68     m_osInterface->pfnFreeResource(
69         m_osInterface,
70         &m_resMetadataTileLineBuffer);
71 
72     m_osInterface->pfnFreeResource(
73         m_osInterface,
74         &m_resMetadataTileColumnBuffer);
75 
76     if (!Mos_ResourceIsNull(&m_resHvcLineRowstoreBuffer))
77     {
78         m_osInterface->pfnFreeResource(
79             m_osInterface,
80             &m_resHvcLineRowstoreBuffer);
81     }
82 
83     m_osInterface->pfnFreeResource(
84         m_osInterface,
85         &m_resHvcTileRowstoreBuffer);
86 
87     for (uint8_t i = 0; i < CODEC_VP9_NUM_CONTEXTS + 1; i++)
88     {
89         m_osInterface->pfnFreeResource(
90             m_osInterface,
91             &m_resVp9ProbBuffer[i]);
92     }
93 
94     m_osInterface->pfnFreeResource(
95         m_osInterface,
96         &m_resVp9SegmentIdBuffer);
97 
98     m_osInterface->pfnFreeResource(
99         m_osInterface,
100         &m_resSegmentIdBuffReset);
101 
102     for (uint8_t i = 0; i < CODECHAL_VP9_NUM_MV_BUFFERS; i++)
103     {
104         m_osInterface->pfnFreeResource(
105             m_osInterface,
106             &m_resVp9MvTemporalBuffer[i]);
107     }
108 
109     if (!Mos_ResourceIsNull(&m_resCopyDataBuffer))
110     {
111         m_osInterface->pfnFreeResource(
112             m_osInterface,
113             &m_resCopyDataBuffer);
114     }
115 
116     m_osInterface->pfnFreeResource(
117         m_osInterface,
118         &m_resHucSharedBuffer);
119 
120     m_osInterface->pfnFreeResource(
121         m_osInterface,
122         &m_resDmemBuffer);
123 
124     m_osInterface->pfnFreeResource(
125         m_osInterface,
126         &m_resInterProbSaveBuffer);
127 
128     if (m_picMhwParams.PipeModeSelectParams)
129     {
130         MOS_Delete(m_picMhwParams.PipeModeSelectParams);
131         m_picMhwParams.PipeModeSelectParams = nullptr;
132     }
133     for (uint8_t i = 0; i < 4; i++)
134     {
135         if (m_picMhwParams.SurfaceParams[i])
136         {
137             MOS_Delete(m_picMhwParams.SurfaceParams[i]);
138             m_picMhwParams.SurfaceParams[i] = nullptr;
139         }
140     }
141     if (m_picMhwParams.PipeBufAddrParams)
142     {
143         MOS_Delete(m_picMhwParams.PipeBufAddrParams);
144         m_picMhwParams.PipeBufAddrParams = nullptr;
145     }
146     if (m_picMhwParams.IndObjBaseAddrParams)
147     {
148         MOS_Delete(m_picMhwParams.IndObjBaseAddrParams);
149         m_picMhwParams.IndObjBaseAddrParams = nullptr;
150     }
151     if (m_picMhwParams.Vp9PicState)
152     {
153         MOS_Delete(m_picMhwParams.Vp9PicState);
154         m_picMhwParams.Vp9PicState = nullptr;
155     }
156     if (m_picMhwParams.Vp9SegmentState)
157     {
158         MOS_Delete(m_picMhwParams.Vp9SegmentState);
159         m_picMhwParams.Vp9SegmentState = nullptr;
160     }
161 }
162 
CodechalDecodeVp9(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)163 CodechalDecodeVp9 ::CodechalDecodeVp9(
164     CodechalHwInterface *   hwInterface,
165     CodechalDebugInterface *debugInterface,
166     PCODECHAL_STANDARD_INFO standardInfo) : CodechalDecode(hwInterface, debugInterface, standardInfo),
167                                             m_usFrameWidthAlignedMinBlk(0),
168                                             m_usFrameHeightAlignedMinBlk(0),
169                                             m_vp9DepthIndicator(0),
170                                             m_chromaFormatinProfile(0),
171                                             m_dataSize(0),
172                                             m_dataOffset(0),
173                                             m_frameCtxIdx(0),
174                                             m_curMvTempBufIdx(0),
175                                             m_colMvTempBufIdx(0),
176                                             m_copyDataBufferSize(0),
177                                             m_copyDataOffset(0),
178                                             m_copyDataBufferInUse(false),
179                                             m_hcpDecPhase(0),
180                                             m_prevFrmWidth(0),
181                                             m_prevFrmHeight(0),
182                                             m_allocatedWidthInSb(0),
183                                             m_allocatedHeightInSb(0),
184                                             m_mvBufferSize(0),
185                                             m_resetSegIdBuffer(false),
186                                             m_pendingResetPartial(0),
187                                             m_saveInterProbs(0),
188                                             m_fullProbBufferUpdate(false),
189                                             m_dmemBufferSize(0)
190 {
191     CODECHAL_DECODE_FUNCTION_ENTER;
192 
193     MOS_ZeroMemory(&m_resDeblockingFilterLineRowStoreScratchBuffer, sizeof(m_resDeblockingFilterLineRowStoreScratchBuffer));
194     MOS_ZeroMemory(&m_resDeblockingFilterTileRowStoreScratchBuffer, sizeof(m_resDeblockingFilterTileRowStoreScratchBuffer));
195     MOS_ZeroMemory(&m_resDeblockingFilterColumnRowStoreScratchBuffer, sizeof(m_resDeblockingFilterColumnRowStoreScratchBuffer));
196     MOS_ZeroMemory(&m_resMetadataLineBuffer, sizeof(m_resMetadataLineBuffer));
197     MOS_ZeroMemory(&m_resMetadataTileLineBuffer, sizeof(m_resMetadataTileLineBuffer));
198     MOS_ZeroMemory(&m_resMetadataTileColumnBuffer, sizeof(m_resMetadataTileColumnBuffer));
199     MOS_ZeroMemory(&m_resHvcLineRowstoreBuffer, sizeof(m_resHvcLineRowstoreBuffer));
200     MOS_ZeroMemory(&m_resHvcTileRowstoreBuffer, sizeof(m_resHvcTileRowstoreBuffer));
201     MOS_ZeroMemory(&m_resVp9SegmentIdBuffer, sizeof(m_resVp9SegmentIdBuffer));
202     MOS_ZeroMemory(&m_resVp9MvTemporalBuffer, sizeof(m_resVp9MvTemporalBuffer));
203     MOS_ZeroMemory(&m_resCopyDataBuffer, sizeof(m_resCopyDataBuffer));
204     MOS_ZeroMemory(&m_segTreeProbs, sizeof(m_segTreeProbs));
205     MOS_ZeroMemory(&m_segPredProbs, sizeof(m_segPredProbs));
206     MOS_ZeroMemory(&m_interProbSaved, sizeof(m_interProbSaved));
207     MOS_ZeroMemory(&m_resDmemBuffer, sizeof(m_resDmemBuffer));
208     MOS_ZeroMemory(&m_resInterProbSaveBuffer, sizeof(m_resInterProbSaveBuffer));
209     MOS_ZeroMemory(&m_probUpdateFlags, sizeof(m_probUpdateFlags));
210     MOS_ZeroMemory(&m_resSegmentIdBuffReset, sizeof(m_resSegmentIdBuffReset));
211     MOS_ZeroMemory(&m_resHucSharedBuffer, sizeof(m_resHucSharedBuffer));
212     MOS_ZeroMemory(&m_picMhwParams, sizeof(m_picMhwParams));
213     MOS_ZeroMemory(&m_destSurface, sizeof(m_destSurface));
214     MOS_ZeroMemory(&m_lastRefSurface, sizeof(m_lastRefSurface));
215     MOS_ZeroMemory(&m_goldenRefSurface, sizeof(m_goldenRefSurface));
216     MOS_ZeroMemory(&m_altRefSurface, sizeof(m_altRefSurface));
217     MOS_ZeroMemory(&m_resDataBuffer, sizeof(m_resDataBuffer));
218     MOS_ZeroMemory(&m_resCoefProbBuffer, sizeof(m_resCoefProbBuffer));
219     MOS_ZeroMemory(&m_resSyncObject, sizeof(m_resSyncObject));
220     MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(m_resSyncObjectWaContextInUse));
221     MOS_ZeroMemory(&m_resSyncObjectVideoContextInUse, sizeof(m_resSyncObjectVideoContextInUse));
222 
223     m_prevFrameParams.value = 0;
224 #if (_DEBUG || _RELEASE_INTERNAL)
225     m_reportFrameCrc        = true;
226 #endif
227     for (uint8_t i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++)
228     {
229         m_pendingResetFullTables[i] = 0;
230         m_pendingCopySegProbs[i]    = 0;
231     }
232 
233     m_hcpInUse = true;
234 }
235 
ProbBufferPartialUpdatewithDrv()236 MOS_STATUS CodechalDecodeVp9 :: ProbBufferPartialUpdatewithDrv()
237 {
238     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
239 
240     CODECHAL_DECODE_FUNCTION_ENTER;
241 
242     CodechalResLock ResourceLock(m_osInterface, &m_resVp9ProbBuffer[m_frameCtxIdx]);
243     auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
244     CODECHAL_DECODE_CHK_NULL_RETURN(data);
245 
246     if (m_probUpdateFlags.bSegProbCopy)
247     {
248         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
249             (data + CODEC_VP9_SEG_PROB_OFFSET),
250             7,
251             m_probUpdateFlags.SegTreeProbs,
252             7));
253         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
254             (data + CODEC_VP9_SEG_PROB_OFFSET + 7),
255             3,
256             m_probUpdateFlags.SegPredProbs,
257             3));
258     }
259 
260     if (m_probUpdateFlags.bProbSave)
261     {
262         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
263             m_interProbSaved,
264             CODECHAL_VP9_INTER_PROB_SIZE,
265             data + CODEC_VP9_INTER_PROB_OFFSET,
266             CODECHAL_VP9_INTER_PROB_SIZE));
267     }
268 
269     if (m_probUpdateFlags.bProbReset)
270     {
271         if (m_probUpdateFlags.bResetFull)
272         {
273             CODECHAL_DECODE_CHK_STATUS_RETURN(ContextBufferInit(
274                 data, (m_probUpdateFlags.bResetKeyDefault ? true : false)));
275         }
276         else
277         {
278             CODECHAL_DECODE_CHK_STATUS_RETURN(CtxBufDiffInit(
279                 data, (m_probUpdateFlags.bResetKeyDefault ? true : false)));
280         }
281     }
282 
283     if (m_probUpdateFlags.bProbRestore)
284     {
285         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
286             data + CODEC_VP9_INTER_PROB_OFFSET,
287             CODECHAL_VP9_INTER_PROB_SIZE,
288             m_interProbSaved,
289             CODECHAL_VP9_INTER_PROB_SIZE));
290     }
291 
292     return eStatus;
293 }
294 
ProbBufFullUpdatewithDrv()295 MOS_STATUS CodechalDecodeVp9 :: ProbBufFullUpdatewithDrv()
296 {
297     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
298 
299     CODECHAL_DECODE_FUNCTION_ENTER;
300 
301     CodechalResLock ResourceLock(m_osInterface, &m_resVp9ProbBuffer[m_frameCtxIdx]);
302     auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
303     CODECHAL_DECODE_CHK_NULL_RETURN(data);
304 
305     CODECHAL_DECODE_CHK_STATUS_RETURN(ContextBufferInit(
306         data, (m_probUpdateFlags.bResetKeyDefault ? true : false)));
307     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
308         (data + CODEC_VP9_SEG_PROB_OFFSET),
309         7,
310         m_probUpdateFlags.SegTreeProbs,
311         7));
312     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
313         (data + CODEC_VP9_SEG_PROB_OFFSET + 7),
314         3,
315         m_probUpdateFlags.SegPredProbs,
316         3));
317 
318     return eStatus;
319 }
320 
ResetSegIdBufferwithDrv()321 MOS_STATUS CodechalDecodeVp9 :: ResetSegIdBufferwithDrv()
322 {
323     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
324 
325     CODECHAL_DECODE_FUNCTION_ENTER;
326 
327     CodechalResLock ResourceLock(m_osInterface, &m_resVp9SegmentIdBuffer);
328     auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
329     CODECHAL_DECODE_CHK_NULL_RETURN(data);
330 
331     MOS_ZeroMemory(
332         data,
333         m_allocatedWidthInSb * m_allocatedHeightInSb * CODECHAL_CACHELINE_SIZE);
334 
335     return eStatus;
336 }
337 
ProbBufFullUpdatewithHucStreamout(PMOS_COMMAND_BUFFER cmdBuffer)338 MOS_STATUS CodechalDecodeVp9 :: ProbBufFullUpdatewithHucStreamout(
339     PMOS_COMMAND_BUFFER         cmdBuffer)
340 {
341     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
342 
343     CODECHAL_DECODE_FUNCTION_ENTER;
344 
345     m_osInterface->pfnSetPerfTag(
346         m_osInterface,
347         (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE));
348     m_osInterface->pfnResetPerfBufferID(m_osInterface);
349 
350     uint32_t bufSize = CODEC_VP9_PROB_MAX_NUM_ELEM; // 16 byte aligned
351 
352     CodechalResLock ResourceLock(m_osInterface, &m_resVp9ProbBuffer[CODEC_VP9_NUM_CONTEXTS]);
353     auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
354     CODECHAL_DECODE_CHK_NULL_RETURN(data);
355 
356     CODECHAL_DECODE_CHK_STATUS_RETURN(ContextBufferInit(
357         data,
358         (m_probUpdateFlags.bResetKeyDefault ? true : false)));
359     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
360         (data + CODEC_VP9_SEG_PROB_OFFSET),
361         7,
362         m_probUpdateFlags.SegTreeProbs,
363         7));
364     CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
365         (data + CODEC_VP9_SEG_PROB_OFFSET + 7),
366         3,
367         m_probUpdateFlags.SegPredProbs,
368         3));
369 
370     CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
371         cmdBuffer,                                    // cmdBuffer
372         &m_resVp9ProbBuffer[CODEC_VP9_NUM_CONTEXTS],  // presSrc
373         &m_resVp9ProbBuffer[m_frameCtxIdx],           // presDst
374         bufSize,                                      // u32CopyLength
375         0,                                            // u32CopyInputOffset
376         0));                                          // u32CopyOutputOffset
377 
378     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
379     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
380     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
381         cmdBuffer,
382         &flushDwParams));
383 
384     return eStatus;
385 }
386 
ResetSegIdBufferwithHucStreamout(PMOS_COMMAND_BUFFER cmdBuffer)387 MOS_STATUS CodechalDecodeVp9 :: ResetSegIdBufferwithHucStreamout(
388     PMOS_COMMAND_BUFFER         cmdBuffer)
389 {
390     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
391 
392     CODECHAL_DECODE_FUNCTION_ENTER;
393 
394     m_osInterface->pfnSetPerfTag(
395         m_osInterface,
396         (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE));
397     m_osInterface->pfnResetPerfBufferID(m_osInterface);
398 
399     uint32_t bufSize =
400         m_allocatedWidthInSb * m_allocatedHeightInSb * CODECHAL_CACHELINE_SIZE;  // 16 byte aligned
401 
402     CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
403         cmdBuffer,                 // cmdBuffer
404         &m_resSegmentIdBuffReset,  // presSrc
405         &m_resVp9SegmentIdBuffer,  // presDst
406         bufSize,                   // u32CopyLength
407         0,                         // u32CopyInputOffset
408         0));                       // u32CopyOutputOffset
409 
410     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
411     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
412     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
413         cmdBuffer,
414         &flushDwParams));
415 
416     return eStatus;
417 }
418 
DetermineInternalBufferUpdate()419 MOS_STATUS CodechalDecodeVp9 :: DetermineInternalBufferUpdate()
420 {
421     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
422 
423     CODECHAL_DECODE_FUNCTION_ENTER;
424 
425     bool    keyFrame       = !m_vp9PicParams->PicFlags.fields.frame_type;
426     bool    intraOnly      = m_vp9PicParams->PicFlags.fields.intra_only;
427     uint8_t curFrameCtxIdx = (uint8_t)m_vp9PicParams->PicFlags.fields.frame_context_idx;
428     bool    isScaling      = (m_destSurface.dwWidth == m_prevFrmWidth) &&
429                              (m_destSurface.dwHeight == m_prevFrmHeight)
430                          ? false
431                          : true;
432     bool resetAll       = (keyFrame |
433                          m_vp9PicParams->PicFlags.fields.error_resilient_mode ||
434                      (m_vp9PicParams->PicFlags.fields.reset_frame_context == 3 &&
435                          m_vp9PicParams->PicFlags.fields.intra_only));
436     bool resetSpecified = (m_vp9PicParams->PicFlags.fields.reset_frame_context == 2 &&
437                            m_vp9PicParams->PicFlags.fields.intra_only);
438 
439     bool copySegProbs       = false;  // indicating if current frame's prob buffer need to update seg tree/pred probs.
440     bool resetFullTbl       = false;  // indicating if current frame will do full frame context table reset
441     bool resetPartialTbl    = false;  // indicating if current frame need to do partial reset from offset 1667 to 2010.
442     bool restoreInterProbs  = false;  // indicating if current frame need to restore offset 1667 to 2010 from saved one, this is only for prob buffer 0.
443     bool saveInterProbsTmp  = false;  // indicating if current frame need to save offset from 1667 to 2010 for prob buffer 0.
444 
445     m_resetSegIdBuffer = keyFrame ||
446                          isScaling ||
447                          m_vp9PicParams->PicFlags.fields.error_resilient_mode ||
448                          m_vp9PicParams->PicFlags.fields.intra_only;
449 
450     m_frameCtxIdx = curFrameCtxIdx;  //indicate which prob buffer need to be used by current frame decode
451     if (!m_vp9PicParams->PicFlags.fields.frame_type ||
452         m_vp9PicParams->PicFlags.fields.intra_only ||
453         m_vp9PicParams->PicFlags.fields.error_resilient_mode)
454     {
455         //always use frame context idx 0 in this case
456         m_frameCtxIdx = 0;
457     }
458 
459     //check if seg tree/pred probs need to be updated in prob buffer of current frame
460     //and also mark the flag bPendingResetSegProbs for other prob buffers
461     if (m_vp9PicParams->PicFlags.fields.segmentation_enabled &&
462         m_vp9PicParams->PicFlags.fields.segmentation_update_map)
463     {
464         copySegProbs = true;
465         for ( uint8_t ctxIdx = 0; ctxIdx < CODEC_VP9_NUM_CONTEXTS; ctxIdx++)
466         {
467             m_pendingCopySegProbs[ctxIdx] = true;
468         }
469         //set current frame's prob buffer pending copy to false
470         m_pendingCopySegProbs[m_frameCtxIdx] = false;
471 
472         //save probs for pending copy
473         MOS_SecureMemcpy(m_segTreeProbs, 7, m_vp9PicParams->SegTreeProbs, 7);
474         MOS_SecureMemcpy(m_segPredProbs, 3, m_vp9PicParams->SegPredProbs, 3);
475     }
476     else if (m_vp9PicParams->PicFlags.fields.segmentation_enabled &&
477              m_pendingCopySegProbs[m_frameCtxIdx])
478     {
479         copySegProbs = true;
480         m_pendingCopySegProbs[m_frameCtxIdx] = false;
481     }
482 
483     //check if probs in frame context table need to be updated for current frame's prob buffer
484     //and also mark the flag bPendingResetFullTables for other prob buffers
485     if (resetAll)
486     {
487         resetFullTbl = true;
488         m_pendingResetPartial = (keyFrame || intraOnly);
489 
490         //prob buffer 0 will be used for current frame decoding
491         for ( uint8_t ctxIdx = 1; ctxIdx < CODEC_VP9_NUM_CONTEXTS; ctxIdx++)
492         {
493             m_pendingResetFullTables[ctxIdx] = true;
494         }
495         m_saveInterProbs = false;
496     }
497     else if (resetSpecified)
498     {
499         //intra only frame:prob buffer 0 will always be used for current frame decoding
500         if (curFrameCtxIdx == 0)
501         {
502             //do prob table 0 reset
503             resetFullTbl = true;
504             m_pendingResetPartial = true;
505             m_saveInterProbs      = false;
506         }
507         else
508         {
509             //not do reset right now, pending the reset full table of specified ctx until a later frame use it to do decode
510             m_pendingResetFullTables[curFrameCtxIdx] = true;
511             if (!m_pendingResetPartial)
512             {
513                 if (!m_saveInterProbs)
514                 {
515                     saveInterProbsTmp = true;
516                     m_saveInterProbs  = true;
517                 }
518                 resetPartialTbl = true;
519             }
520         }
521     }
522     else if (intraOnly)
523     {
524         //prob buffer 0 will be used for current frame decoding
525         if (!m_pendingResetPartial)
526         {
527             if (!m_saveInterProbs)
528             {
529                 saveInterProbsTmp = true;
530                 m_saveInterProbs  = true;
531             }
532             resetPartialTbl = true;
533         }
534     }
535     else if (m_pendingResetFullTables[curFrameCtxIdx])
536     {
537         //here curFrameCtxIdx != 0, frame is inter frame
538         resetFullTbl = true;
539         m_pendingResetFullTables[curFrameCtxIdx] = false;
540     }
541     else if (curFrameCtxIdx == 0 && m_pendingResetPartial)
542     {
543         //here curFrameCtxIdx = 0, frame is inter frame
544         resetPartialTbl = true;
545         m_pendingResetPartial = false;
546     }
547     else if (curFrameCtxIdx == 0 && m_saveInterProbs)
548     {
549         //here curFrameCtxIdx = 0, frame is inter frame
550         restoreInterProbs = true;
551         m_saveInterProbs  = false;
552     }
553 
554     //decide if prob buffer need to do a full udpate or partial upate
555     if (resetFullTbl && copySegProbs)
556     {
557         //update the whole prob buffer
558         m_fullProbBufferUpdate = true;
559     }
560     else
561     {
562         //partial buffer update
563         m_fullProbBufferUpdate = false;
564     }
565 
566     //propogate ProbUpdateFlags
567     MOS_ZeroMemory(&m_probUpdateFlags, sizeof(m_probUpdateFlags));
568     if (copySegProbs)
569     {
570         m_probUpdateFlags.bSegProbCopy = true;
571         MOS_SecureMemcpy(m_probUpdateFlags.SegTreeProbs, 7, m_segTreeProbs, 7);
572         MOS_SecureMemcpy(m_probUpdateFlags.SegPredProbs, 3, m_segPredProbs, 3);
573     }
574     m_probUpdateFlags.bProbReset       = resetFullTbl || resetPartialTbl;
575     m_probUpdateFlags.bResetFull       = resetFullTbl;
576     m_probUpdateFlags.bResetKeyDefault = (keyFrame || intraOnly);
577     m_probUpdateFlags.bProbSave        = saveInterProbsTmp;
578     m_probUpdateFlags.bProbRestore     = restoreInterProbs;
579 
580     return eStatus;
581 }
582 
AllocateResourcesFixedSizes()583 MOS_STATUS CodechalDecodeVp9 :: AllocateResourcesFixedSizes()
584 {
585     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
586 
587     CODECHAL_DECODE_FUNCTION_ENTER;
588 
589     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
590         m_osInterface, &m_resSyncObject));
591     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
592         m_osInterface, &m_resSyncObjectWaContextInUse));
593     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
594         m_osInterface, &m_resSyncObjectVideoContextInUse));
595 
596     CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalAllocateDataList(
597         m_vp9RefList,
598         CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9));
599 
600     // VP9 Probability buffer
601     for (uint8_t i = 0; i < CODEC_VP9_NUM_CONTEXTS + 1; i++)
602     {
603         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
604                                                       &m_resVp9ProbBuffer[i],
605                                                       MOS_ALIGN_CEIL(CODEC_VP9_PROB_MAX_NUM_ELEM, CODECHAL_PAGE_SIZE),
606                                                       "Vp9ProbabilityBuffer"),
607             "Failed to allocate VP9 probability Buffer.");
608 
609         CodechalResLock ResourceLock(m_osInterface, &m_resVp9ProbBuffer[i]);
610         auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
611         CODECHAL_DECODE_CHK_NULL_RETURN(data);
612 
613         MOS_ZeroMemory(data, CODEC_VP9_PROB_MAX_NUM_ELEM);
614         //initialize seg_tree_prob and seg_pred_prob
615         MOS_FillMemory((data + CODEC_VP9_SEG_PROB_OFFSET), 7, CODEC_VP9_MAX_PROB);
616         MOS_FillMemory((data + CODEC_VP9_SEG_PROB_OFFSET + 7), 3, CODEC_VP9_MAX_PROB);
617     }
618 
619     // DMEM buffer send to HuC FW
620     m_dmemBufferSize = MOS_ALIGN_CEIL(sizeof(CODECHAL_DECODE_VP9_PROB_UPDATE), CODECHAL_CACHELINE_SIZE);
621     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
622                                                   &m_resDmemBuffer,
623                                                   m_dmemBufferSize,
624                                                   "DmemBuffer"),
625         "Failed to allocate Dmem Buffer.");
626 
627     // VP9 Interprobs save buffer
628     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
629                                                   &m_resInterProbSaveBuffer,
630                                                   MOS_ALIGN_CEIL(CODECHAL_VP9_INTER_PROB_SIZE, CODECHAL_PAGE_SIZE),
631                                                   "VP9InterProbsSaveBuffer"),
632         "Failed to allocate VP9 inter probability save Buffer.");
633 
634     // VP9 shared buffer with HuC FW, mapping to region 15
635     CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
636                                                   &m_resHucSharedBuffer,
637                                                   MOS_ALIGN_CEIL(CODEC_VP9_PROB_MAX_NUM_ELEM, CODECHAL_PAGE_SIZE),
638                                                   "VP9HucSharedBuffer"),
639         "Failed to allocate VP9 Huc shared Buffer.");
640 
641     return eStatus;
642 }
643 
AllocateResourcesVariableSizes()644 MOS_STATUS CodechalDecodeVp9 :: AllocateResourcesVariableSizes()
645 {
646     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
647 
648     CODECHAL_DECODE_FUNCTION_ENTER;
649 
650     uint32_t widthInSb   = MOS_ROUNDUP_DIVIDE(m_width, CODEC_VP9_SUPER_BLOCK_WIDTH);
651     uint32_t heightInSb  = MOS_ROUNDUP_DIVIDE(m_height, CODEC_VP9_SUPER_BLOCK_HEIGHT);
652     uint8_t  maxBitDepth  = 8 + m_vp9DepthIndicator * 2;
653     uint8_t  chromaFormat = m_chromaFormatinProfile;
654 
655     MHW_VDBOX_HCP_BUFFER_SIZE_PARAMS    hcpBufSizeParam;
656     MOS_ZeroMemory(&hcpBufSizeParam, sizeof(hcpBufSizeParam));
657     hcpBufSizeParam.ucMaxBitDepth  = maxBitDepth;
658     hcpBufSizeParam.ucChromaFormat = chromaFormat;
659     hcpBufSizeParam.dwPicWidth     = widthInSb;
660     hcpBufSizeParam.dwPicHeight    = heightInSb;
661 
662     MHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam;
663     MOS_ZeroMemory(&reallocParam, sizeof(reallocParam));
664     reallocParam.ucMaxBitDepth      = maxBitDepth;
665     reallocParam.ucChromaFormat     = chromaFormat;
666     reallocParam.dwPicWidth         = widthInSb;
667     reallocParam.dwPicWidthAlloced  = m_allocatedWidthInSb;
668     reallocParam.dwPicHeight        = heightInSb;
669     reallocParam.dwPicHeightAlloced = m_allocatedHeightInSb;
670 
671     if (!m_hcpInterface->IsVp9DfRowstoreCacheEnabled())
672     {
673         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
674             MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_LINE,
675             &reallocParam));
676         if (reallocParam.bNeedBiggerSize ||
677             Mos_ResourceIsNull(&m_resDeblockingFilterLineRowStoreScratchBuffer))
678         {
679             if (!Mos_ResourceIsNull(&m_resDeblockingFilterLineRowStoreScratchBuffer))
680             {
681                 m_osInterface->pfnFreeResource(
682                     m_osInterface,
683                     &m_resDeblockingFilterLineRowStoreScratchBuffer);
684             }
685 
686             // Deblocking Filter Line Row Store Scratch data surface
687             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
688                 MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_LINE,
689                 &hcpBufSizeParam));
690 
691             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
692                                                           &m_resDeblockingFilterLineRowStoreScratchBuffer,
693                                                           hcpBufSizeParam.dwBufferSize,
694                                                           "DeblockingLineScratchBuffer"),
695                 "Failed to allocate deblocking line scratch Buffer.");
696         }
697     }
698 
699     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
700         MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_LINE,
701         &reallocParam));
702     if (reallocParam.bNeedBiggerSize ||
703         Mos_ResourceIsNull(&m_resDeblockingFilterTileRowStoreScratchBuffer))
704     {
705         if (!Mos_ResourceIsNull(&m_resDeblockingFilterTileRowStoreScratchBuffer))
706         {
707             m_osInterface->pfnFreeResource(
708                 m_osInterface,
709                 &m_resDeblockingFilterTileRowStoreScratchBuffer);
710         }
711 
712         // Deblocking Filter Tile Row Store Scratch data surface
713         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
714             MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_LINE,
715             &hcpBufSizeParam));
716 
717         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
718                                                       &m_resDeblockingFilterTileRowStoreScratchBuffer,
719                                                       hcpBufSizeParam.dwBufferSize,
720                                                       "DeblockingTileScratchBuffer"),
721             "Failed to allocate deblocking tile scratch Buffer.");
722     }
723 
724     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
725         MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_COL,
726         &reallocParam));
727     if (reallocParam.bNeedBiggerSize ||
728         Mos_ResourceIsNull(&m_resDeblockingFilterColumnRowStoreScratchBuffer))
729     {
730         if (!Mos_ResourceIsNull(&m_resDeblockingFilterColumnRowStoreScratchBuffer))
731         {
732             m_osInterface->pfnFreeResource(
733                 m_osInterface,
734                 &m_resDeblockingFilterColumnRowStoreScratchBuffer);
735         }
736         // Deblocking Filter Column Row Store Scratch data surface
737         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
738             MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_COL,
739             &hcpBufSizeParam));
740 
741         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
742                                                       &m_resDeblockingFilterColumnRowStoreScratchBuffer,
743                                                       hcpBufSizeParam.dwBufferSize,
744                                                       "DeblockingColumnScratchBuffer"),
745             "Failed to allocate deblocking column scratch Buffer.");
746     }
747 
748     if (!m_hcpInterface->IsVp9DatRowstoreCacheEnabled())
749     {
750         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
751             MHW_VDBOX_HCP_INTERNAL_BUFFER_META_LINE,
752             &reallocParam));
753         if (reallocParam.bNeedBiggerSize ||
754             Mos_ResourceIsNull(&m_resMetadataLineBuffer))
755         {
756             if (!Mos_ResourceIsNull(&m_resMetadataLineBuffer))
757             {
758                 m_osInterface->pfnFreeResource(
759                     m_osInterface,
760                     &m_resMetadataLineBuffer);
761             }
762 
763             // Metadata Line buffer
764             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
765                 MHW_VDBOX_HCP_INTERNAL_BUFFER_META_LINE,
766                 &hcpBufSizeParam));
767 
768             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
769                                                           &m_resMetadataLineBuffer,
770                                                           hcpBufSizeParam.dwBufferSize,
771                                                           "MetadataLineBuffer"),
772                 "Failed to allocate meta data line Buffer.");
773         }
774     }
775 
776     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
777         MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_LINE,
778         &reallocParam));
779     if (reallocParam.bNeedBiggerSize ||
780         Mos_ResourceIsNull(&m_resMetadataTileLineBuffer))
781     {
782         if (!Mos_ResourceIsNull(&m_resMetadataTileLineBuffer))
783         {
784             m_osInterface->pfnFreeResource(
785                 m_osInterface,
786                 &m_resMetadataTileLineBuffer);
787         }
788         // Metadata Tile Line buffer
789         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
790             MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_LINE,
791             &hcpBufSizeParam));
792 
793         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
794                                                       &m_resMetadataTileLineBuffer,
795                                                       hcpBufSizeParam.dwBufferSize,
796                                                       "MetadataTileLineBuffer"),
797             "Failed to allocate meta data tile line Buffer.");
798     }
799 
800     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
801         MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_COL,
802         &reallocParam));
803     if (reallocParam.bNeedBiggerSize ||
804         Mos_ResourceIsNull(&m_resMetadataTileColumnBuffer))
805     {
806         if (!Mos_ResourceIsNull(&m_resMetadataTileColumnBuffer))
807         {
808             m_osInterface->pfnFreeResource(
809                 m_osInterface,
810                 &m_resMetadataTileColumnBuffer);
811         }
812         // Metadata Tile Column buffer
813         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
814         MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_COL,
815         &hcpBufSizeParam));
816 
817         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
818                                                       &m_resMetadataTileColumnBuffer,
819                                                       hcpBufSizeParam.dwBufferSize,
820                                                       "MetadataTileColumnBuffer"),
821             "Failed to allocate meta data tile column Buffer.");
822     }
823 
824     if (!m_hcpInterface->IsVp9HvdRowstoreCacheEnabled())
825     {
826         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
827             MHW_VDBOX_VP9_INTERNAL_BUFFER_HVD_LINE,
828             &reallocParam));
829         if (reallocParam.bNeedBiggerSize ||
830             Mos_ResourceIsNull(&m_resHvcLineRowstoreBuffer))
831         {
832             if (!Mos_ResourceIsNull(&m_resHvcLineRowstoreBuffer))
833             {
834                 m_osInterface->pfnFreeResource(
835                     m_osInterface,
836                     &m_resHvcLineRowstoreBuffer);
837             }
838 
839             // HVC Line Row Store Buffer
840             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
841                 MHW_VDBOX_VP9_INTERNAL_BUFFER_HVD_LINE,
842                 &hcpBufSizeParam));
843 
844             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
845                                                           &m_resHvcLineRowstoreBuffer,
846                                                           hcpBufSizeParam.dwBufferSize,
847                                                           "HvcLineRowStoreBuffer"),
848                 "Failed to allocate Hvc line row store Buffer.");
849         }
850     }
851 
852     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
853         MHW_VDBOX_VP9_INTERNAL_BUFFER_HVD_TILE,
854         &reallocParam));
855     if (reallocParam.bNeedBiggerSize ||
856         Mos_ResourceIsNull(&m_resHvcTileRowstoreBuffer))
857     {
858         if (!Mos_ResourceIsNull(&m_resHvcTileRowstoreBuffer))
859         {
860             m_osInterface->pfnFreeResource(
861                 m_osInterface,
862                 &m_resHvcTileRowstoreBuffer);
863         }
864         // HVC Tile Row Store Buffer
865         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
866             MHW_VDBOX_VP9_INTERNAL_BUFFER_HVD_TILE,
867             &hcpBufSizeParam));
868 
869         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
870                                                       &m_resHvcTileRowstoreBuffer,
871                                                       hcpBufSizeParam.dwBufferSize,
872                                                       "HvcTileRowStoreBuffer"),
873             "Failed to allocate Hvc tile row store Buffer.");
874     }
875 
876     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
877             MHW_VDBOX_VP9_INTERNAL_BUFFER_SEGMENT_ID,
878             &reallocParam));
879     if (reallocParam.bNeedBiggerSize ||
880         Mos_ResourceIsNull(&m_resVp9SegmentIdBuffer))
881     {
882         if (!Mos_ResourceIsNull(&m_resVp9SegmentIdBuffer))
883         {
884             m_osInterface->pfnFreeResource(
885                 m_osInterface,
886                 &m_resVp9SegmentIdBuffer);
887         }
888         // VP9 Segment ID buffer
889         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
890             MHW_VDBOX_VP9_INTERNAL_BUFFER_SEGMENT_ID,
891             &hcpBufSizeParam));
892 
893         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
894                                                       &m_resVp9SegmentIdBuffer,
895                                                       hcpBufSizeParam.dwBufferSize,
896                                                       "Vp9SegmentIdBuffer"),
897             "Failed to allocate VP9 segment ID Buffer.");
898     }
899 
900     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
901         MHW_VDBOX_VP9_INTERNAL_BUFFER_SEGMENT_ID,
902         &reallocParam));
903     if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resSegmentIdBuffReset))
904     {
905         if (!Mos_ResourceIsNull(&m_resSegmentIdBuffReset))
906         {
907             m_osInterface->pfnFreeResource(
908                 m_osInterface,
909                 &m_resSegmentIdBuffReset);
910         }
911         // VP9 Segment ID Reset buffer
912         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
913             MHW_VDBOX_VP9_INTERNAL_BUFFER_SEGMENT_ID,
914             &hcpBufSizeParam));
915 
916         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
917                                                       &m_resSegmentIdBuffReset,
918                                                       hcpBufSizeParam.dwBufferSize,
919                                                       "SegmentIdBuffreset",
920                                                       true,
921                                                       0),
922             "Failed to allocate segment ID reset Buffer.");
923     }
924 
925     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsVp9BufferReallocNeeded(
926         MHW_VDBOX_HCP_INTERNAL_BUFFER_CURR_MV_TEMPORAL,
927         &reallocParam));
928     if (reallocParam.bNeedBiggerSize || m_mvBufferSize == 0)
929     {
930         for (uint8_t i = 0; i < CODECHAL_VP9_NUM_MV_BUFFERS; i++)
931         {
932             if (!Mos_ResourceIsNull(&m_resVp9MvTemporalBuffer[i]))
933             {
934                 m_osInterface->pfnFreeResource(
935                     m_osInterface,
936                     &m_resVp9MvTemporalBuffer[i]);
937             }
938         }
939 
940         // VP9 MV Temporal buffers
941         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetVp9BufferSize(
942             MHW_VDBOX_HCP_INTERNAL_BUFFER_CURR_MV_TEMPORAL,
943             &hcpBufSizeParam));
944 
945         for (uint8_t i = 0; i < CODECHAL_VP9_NUM_MV_BUFFERS; i++)
946         {
947             CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
948                                                           &m_resVp9MvTemporalBuffer[i],
949                                                           hcpBufSizeParam.dwBufferSize,
950                                                           "MvTemporalBuffer"),
951                 "Failed to allocate Mv temporal Buffer.");
952         }
953 
954         m_mvBufferSize = hcpBufSizeParam.dwBufferSize;
955     }
956 
957     if (m_secureDecoder)
958     {
959         CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AllocateResource(this));
960     }
961 
962     //backup allocated memory size
963     m_allocatedWidthInSb  = widthInSb;
964     m_allocatedHeightInSb = heightInSb;
965 
966     return eStatus;
967 }
968 
InitializeBeginFrame()969 MOS_STATUS CodechalDecodeVp9 :: InitializeBeginFrame()
970 {
971     CODECHAL_DECODE_FUNCTION_ENTER;
972 
973     m_incompletePicture = false;
974     m_copyDataBufferInUse = false;
975     m_copyDataOffset      = 0;
976 
977     return MOS_STATUS_SUCCESS;
978 }
979 
CopyDataSurface()980 MOS_STATUS CodechalDecodeVp9 :: CopyDataSurface()
981 {
982     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
983 
984     CODECHAL_DECODE_FUNCTION_ENTER;
985 
986     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
987         m_osInterface,
988         m_videoContextForWa));
989     m_osInterface->pfnResetOsStates(m_osInterface);
990 
991     m_osInterface->pfnSetPerfTag(
992         m_osInterface,
993         (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE));
994     m_osInterface->pfnResetPerfBufferID(m_osInterface);
995 
996     MOS_COMMAND_BUFFER cmdBuffer;
997     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
998         m_osInterface,
999         &cmdBuffer,
1000         0));
1001 
1002     // Send command buffer header at the beginning (OS dependent)
1003     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1004         &cmdBuffer,
1005         false));
1006 
1007     CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
1008         &cmdBuffer,            // pCmdBuffer
1009         &m_resDataBuffer,      // presSrc
1010         &m_resCopyDataBuffer,  // presDst
1011         m_dataSize,            // u32CopyLength
1012         m_dataOffset,          // u32CopyInputOffset
1013         m_copyDataOffset));    // u32CopyOutputOffset
1014 
1015     m_copyDataOffset += MOS_ALIGN_CEIL(m_dataSize, MHW_CACHELINE_SIZE);
1016 
1017     MHW_MI_FLUSH_DW_PARAMS  flushDwParams;
1018     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1019     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1020         &cmdBuffer,
1021         &flushDwParams));
1022 
1023     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1024         &cmdBuffer,
1025         nullptr));
1026 
1027     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1028 
1029     // sync resource
1030     if (!m_incompletePicture)
1031     {
1032         MOS_SYNC_PARAMS syncParams = g_cInitSyncParams;
1033         syncParams.GpuContext = m_videoContext;
1034         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1035         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
1036 
1037         syncParams = g_cInitSyncParams;
1038         syncParams.GpuContext = m_videoContextForWa;
1039         syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
1040         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
1041     }
1042 
1043     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1044         m_osInterface,
1045         &cmdBuffer,
1046         m_videoContextForWaUsesNullHw));
1047 
1048     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
1049         m_osInterface,
1050         m_videoContext));
1051 
1052     return eStatus;
1053 }
1054 
CheckAndCopyBitStream()1055 MOS_STATUS CodechalDecodeVp9 :: CheckAndCopyBitStream()
1056 {
1057     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1058 
1059     CODECHAL_DECODE_FUNCTION_ENTER;
1060 
1061     uint32_t badSliceChopping = 0;
1062     // No pVp9SliceParams is set from APP.
1063     if (m_vp9SliceParams == nullptr)
1064     {
1065         badSliceChopping = 0;
1066     }
1067     else
1068     {
1069         badSliceChopping = m_vp9SliceParams->wBadSliceChopping;
1070     }
1071 
1072     // No BSBytesInBuffer is sent from App, driver here just give an estimation.
1073     if (badSliceChopping != 0)
1074     {
1075         m_vp9PicParams->BSBytesInBuffer =
1076             (m_vp9PicParams->FrameWidthMinus1 + 1) * (m_vp9PicParams->FrameHeightMinus1 + 1) * 6;
1077     }
1078 
1079     if (IsFirstExecuteCall()) // first exec call
1080     {
1081         if (m_dataSize < m_vp9PicParams->BSBytesInBuffer)  // Current bitstream buffer is not big enough
1082         {
1083             // Allocate or reallocate the copy data buffer.
1084             if (m_copyDataBufferSize < MOS_ALIGN_CEIL(m_vp9PicParams->BSBytesInBuffer, 64))
1085             {
1086                 if (!Mos_ResourceIsNull(&m_resCopyDataBuffer))
1087                 {
1088                     m_osInterface->pfnFreeResource(
1089                         m_osInterface,
1090                         &m_resCopyDataBuffer);
1091                 }
1092 
1093                 m_copyDataBufferSize = MOS_ALIGN_CEIL(m_vp9PicParams->BSBytesInBuffer, 64);
1094 
1095                 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
1096                                                               &m_resCopyDataBuffer,
1097                                                               m_copyDataBufferSize,
1098                                                               "Vp9CopyDataBuffer"),
1099                     "Failed to allocate Vp9 copy data Buffer.");
1100             }
1101 
1102             // Copy bitstream into the copy buffer
1103             if (m_dataSize)
1104             {
1105                 CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface());
1106 
1107                 m_copyDataBufferInUse = true;
1108             }
1109 
1110             m_incompletePicture = true;
1111         }
1112     }
1113     else // second and later exec calls
1114     {
1115         CODECHAL_DECODE_CHK_COND_RETURN(
1116             (m_copyDataOffset + m_dataSize > m_copyDataBufferSize),
1117             "Bitstream size exceeds copy data buffer size!");
1118 
1119         // Copy bitstream into the copy buffer
1120         if (m_dataSize)
1121         {
1122             CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface());
1123         }
1124 
1125         if (m_copyDataOffset >= m_vp9PicParams->BSBytesInBuffer || badSliceChopping == 2)
1126         {
1127             m_incompletePicture = false;
1128         }
1129     }
1130 
1131     return eStatus;
1132 }
InitializeDecodeMode()1133 MOS_STATUS CodechalDecodeVp9 :: InitializeDecodeMode ()
1134 {
1135     //do nothing for VP9 Base class. will be overloaded by inherited class to support dynamic mode switch
1136     return MOS_STATUS_SUCCESS;
1137 }
1138 
InitSfcState()1139 MOS_STATUS CodechalDecodeVp9::InitSfcState()
1140 {
1141     // Default no SFC support
1142     return MOS_STATUS_SUCCESS;
1143 }
1144 
SetFrameStates()1145 MOS_STATUS CodechalDecodeVp9::SetFrameStates ()
1146 {
1147     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1148 
1149     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
1150     CODECHAL_DECODE_FUNCTION_ENTER;
1151 
1152     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface);
1153     CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer);
1154 
1155     m_dataSize         = m_decodeParams.m_dataSize;
1156     m_dataOffset       = m_decodeParams.m_dataOffset;
1157     m_vp9PicParams     = (PCODEC_VP9_PIC_PARAMS)m_decodeParams.m_picParams;
1158     m_vp9SegmentParams = (PCODEC_VP9_SEGMENT_PARAMS)m_decodeParams.m_iqMatrixBuffer;
1159     m_vp9SliceParams   = (PCODEC_VP9_SLICE_PARAMS)m_decodeParams.m_sliceParams;
1160 
1161     CODECHAL_DECODE_CHK_NULL_RETURN(m_vp9SegmentParams);
1162 
1163     m_destSurface   = *(m_decodeParams.m_destSurface);
1164     m_resDataBuffer = *(m_decodeParams.m_dataBuffer);
1165     if (m_decodeParams.m_coefProbBuffer)        // This is an optional buffer passed from App. To be removed once VP9 FF Decode Driver is mature.
1166     {
1167         m_resCoefProbBuffer = *(m_decodeParams.m_coefProbBuffer);
1168     }
1169 
1170     if (IsFirstExecuteCall())
1171     {
1172         CODECHAL_DECODE_CHK_STATUS_RETURN(InitializeBeginFrame());
1173     }
1174 
1175     CODECHAL_DECODE_CHK_STATUS_RETURN(CheckAndCopyBitStream());
1176 
1177     m_cencBuf = m_decodeParams.m_cencBuf;
1178 
1179     // Bitstream is incomplete, don't do any decoding work.
1180     if (m_incompletePicture)
1181     {
1182         eStatus = MOS_STATUS_SUCCESS;
1183         return eStatus;
1184     }
1185 
1186     CODECHAL_DEBUG_TOOL(
1187         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1188             m_copyDataBufferInUse ? &m_resCopyDataBuffer : &m_resDataBuffer,
1189             CodechalDbgAttr::attrBitstream,
1190             "_DEC",
1191             m_copyDataBufferInUse ? m_copyDataBufferSize : m_dataSize,
1192             m_copyDataBufferInUse ? 0 : m_dataOffset,
1193             CODECHAL_NUM_MEDIA_STATES));)
1194 
1195     m_statusReportFeedbackNumber = m_vp9PicParams->StatusReportFeedbackNumber;
1196     m_width =
1197         MOS_MAX(m_width, (uint32_t)(m_vp9PicParams->FrameWidthMinus1 + 1));
1198     m_height =
1199         MOS_MAX(m_height, (uint32_t)(m_vp9PicParams->FrameHeightMinus1 + 1));
1200     m_usFrameWidthAlignedMinBlk =
1201         MOS_ALIGN_CEIL(m_vp9PicParams->FrameWidthMinus1 + 1, CODEC_VP9_MIN_BLOCK_WIDTH);
1202     m_usFrameHeightAlignedMinBlk =
1203         MOS_ALIGN_CEIL(m_vp9PicParams->FrameHeightMinus1 + 1, CODEC_VP9_MIN_BLOCK_WIDTH);
1204 
1205     // Overwrite the actual surface height with the coded height and width of the frame
1206     // for VP9 since it's possible for a VP9 frame to change size during playback
1207     m_destSurface.dwWidth  = m_vp9PicParams->FrameWidthMinus1 + 1;
1208     m_destSurface.dwHeight = m_vp9PicParams->FrameHeightMinus1 + 1;
1209 
1210     PCODEC_REF_LIST destEntry = m_vp9RefList[m_vp9PicParams->CurrPic.FrameIdx];
1211 
1212     // Clear FilterLevel Array inside segment data when filter_level inside picparam is zero
1213     if (m_cencBuf == nullptr)
1214     {
1215         MOS_ZeroMemory(destEntry, sizeof(CODEC_REF_LIST));
1216         // Clear FilterLevel Array inside segment data when filter_level inside picparam is zero
1217         if ((!m_vp9PicParams->filter_level))
1218         {
1219             PCODEC_VP9_SEG_PARAMS vp9SegData = &m_vp9SegmentParams->SegData[0];
1220 
1221             for (uint8_t i = 0; i < 8; i++)
1222             {
1223                 *((uint32_t *)&vp9SegData->FilterLevel[0][0]) = 0;
1224                 *((uint32_t *)&vp9SegData->FilterLevel[2][0]) = 0;
1225                 vp9SegData++;      // Go on to next record.
1226             }
1227         }
1228     }
1229     destEntry->resRefPic     = m_destSurface.OsResource;
1230     destEntry->dwFrameWidth  = m_vp9PicParams->FrameWidthMinus1 + 1;
1231     destEntry->dwFrameHeight = m_vp9PicParams->FrameHeightMinus1 + 1;
1232 
1233     if (m_hcpInterface->IsRowStoreCachingSupported() &&
1234         m_usFrameWidthAlignedMinBlk != MOS_ALIGN_CEIL(m_prevFrmWidth, CODEC_VP9_MIN_BLOCK_WIDTH))
1235     {
1236         MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
1237         uint8_t usChromaSamplingFormat;
1238         if (m_vp9PicParams->subsampling_x == 1 && m_vp9PicParams->subsampling_y == 1)
1239         {
1240             usChromaSamplingFormat = HCP_CHROMA_FORMAT_YUV420;
1241         }
1242         else if (m_vp9PicParams->subsampling_x == 0 && m_vp9PicParams->subsampling_y == 0)
1243         {
1244             usChromaSamplingFormat = HCP_CHROMA_FORMAT_YUV444;
1245         }
1246         else
1247         {
1248             CODECHAL_DECODE_ASSERTMESSAGE("Invalid Chroma sampling format!");
1249             eStatus = MOS_STATUS_INVALID_PARAMETER;
1250             return eStatus;
1251         }
1252         MOS_ZeroMemory(&rowstoreParams, sizeof(rowstoreParams));
1253         rowstoreParams.dwPicWidth       = m_usFrameWidthAlignedMinBlk;
1254         rowstoreParams.bMbaff       = false;
1255         rowstoreParams.Mode         = CODECHAL_DECODE_MODE_VP9VLD;
1256         rowstoreParams.ucBitDepthMinus8 = m_vp9PicParams->BitDepthMinus8;
1257         rowstoreParams.ucChromaFormat   = usChromaSamplingFormat;
1258         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams));
1259     }
1260 
1261     CODECHAL_DECODE_CHK_STATUS_RETURN(InitializeDecodeMode());
1262     CODECHAL_DECODE_CHK_STATUS_RETURN(InitSfcState());
1263 
1264     // Allocate internal buffer or reallocate When current resolution is bigger than allocated internal buffer size
1265     CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesVariableSizes());
1266 
1267     CODECHAL_DECODE_CHK_STATUS_RETURN(DetermineInternalBufferUpdate());
1268 
1269     m_hcpDecPhase = CodechalHcpDecodePhaseInitialized;
1270 
1271     m_perfType = m_vp9PicParams->PicFlags.fields.frame_type ? P_TYPE : I_TYPE;
1272 
1273     m_crrPic = m_vp9PicParams->CurrPic;
1274 
1275     if (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_INTER_FRAME &&
1276         !m_vp9PicParams->PicFlags.fields.intra_only)
1277     {
1278         m_curMvTempBufIdx = (m_curMvTempBufIdx + 1) % CODECHAL_VP9_NUM_MV_BUFFERS;
1279         m_colMvTempBufIdx = (m_curMvTempBufIdx < 1) ? (CODECHAL_VP9_NUM_MV_BUFFERS - 1) : (m_curMvTempBufIdx - 1);
1280     }
1281 
1282     CODECHAL_DEBUG_TOOL(
1283         CODECHAL_DECODE_CHK_NULL_RETURN(m_debugInterface);
1284         m_vp9PicParams->CurrPic.PicFlags = PICTURE_FRAME;
1285         m_debugInterface->m_currPic      = m_crrPic;
1286         m_debugInterface->m_frameType    = m_perfType;
1287 
1288         CODECHAL_DECODE_CHK_STATUS_RETURN(DumpDecodePicParams(
1289             m_vp9PicParams));
1290 
1291         if (m_vp9SegmentParams) {
1292             CODECHAL_DECODE_CHK_STATUS_RETURN(DumpDecodeSegmentParams(
1293                 m_vp9SegmentParams));
1294         })
1295 
1296     return eStatus;
1297 }
1298 
DetermineDecodePhase()1299 MOS_STATUS CodechalDecodeVp9 :: DetermineDecodePhase()
1300 {
1301     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1302 
1303     CODECHAL_DECODE_FUNCTION_ENTER;
1304 
1305     uint32_t curPhase = m_hcpDecPhase;
1306     switch (curPhase)
1307     {
1308     case CodechalHcpDecodePhaseInitialized:
1309         m_hcpDecPhase = CodechalHcpDecodePhaseLegacyLong;
1310         break;
1311     default:
1312         eStatus = MOS_STATUS_INVALID_PARAMETER;
1313         CODECHAL_DECODE_ASSERTMESSAGE("invalid decode phase.");
1314         return eStatus;
1315     }
1316 
1317     return eStatus;
1318 }
1319 
InitPicStateMhwParams()1320 MOS_STATUS CodechalDecodeVp9 :: InitPicStateMhwParams()
1321 {
1322     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1323     PMOS_RESOURCE usedDummyReference = nullptr;
1324 
1325     CODECHAL_DECODE_FUNCTION_ENTER;
1326 
1327     // Reset all pic Mhw Params
1328     *m_picMhwParams.PipeModeSelectParams = {};
1329     *m_picMhwParams.PipeBufAddrParams = {};
1330     MOS_ZeroMemory(m_picMhwParams.IndObjBaseAddrParams, sizeof(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS));
1331     MOS_ZeroMemory(m_picMhwParams.Vp9PicState, sizeof(MHW_VDBOX_VP9_PIC_STATE));
1332     MOS_ZeroMemory(m_picMhwParams.Vp9SegmentState, sizeof(MHW_VDBOX_VP9_SEGMENT_STATE));
1333 
1334     PCODEC_PICTURE refFrameList      = &(m_vp9PicParams->RefFrameList[0]);
1335     uint8_t        lastRefPicIndex   = m_vp9PicParams->PicFlags.fields.LastRefIdx;
1336     uint8_t        goldenRefPicIndex = m_vp9PicParams->PicFlags.fields.GoldenRefIdx;
1337     uint8_t        altRefPicIndex    = m_vp9PicParams->PicFlags.fields.AltRefIdx;
1338     if (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME ||
1339         m_vp9PicParams->PicFlags.fields.intra_only)
1340     {
1341         // reference surface should be nullptr when key_frame == true or intra only frame
1342         m_presLastRefSurface   = nullptr;
1343         m_presGoldenRefSurface = nullptr;
1344         m_presAltRefSurface    = nullptr;
1345     }
1346     else
1347     {
1348         if (lastRefPicIndex > 7 || goldenRefPicIndex > 7 || altRefPicIndex > 7)
1349         {
1350             CODECHAL_DECODE_ASSERTMESSAGE("invalid ref index (should be in [0,7]) in pic parameter!");
1351             eStatus = MOS_STATUS_INVALID_PARAMETER;
1352             return eStatus;
1353         }
1354 
1355         if (refFrameList[lastRefPicIndex].FrameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9)
1356         {
1357             refFrameList[lastRefPicIndex].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9 - 1;
1358         }
1359         if (refFrameList[goldenRefPicIndex].FrameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9)
1360         {
1361             refFrameList[goldenRefPicIndex].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9 - 1;
1362         }
1363         if (refFrameList[altRefPicIndex].FrameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9)
1364         {
1365             refFrameList[altRefPicIndex].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9 - 1;
1366         }
1367         PCODEC_REF_LIST *vp9RefList = &(m_vp9RefList[0]);
1368         m_presLastRefSurface        = &(vp9RefList[refFrameList[lastRefPicIndex].FrameIdx]->resRefPic);
1369         m_presGoldenRefSurface      = &(vp9RefList[refFrameList[goldenRefPicIndex].FrameIdx]->resRefPic);
1370         m_presAltRefSurface         = &(vp9RefList[refFrameList[altRefPicIndex].FrameIdx]->resRefPic);
1371     }
1372 
1373     uint16_t usChromaSamplingFormat;
1374     if (m_vp9PicParams->subsampling_x == 1 && m_vp9PicParams->subsampling_y == 1)
1375     {
1376         usChromaSamplingFormat = HCP_CHROMA_FORMAT_YUV420;
1377     }
1378     else if (m_vp9PicParams->subsampling_x == 0 && m_vp9PicParams->subsampling_y == 0)
1379     {
1380         usChromaSamplingFormat = HCP_CHROMA_FORMAT_YUV444;
1381     }
1382     else
1383     {
1384         CODECHAL_DECODE_ASSERTMESSAGE("Invalid Chroma sampling format!");
1385         eStatus = MOS_STATUS_INVALID_PARAMETER;
1386         return eStatus;
1387     }
1388 
1389     m_picMhwParams.PipeModeSelectParams->Mode                  = m_mode;
1390     m_picMhwParams.PipeModeSelectParams->bStreamOutEnabled     = m_streamOutEnabled;
1391 
1392     // Populate surface param for decoded picture
1393     m_picMhwParams.SurfaceParams[0]->Mode               = m_mode;
1394     m_picMhwParams.SurfaceParams[0]->psSurface              = &m_destSurface;
1395     m_picMhwParams.SurfaceParams[0]->ChromaType         = (uint8_t)usChromaSamplingFormat;
1396     m_picMhwParams.SurfaceParams[0]->ucSurfaceStateId   = CODECHAL_HCP_DECODED_SURFACE_ID;
1397     m_picMhwParams.SurfaceParams[0]->ucBitDepthLumaMinus8   = m_vp9PicParams->BitDepthMinus8;
1398     m_picMhwParams.SurfaceParams[0]->ucBitDepthChromaMinus8 = m_vp9PicParams->BitDepthMinus8;
1399     m_picMhwParams.SurfaceParams[0]->dwUVPlaneAlignment = 8;
1400 
1401     if (MEDIA_IS_WA(m_waTable, WaDummyReference) &&
1402         !Mos_ResourceIsNull(&m_dummyReference.OsResource))
1403     {
1404         usedDummyReference = &m_dummyReference.OsResource;
1405     }
1406     else
1407     {
1408         usedDummyReference = &m_destSurface.OsResource;
1409     }
1410 
1411     // Populate surface param for reference pictures
1412     if (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_INTER_FRAME &&
1413         !m_vp9PicParams->PicFlags.fields.intra_only &&
1414         m_presLastRefSurface != nullptr &&
1415         m_presGoldenRefSurface != nullptr &&
1416         m_presAltRefSurface != nullptr)
1417     {
1418         if (Mos_ResourceIsNull(m_presLastRefSurface))
1419         {
1420             m_presLastRefSurface = usedDummyReference;
1421         }
1422         if (Mos_ResourceIsNull(m_presGoldenRefSurface))
1423         {
1424             m_presGoldenRefSurface = usedDummyReference;
1425         }
1426         if (Mos_ResourceIsNull(m_presAltRefSurface))
1427         {
1428             m_presAltRefSurface = usedDummyReference;
1429         }
1430 
1431         //MOS_SURFACE lastRefSurface;
1432         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
1433             &m_lastRefSurface.OsResource,
1434             sizeof(MOS_RESOURCE),
1435             m_presLastRefSurface,
1436             sizeof(MOS_RESOURCE)));
1437         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1438             m_osInterface,
1439             &m_lastRefSurface));
1440 
1441         //MOS_SURFACE goldenRefSurface;
1442         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
1443             &m_goldenRefSurface.OsResource,
1444             sizeof(MOS_RESOURCE),
1445             m_presGoldenRefSurface,
1446             sizeof(MOS_RESOURCE)));
1447         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1448             m_osInterface,
1449             &m_goldenRefSurface));
1450 
1451         //MOS_SURFACE altRefSurface;
1452         CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
1453             &m_altRefSurface.OsResource,
1454             sizeof(MOS_RESOURCE),
1455             m_presAltRefSurface,
1456             sizeof(MOS_RESOURCE)));
1457         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1458             m_osInterface,
1459             &m_altRefSurface));
1460 
1461         for (uint8_t i = 1; i < 4; i++)
1462         {
1463             m_picMhwParams.SurfaceParams[i]->Mode               = m_mode;
1464             m_picMhwParams.SurfaceParams[i]->ChromaType         = (uint8_t)usChromaSamplingFormat;
1465             m_picMhwParams.SurfaceParams[i]->dwUVPlaneAlignment = 8;
1466 
1467             switch (i)
1468             {
1469                 case 1:
1470                     m_picMhwParams.SurfaceParams[i]->psSurface          = &m_lastRefSurface;
1471                     m_picMhwParams.SurfaceParams[i]->ucSurfaceStateId   = CODECHAL_HCP_LAST_SURFACE_ID;
1472                     break;
1473                 case 2:
1474                     m_picMhwParams.SurfaceParams[i]->psSurface          = &m_goldenRefSurface;
1475                     m_picMhwParams.SurfaceParams[i]->ucSurfaceStateId   = CODECHAL_HCP_GOLDEN_SURFACE_ID;
1476                     break;
1477                 case 3:
1478                     m_picMhwParams.SurfaceParams[i]->psSurface          = &m_altRefSurface;
1479                     m_picMhwParams.SurfaceParams[i]->ucSurfaceStateId   = CODECHAL_HCP_ALTREF_SURFACE_ID;
1480                     break;
1481             }
1482         }
1483     }
1484 
1485     m_picMhwParams.PipeBufAddrParams->Mode                                          = m_mode;
1486     m_picMhwParams.PipeBufAddrParams->psPreDeblockSurface                           = &m_destSurface;
1487 
1488     m_picMhwParams.PipeBufAddrParams->presReferences[CodechalDecodeLastRef]      = m_presLastRefSurface;
1489     m_picMhwParams.PipeBufAddrParams->presReferences[CodechalDecodeGoldenRef]    = m_presGoldenRefSurface;
1490     m_picMhwParams.PipeBufAddrParams->presReferences[CodechalDecodeAlternateRef] = m_presAltRefSurface;
1491 
1492     // set all ref pic addresses in HCP_PIPE_BUF_ADDR_STATE command to valid addresses for error concealment purpose, set the unused ones to the first used one
1493     for (uint8_t i = 0; i < CODECHAL_DECODE_VP9_MAX_NUM_REF_FRAME; i++)
1494     {
1495         if (!m_picMhwParams.PipeBufAddrParams->presReferences[i])
1496         {
1497             m_picMhwParams.PipeBufAddrParams->presReferences[i] = usedDummyReference;
1498         }
1499     }
1500 
1501 #ifdef _MMC_SUPPORTED
1502     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(m_picMhwParams.PipeBufAddrParams));
1503 #endif
1504 
1505     if (m_streamOutEnabled)
1506     {
1507         m_picMhwParams.PipeBufAddrParams->presStreamOutBuffer =
1508             &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
1509     }
1510 
1511 #ifdef _MMC_SUPPORTED
1512     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(m_picMhwParams.PipeBufAddrParams));
1513 
1514     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
1515 #endif
1516 
1517     m_picMhwParams.PipeBufAddrParams->presMfdDeblockingFilterRowStoreScratchBuffer =
1518         &m_resDeblockingFilterLineRowStoreScratchBuffer;
1519     m_picMhwParams.PipeBufAddrParams->presDeblockingFilterTileRowStoreScratchBuffer =
1520         &m_resDeblockingFilterTileRowStoreScratchBuffer;
1521     m_picMhwParams.PipeBufAddrParams->presDeblockingFilterColumnRowStoreScratchBuffer =
1522         &m_resDeblockingFilterColumnRowStoreScratchBuffer;
1523 
1524     m_picMhwParams.PipeBufAddrParams->presMetadataLineBuffer       = &m_resMetadataLineBuffer;
1525     m_picMhwParams.PipeBufAddrParams->presMetadataTileLineBuffer   = &m_resMetadataTileLineBuffer;
1526     m_picMhwParams.PipeBufAddrParams->presMetadataTileColumnBuffer = &m_resMetadataTileColumnBuffer;
1527     m_picMhwParams.PipeBufAddrParams->presVp9ProbBuffer            = &m_resVp9ProbBuffer[m_frameCtxIdx];
1528     m_picMhwParams.PipeBufAddrParams->presVp9SegmentIdBuffer       = &m_resVp9SegmentIdBuffer;
1529     m_picMhwParams.PipeBufAddrParams->presHvdLineRowStoreBuffer    = &m_resHvcLineRowstoreBuffer;
1530     m_picMhwParams.PipeBufAddrParams->presHvdTileRowStoreBuffer    = &m_resHvcTileRowstoreBuffer;
1531 
1532     if (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_INTER_FRAME &&
1533         !m_vp9PicParams->PicFlags.fields.intra_only)
1534     {
1535         m_picMhwParams.PipeBufAddrParams->presCurMvTempBuffer = &m_resVp9MvTemporalBuffer[m_curMvTempBufIdx];
1536 
1537         if (!m_prevFrameParams.fields.KeyFrame && !m_prevFrameParams.fields.IntraOnly)
1538         {
1539             // For VP9, only index 0 is required to be filled
1540             m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[0] = &m_resVp9MvTemporalBuffer[m_colMvTempBufIdx];
1541         }
1542     }
1543 
1544     m_picMhwParams.IndObjBaseAddrParams->Mode           = m_mode;
1545     m_picMhwParams.IndObjBaseAddrParams->dwDataSize     = m_copyDataBufferInUse ? m_copyDataBufferSize : m_dataSize;
1546     m_picMhwParams.IndObjBaseAddrParams->dwDataOffset   = m_copyDataBufferInUse ? 0 : m_dataOffset;
1547     m_picMhwParams.IndObjBaseAddrParams->presDataBuffer = m_copyDataBufferInUse ? &m_resCopyDataBuffer : &m_resDataBuffer;
1548 
1549     if (m_secureDecoder)
1550     {
1551         CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->SetBitstreamBuffer(m_picMhwParams.IndObjBaseAddrParams));
1552     }
1553 
1554     m_picMhwParams.Vp9PicState->pVp9PicParams         = m_vp9PicParams;
1555     m_picMhwParams.Vp9PicState->ppVp9RefList          = &(m_vp9RefList[0]);
1556     m_picMhwParams.Vp9PicState->PrevFrameParams.value = m_prevFrameParams.value;
1557     m_picMhwParams.Vp9PicState->dwPrevFrmWidth        = m_prevFrmWidth;
1558     m_picMhwParams.Vp9PicState->dwPrevFrmHeight       = m_prevFrmHeight;
1559 
1560     m_prevFrameParams.fields.KeyFrame  = !m_vp9PicParams->PicFlags.fields.frame_type;
1561     m_prevFrameParams.fields.IntraOnly = m_vp9PicParams->PicFlags.fields.intra_only;
1562     m_prevFrameParams.fields.Display   = m_vp9PicParams->PicFlags.fields.show_frame;
1563     m_prevFrmWidth                     = m_vp9PicParams->FrameWidthMinus1 + 1;
1564     m_prevFrmHeight                    = m_vp9PicParams->FrameHeightMinus1 + 1;
1565 
1566     m_picMhwParams.Vp9SegmentState->Mode                = m_mode;
1567     m_picMhwParams.Vp9SegmentState->pVp9SegmentParams   = m_vp9SegmentParams;
1568 
1569     return eStatus;
1570 }
1571 
AddPicStateMhwCmds(PMOS_COMMAND_BUFFER cmdBuffer)1572 MOS_STATUS CodechalDecodeVp9 :: AddPicStateMhwCmds(
1573     PMOS_COMMAND_BUFFER       cmdBuffer)
1574 {
1575     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1576 
1577     CODECHAL_DECODE_FUNCTION_ENTER;
1578 
1579     CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
1580 
1581     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeModeSelectCmd(
1582         cmdBuffer,
1583         m_picMhwParams.PipeModeSelectParams));
1584 
1585     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(
1586         cmdBuffer,
1587         m_picMhwParams.SurfaceParams[0]));
1588 
1589     // For non-key frame, send extra surface commands for reference pictures
1590     if (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_INTER_FRAME &&
1591         !m_vp9PicParams->PicFlags.fields.intra_only)
1592     {
1593         for (uint8_t i = 1; i < 4; i++)
1594         {
1595             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(
1596                 cmdBuffer,
1597                 m_picMhwParams.SurfaceParams[i]));
1598         }
1599     }
1600 
1601     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeBufAddrCmd(
1602         cmdBuffer,
1603         m_picMhwParams.PipeBufAddrParams));
1604 
1605     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpIndObjBaseAddrCmd(
1606         cmdBuffer,
1607         m_picMhwParams.IndObjBaseAddrParams));
1608 
1609     if (m_cencBuf)
1610     {
1611         CODECHAL_DECODE_CHK_STATUS_RETURN(SetCencBatchBuffer(cmdBuffer));
1612     }
1613     else
1614     {
1615         for (uint8_t i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++)
1616         {
1617             // Error handling for illegal programming on segmentation fields @ KEY/INTRA_ONLY frames
1618             PCODEC_VP9_SEG_PARAMS vp9SegData = &(m_picMhwParams.Vp9SegmentState->pVp9SegmentParams->SegData[i]);
1619             if (vp9SegData->SegmentFlags.fields.SegmentReferenceEnabled &&
1620                 (!m_vp9PicParams->PicFlags.fields.frame_type || m_vp9PicParams->PicFlags.fields.intra_only))
1621             {
1622                 vp9SegData->SegmentFlags.fields.SegmentReference = CODECHAL_DECODE_VP9_INTRA_FRAME;
1623             }
1624 
1625             m_picMhwParams.Vp9SegmentState->ucCurrentSegmentId = i;
1626             CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpVp9SegmentStateCmd(
1627                 cmdBuffer,
1628                 nullptr,
1629                 m_picMhwParams.Vp9SegmentState));
1630 
1631             if (m_vp9PicParams->PicFlags.fields.segmentation_enabled == 0)
1632             {
1633                 break;
1634             }
1635         }
1636 
1637         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpVp9PicStateCmd(
1638             cmdBuffer,
1639             nullptr,
1640             m_picMhwParams.Vp9PicState));
1641 
1642         if (m_secureDecoder)
1643         {
1644             CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AddHcpSecureState(
1645                 cmdBuffer,
1646                 this));
1647         }
1648     }
1649     return eStatus;
1650 }
1651 
UpdatePicStateBuffers(PMOS_COMMAND_BUFFER cmdBuffe)1652 MOS_STATUS CodechalDecodeVp9 :: UpdatePicStateBuffers(
1653     PMOS_COMMAND_BUFFER       cmdBuffe)
1654 {
1655     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1656 
1657     CODECHAL_DECODE_FUNCTION_ENTER;
1658 
1659     if (m_resetSegIdBuffer)
1660     {
1661         if (m_osInterface->osCpInterface->IsHMEnabled())
1662         {
1663             if (m_secureDecoder)
1664             {
1665                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->ResetVP9SegIdBufferWithHuc(this, cmdBuffe));
1666             }
1667         }
1668         else
1669         {
1670             CODECHAL_DECODE_CHK_STATUS_RETURN(ResetSegIdBufferwithDrv());
1671         }
1672     }
1673 
1674     if (m_osInterface->osCpInterface->IsHMEnabled())
1675     {
1676         if (m_secureDecoder)
1677         {
1678             CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->UpdateVP9ProbBufferWithHuc(m_fullProbBufferUpdate, this, cmdBuffe));
1679         }
1680     }
1681     else
1682     {
1683         if (m_fullProbBufferUpdate)
1684         {
1685             CODECHAL_DECODE_CHK_STATUS_RETURN(ProbBufFullUpdatewithDrv());
1686         }
1687         else
1688         {
1689             CODECHAL_DECODE_CHK_STATUS_RETURN(ProbBufferPartialUpdatewithDrv());
1690         }
1691     }
1692 
1693     CODECHAL_DEBUG_TOOL(
1694         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1695             &m_resVp9SegmentIdBuffer,
1696             CodechalDbgAttr::attrSegId,
1697             "SegId_beforeHCP",
1698             (m_allocatedWidthInSb * m_allocatedHeightInSb * CODECHAL_CACHELINE_SIZE)));
1699         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1700             &(m_resVp9ProbBuffer[m_frameCtxIdx]),
1701             CodechalDbgAttr::attrCoefProb,
1702             "PakHwCoeffProbs_beforeHCP",
1703             CODEC_VP9_PROB_MAX_NUM_ELEM));)
1704 
1705     return eStatus;
1706 }
1707 
DecodeStateLevel()1708 MOS_STATUS CodechalDecodeVp9 :: DecodeStateLevel()
1709 {
1710     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1711 
1712     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
1713     CODECHAL_DECODE_FUNCTION_ENTER;
1714 
1715     if (m_secureDecoder && m_hcpDecPhase == CodechalHcpDecodePhaseInitialized)
1716     {
1717         CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->Execute(this));
1718     }
1719 
1720     //HCP Decode Phase State Machine
1721     DetermineDecodePhase();
1722 
1723     MOS_COMMAND_BUFFER cmdBuffer;
1724     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
1725         m_osInterface,
1726         &cmdBuffer,
1727         0));
1728 
1729     auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
1730     HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
1731 
1732     //Frame tracking functionality is called at the start of a command buffer.
1733     //Called at FE decode phase, since BE decode phase will only construct BE batch buffers.
1734     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1735         &cmdBuffer, true));
1736 
1737     CODECHAL_DECODE_CHK_STATUS_RETURN(InitPicStateMhwParams());
1738 
1739     CODECHAL_DECODE_CHK_STATUS_RETURN(UpdatePicStateBuffers(&cmdBuffer));
1740 
1741     if (m_statusQueryReportingEnabled)
1742     {
1743         CODECHAL_DECODE_CHK_STATUS_RETURN(
1744             StartStatusReport(&cmdBuffer));
1745     }
1746 
1747     CODECHAL_DECODE_CHK_STATUS_RETURN(AddPicStateMhwCmds(
1748         &cmdBuffer));
1749     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1750 
1751     return eStatus;
1752 }
1753 
DecodePrimitiveLevel()1754 MOS_STATUS CodechalDecodeVp9 :: DecodePrimitiveLevel()
1755 {
1756     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1757 
1758     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
1759 
1760     CODECHAL_DECODE_FUNCTION_ENTER;
1761 
1762     // Bitstream is incomplete, don't do any decoding work.
1763     if (m_incompletePicture)
1764     {
1765         eStatus = MOS_STATUS_SUCCESS;
1766         return eStatus;
1767     }
1768 
1769     CODECHAL_DECODE_CHK_COND_RETURN(
1770         (m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex()),
1771         "ERROR - vdbox index exceed the maximum");
1772 
1773     m_osInterface->pfnSetPerfTag(
1774         m_osInterface,
1775         (uint16_t)(((m_mode << 4) & 0xF0) | (m_perfType & 0xF)));
1776     m_osInterface->pfnResetPerfBufferID(m_osInterface);
1777 
1778     MOS_COMMAND_BUFFER cmdBuffer;
1779     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
1780         m_osInterface,
1781         &cmdBuffer,
1782         0));
1783 
1784     if (m_cencBuf == nullptr)
1785     {
1786         MHW_VDBOX_HCP_BSD_PARAMS bsdParams;
1787         MOS_ZeroMemory(&bsdParams, sizeof(bsdParams));
1788         bsdParams.dwBsdDataLength =
1789             m_vp9PicParams->BSBytesInBuffer - m_vp9PicParams->UncompressedHeaderLengthInBytes;
1790         bsdParams.dwBsdDataStartOffset = m_vp9PicParams->UncompressedHeaderLengthInBytes;
1791 
1792         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpBsdObjectCmd(
1793             &cmdBuffer,
1794             &bsdParams));
1795     }
1796 
1797     // Send VD Pipe Flush command for SKL+
1798     MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdpipeFlushParams;
1799     MOS_ZeroMemory(&vdpipeFlushParams, sizeof(vdpipeFlushParams));
1800     vdpipeFlushParams.Flags.bWaitDoneHEVC = 1;
1801     vdpipeFlushParams.Flags.bFlushHEVC = 1;
1802     vdpipeFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1;
1803     CODECHAL_DECODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(
1804         &cmdBuffer,
1805         &vdpipeFlushParams));
1806 
1807     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1808     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1809     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1810         &cmdBuffer,
1811         &flushDwParams));
1812 
1813     MOS_SYNC_PARAMS syncParams;
1814     syncParams          = g_cInitSyncParams;
1815     syncParams.GpuContext               = m_videoContext;
1816     syncParams.presSyncResource         = &m_destSurface.OsResource;
1817     syncParams.bReadOnly                = false;
1818     syncParams.bDisableDecodeSyncLock   = m_disableDecodeSyncLock;
1819     syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1820 
1821     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1822     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1823 
1824     // Update the resource tag (s/w tag) for On-Demand Sync
1825     m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1826 
1827     // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1828     if (m_osInterface->bTagResourceSync)
1829     {
1830         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
1831             &cmdBuffer,
1832             &syncParams));
1833     }
1834 
1835     if (m_statusQueryReportingEnabled)
1836     {
1837         CodechalDecodeStatusReport decodeStatusReport;
1838 
1839         decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
1840         decodeStatusReport.m_currDecodedPic     = m_vp9PicParams->CurrPic;
1841         decodeStatusReport.m_currDeblockedPic   = m_vp9PicParams->CurrPic;
1842         decodeStatusReport.m_codecStatus        = CODECHAL_STATUS_UNAVAILABLE;
1843         decodeStatusReport.m_numMbsAffected     = m_usFrameWidthAlignedMinBlk * m_usFrameHeightAlignedMinBlk;
1844         decodeStatusReport.m_currDecodedPicRes  = m_vp9RefList[m_vp9PicParams->CurrPic.FrameIdx]->resRefPic;
1845 
1846         // VP9 plug-in/out was NOT fully enabled; this is just to make sure driver would not crash in CodecHal_DecodeEndFrame(),
1847         // which requires the value of DecodeStatusReport.presCurrDecodedPic
1848         CODECHAL_DEBUG_TOOL(
1849             decodeStatusReport.m_frameType = m_perfType;
1850         )
1851 
1852         CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
1853             decodeStatusReport,
1854             &cmdBuffer));
1855     }
1856 
1857     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1858         &cmdBuffer,
1859         &flushDwParams));
1860 
1861     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1862         &cmdBuffer,
1863         nullptr));
1864 
1865     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1866 
1867     CODECHAL_DEBUG_TOOL(
1868         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1869             &cmdBuffer,
1870             CODECHAL_NUM_MEDIA_STATES,
1871             "_DEC"));
1872 
1873         //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
1874         //    m_debugInterface,
1875         //    &cmdBuffer));
1876 
1877         m_mmc->UpdateUserFeatureKey(&m_destSurface);)
1878 
1879     bool syncCompleteFrame = m_copyDataBufferInUse;
1880 
1881     if (syncCompleteFrame)
1882     {
1883         //Sync up complete frame
1884         MOS_SYNC_PARAMS copyDataSyncParams = g_cInitSyncParams;
1885         copyDataSyncParams.GpuContext = m_videoContextForWa;
1886         copyDataSyncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1887 
1888         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &copyDataSyncParams));
1889 
1890         copyDataSyncParams = g_cInitSyncParams;
1891         copyDataSyncParams.GpuContext = m_videoContext;
1892         copyDataSyncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
1893 
1894         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &copyDataSyncParams));
1895     }
1896 
1897     uint32_t renderingFlags = m_videoContextUsesNullHw;
1898 
1899     HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
1900 
1901     //submit command buffer
1902     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1903         m_osInterface,
1904         &cmdBuffer,
1905         renderingFlags));
1906 
1907     // Reset status report
1908     if (m_statusQueryReportingEnabled)
1909     {
1910         CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
1911             m_videoContextUsesNullHw));
1912     }
1913 
1914 #ifdef CODECHAL_HUC_KERNEL_DEBUG
1915     CODECHAL_DEBUG_TOOL(
1916     CODECHAL_DECODE_CHK_STATUS(m_debugInterface->DumpHucRegion(
1917         &pVp9State->resHucSharedBuffer,
1918         0,
1919         CODEC_VP9_PROB_MAX_NUM_ELEM,
1920         15,
1921         "",
1922         false,
1923         0,
1924         CodechalHucRegionDumpType::hucRegionDumpDefault));
1925 
1926     )
1927 #endif
1928 
1929     CODECHAL_DEBUG_TOOL(
1930         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1931             &m_resVp9SegmentIdBuffer,
1932             CodechalDbgAttr::attrSegId,
1933             "SegId",
1934             (m_allocatedWidthInSb * m_allocatedHeightInSb * CODECHAL_CACHELINE_SIZE)));
1935         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1936             &(m_resVp9ProbBuffer[m_frameCtxIdx]),
1937             CodechalDbgAttr::attrCoefProb,
1938             "PakHwCoeffProbs",
1939             CODEC_VP9_PROB_MAX_NUM_ELEM));)
1940 
1941     // Needs to be re-set for Linux buffer re-use scenarios
1942     // pVp9RefList[pVp9PicParams->ucCurrPicIndex]->resRefPic =
1943     //    sDestSurface.OsResource;
1944 
1945     // Send the signal to indicate decode completion, in case On-Demand Sync is not present
1946     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
1947 
1948     return eStatus;
1949 }
1950 
InitMmcState()1951 MOS_STATUS CodechalDecodeVp9::InitMmcState()
1952 {
1953 #ifdef _MMC_SUPPORTED
1954     m_mmc = MOS_New(CodechalMmcDecodeVp9, m_hwInterface, this);
1955     CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
1956 #endif
1957     return MOS_STATUS_SUCCESS;
1958 }
1959 
AllocateStandard(CodechalSetting * settings)1960 MOS_STATUS CodechalDecodeVp9 :: AllocateStandard (
1961     CodechalSetting *settings)
1962 {
1963     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1964 
1965     CODECHAL_DECODE_FUNCTION_ENTER;
1966 
1967     CODECHAL_DECODE_CHK_NULL_RETURN(settings);
1968 
1969     CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
1970 
1971     m_width                      = settings->width;
1972     m_height                     = settings->height;
1973     if (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_8_BITS)
1974         m_vp9DepthIndicator = 0;
1975     if (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_10_BITS)
1976         m_vp9DepthIndicator = 1;
1977     if (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_12_BITS)
1978         m_vp9DepthIndicator = 2;
1979     m_chromaFormatinProfile = settings->chromaFormat;
1980 
1981     MHW_VDBOX_STATE_CMDSIZE_PARAMS      stateCmdSizeParams;
1982     stateCmdSizeParams.bHucDummyStream = false;
1983 
1984     // Picture Level Commands
1985     m_hwInterface->GetHxxStateCommandSize(
1986         m_mode,
1987         &m_commandBufferSizeNeeded,
1988         &m_commandPatchListSizeNeeded,
1989         &stateCmdSizeParams);
1990 
1991     // Primitive Level Commands
1992     m_hwInterface->GetHxxPrimitiveCommandSize(
1993         m_mode,
1994         &m_standardDecodeSizeNeeded,
1995         &m_standardDecodePatchListSizeNeeded,
1996         false);
1997 
1998     CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesFixedSizes());
1999 
2000     // Prepare Pic Params
2001     m_picMhwParams.PipeModeSelectParams = MOS_New(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS);
2002     m_picMhwParams.PipeBufAddrParams = MOS_New(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS);
2003     m_picMhwParams.IndObjBaseAddrParams = MOS_New(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS);
2004     m_picMhwParams.Vp9PicState = MOS_New(MHW_VDBOX_VP9_PIC_STATE);
2005     m_picMhwParams.Vp9SegmentState = MOS_New(MHW_VDBOX_VP9_SEGMENT_STATE);
2006 
2007     MOS_ZeroMemory(m_picMhwParams.IndObjBaseAddrParams, sizeof(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS));
2008     MOS_ZeroMemory(m_picMhwParams.Vp9PicState, sizeof(MHW_VDBOX_VP9_PIC_STATE));
2009     MOS_ZeroMemory(m_picMhwParams.Vp9SegmentState, sizeof(MHW_VDBOX_VP9_SEGMENT_STATE));
2010 
2011     for (uint16_t i = 0; i < 4; i++)
2012     {
2013         m_picMhwParams.SurfaceParams[i] = MOS_New(MHW_VDBOX_SURFACE_PARAMS);
2014         MOS_ZeroMemory(m_picMhwParams.SurfaceParams[i], sizeof(MHW_VDBOX_SURFACE_PARAMS));
2015     }
2016 
2017     return eStatus;
2018 }
2019 
2020 #if USE_CODECHAL_DEBUG_TOOL
DumpDecodePicParams(PCODEC_VP9_PIC_PARAMS picParams)2021 MOS_STATUS CodechalDecodeVp9::DumpDecodePicParams(
2022     PCODEC_VP9_PIC_PARAMS picParams)
2023 {
2024     CODECHAL_DEBUG_FUNCTION_ENTER;
2025 
2026     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
2027     {
2028         return MOS_STATUS_SUCCESS;
2029     }
2030     CODECHAL_DEBUG_CHK_NULL(picParams);
2031 
2032     std::ostringstream oss;
2033     oss.setf(std::ios::showbase | std::ios::uppercase);
2034 
2035     oss << "CurrPic FrameIdx: " << std::hex << +picParams->CurrPic.FrameIdx << std::endl;
2036     oss << "CurrPic PicFlags: " << std::hex << +picParams->CurrPic.PicFlags << std::endl;
2037 
2038     for (uint8_t i = 0; i < 8; ++i)
2039     {
2040         oss << "RefFrameList["<<+i<<"] FrameIdx:" << std::hex << +picParams->RefFrameList[i].FrameIdx << std::endl;
2041         oss << "RefFrameList["<<+i<<"] PicFlags:" << std::hex << +picParams->RefFrameList[i].PicFlags << std::endl;
2042     }
2043     oss << "FrameWidthMinus1: " << std::hex << +picParams->FrameWidthMinus1 << std::endl;
2044     oss << "FrameHeightMinus1: " << std::hex << +picParams->FrameHeightMinus1 << std::endl;
2045     oss << "PicFlags value: " << std::hex << +picParams->PicFlags.value << std::endl;
2046     oss << "frame_type: " << std::hex << +picParams->PicFlags.fields.frame_type << std::endl;
2047     oss << "show_frame: " << std::hex << +picParams->PicFlags.fields.show_frame << std::endl;
2048     oss << "error_resilient_mode: " << std::hex << +picParams->PicFlags.fields.error_resilient_mode << std::endl;
2049     oss << "intra_only: " << std::hex << +picParams->PicFlags.fields.intra_only << std::endl;
2050     oss << "LastRefIdx: " << std::hex << +picParams->PicFlags.fields.LastRefIdx << std::endl;
2051     oss << "LastRefSignBias: " << std::hex << +picParams->PicFlags.fields.LastRefSignBias << std::endl;
2052     oss << "GoldenRefIdx: " << std::hex << +picParams->PicFlags.fields.GoldenRefIdx << std::endl;
2053     oss << "GoldenRefSignBias: " << std::hex << +picParams->PicFlags.fields.GoldenRefSignBias << std::endl;
2054     oss << "AltRefIdx: " << std::hex << +picParams->PicFlags.fields.AltRefIdx << std::endl;
2055     oss << "AltRefSignBias: " << std::hex << +picParams->PicFlags.fields.AltRefSignBias << std::endl;
2056     oss << "allow_high_precision_mv: " << std::hex << +picParams->PicFlags.fields.allow_high_precision_mv << std::endl;
2057     oss << "mcomp_filter_type: " << std::hex << +picParams->PicFlags.fields.mcomp_filter_type << std::endl;
2058     oss << "frame_parallel_decoding_mode: " << std::hex << +picParams->PicFlags.fields.frame_parallel_decoding_mode << std::endl;
2059     oss << "segmentation_enabled: " << std::hex << +picParams->PicFlags.fields.segmentation_enabled << std::endl;
2060     oss << "segmentation_temporal_update: " << std::hex << +picParams->PicFlags.fields.segmentation_temporal_update << std::endl;
2061     oss << "segmentation_update_map: " << std::hex << +picParams->PicFlags.fields.segmentation_update_map << std::endl;
2062     oss << "reset_frame_context: " << std::hex << +picParams->PicFlags.fields.reset_frame_context << std::endl;
2063     oss << "refresh_frame_context: " << std::hex << +picParams->PicFlags.fields.refresh_frame_context << std::endl;
2064     oss << "frame_context_idx: " << std::hex << +picParams->PicFlags.fields.frame_context_idx << std::endl;
2065     oss << "LosslessFlag: " << std::hex << +picParams->PicFlags.fields.LosslessFlag << std::endl;
2066     oss << "ReservedField: " << std::hex << +picParams->PicFlags.fields.ReservedField << std::endl;
2067     oss << "filter_level: " << std::hex << +picParams->filter_level << std::endl;
2068     oss << "sharpness_level: " << std::hex << +picParams->sharpness_level << std::endl;
2069     oss << "log2_tile_rows: " << std::hex << +picParams->log2_tile_rows << std::endl;
2070     oss << "log2_tile_columns: " << std::hex << +picParams->log2_tile_columns << std::endl;
2071     oss << "UncompressedHeaderLengthInBytes: " << std::hex << +picParams->UncompressedHeaderLengthInBytes << std::endl;
2072     oss << "FirstPartitionSize: " << std::hex << +picParams->FirstPartitionSize << std::endl;
2073     oss << "profile: " << std::hex << +picParams->profile << std::endl;
2074     oss << "BitDepthMinus8: " << std::hex << +picParams->BitDepthMinus8 << std::endl;
2075     oss << "subsampling_x: " << std::hex << +picParams->subsampling_x << std::endl;
2076     oss << "subsampling_y: " << std::hex << +picParams->subsampling_y << std::endl;
2077 
2078     for (uint8_t i = 0; i < 7; ++i)
2079     {
2080         oss << "SegTreeProbs["<<+i<<"]: " << std::hex << +picParams->SegTreeProbs[i] << std::endl;
2081     }
2082     for (uint8_t i = 0; i < 3; ++i)
2083     {
2084         oss << "SegPredProbs["<<+i<<"]: " << std::hex << +picParams->SegPredProbs[i] << std::endl;
2085     }
2086     oss << "BSBytesInBuffer: " << std::hex << +picParams->BSBytesInBuffer << std::endl;
2087     oss << "StatusReportFeedbackNumber: " << std::hex << +picParams->StatusReportFeedbackNumber << std::endl;
2088 
2089     const char* fileName = m_debugInterface->CreateFileName(
2090         "_DEC",
2091         CodechalDbgBufferType::bufPicParams,
2092         CodechalDbgExtType::txt);
2093 
2094     std::ofstream ofs(fileName, std::ios::out);
2095     ofs << oss.str();
2096     ofs.close();
2097 
2098     return MOS_STATUS_SUCCESS;
2099 }
2100 
DumpDecodeSegmentParams(PCODEC_VP9_SEGMENT_PARAMS segmentParams)2101 MOS_STATUS CodechalDecodeVp9::DumpDecodeSegmentParams(
2102     PCODEC_VP9_SEGMENT_PARAMS segmentParams)
2103 {
2104     CODECHAL_DEBUG_FUNCTION_ENTER;
2105 
2106     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSegmentParams))
2107     {
2108         return MOS_STATUS_SUCCESS;
2109     }
2110 
2111     CODECHAL_DEBUG_CHK_NULL(segmentParams);
2112 
2113     std::ostringstream oss;
2114     oss.setf(std::ios::showbase | std::ios::uppercase);
2115 
2116     for (uint8_t i = 0; i < 8; ++i)
2117     {
2118         oss << "SegData["<<+i<<"] SegmentFlags value: " << std::hex << +segmentParams->SegData[i].SegmentFlags.value << std::endl;
2119         oss << "SegData["<<+i<<"] SegmentReferenceEnabled: " << std::hex << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReferenceEnabled << std::endl;
2120         oss << "SegData["<<+i<<"] SegmentReference: " << std::hex << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReference << std::endl;
2121         oss << "SegData["<<+i<<"] SegmentReferenceSkipped: " << std::hex << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReferenceSkipped << std::endl;
2122         oss << "SegData["<<+i<<"] ReservedField3: " << std::hex << +segmentParams->SegData[i].SegmentFlags.fields.ReservedField3 << std::endl;
2123 
2124         for (uint8_t j = 0; j < 4; ++j)
2125         {
2126             oss << "SegData["<<+i<<"] FilterLevel["<<+j<<"]:";
2127             oss << std::hex << +segmentParams->SegData[i].FilterLevel[j][0]<<" ";
2128             oss << std::hex<< +segmentParams->SegData[i].FilterLevel[j][1] << std::endl;
2129         }
2130         oss << "SegData["<<+i<<"] LumaACQuantScale: " << std::hex << +segmentParams->SegData[i].LumaACQuantScale << std::endl;
2131         oss << "SegData["<<+i<<"] LumaDCQuantScale: " << std::hex << +segmentParams->SegData[i].LumaDCQuantScale << std::endl;
2132         oss << "SegData["<<+i<<"] ChromaACQuantScale: " << std::hex << +segmentParams->SegData[i].ChromaACQuantScale << std::endl;
2133         oss << "SegData["<<+i<<"] ChromaDCQuantScale: " << std::hex << +segmentParams->SegData[i].ChromaDCQuantScale << std::endl;
2134     }
2135 
2136     const char* fileName = m_debugInterface->CreateFileName(
2137         "_DEC",
2138         CodechalDbgBufferType::bufSegmentParams,
2139         CodechalDbgExtType::txt);
2140 
2141     std::ofstream ofs(fileName, std::ios::out);
2142     ofs << oss.str();
2143     ofs.close();
2144     return MOS_STATUS_SUCCESS;
2145 }
2146 
2147 #endif
2148 
CtxBufDiffInit(uint8_t * ctxBuffer,bool setToKey)2149 MOS_STATUS CodechalDecodeVp9::CtxBufDiffInit(
2150     uint8_t             *ctxBuffer,
2151     bool                 setToKey)
2152 {
2153     int32_t i, j;
2154     uint32_t byteCnt = CODEC_VP9_INTER_PROB_OFFSET;
2155     //inter mode probs. have to be zeros for Key frame
2156     for (i = 0; i < CODEC_VP9_INTER_MODE_CONTEXTS; i++)
2157     {
2158         for (j = 0; j < CODEC_VP9_INTER_MODES - 1; j++)
2159         {
2160             if (!setToKey)
2161             {
2162                 ctxBuffer[byteCnt++] = DefaultInterModeProbs[i][j];
2163             }
2164             else
2165             {
2166                 //zeros for key frame
2167                 byteCnt++;
2168             }
2169         }
2170     }
2171     //switchable interprediction probs
2172     for (i = 0; i < CODEC_VP9_SWITCHABLE_FILTERS + 1; i++)
2173     {
2174         for (j = 0; j < CODEC_VP9_SWITCHABLE_FILTERS - 1; j++)
2175         {
2176             if (!setToKey)
2177             {
2178                 ctxBuffer[byteCnt++] = DefaultSwitchableInterpProb[i][j];
2179             }
2180             else
2181             {
2182                 //zeros for key frame
2183                 byteCnt++;
2184             }
2185         }
2186     }
2187     //intra inter probs
2188     for (i = 0; i < CODEC_VP9_INTRA_INTER_CONTEXTS; i++)
2189     {
2190         if (!setToKey)
2191         {
2192             ctxBuffer[byteCnt++] = DefaultIntraInterProb[i];
2193         }
2194         else
2195         {
2196             //zeros for key frame
2197             byteCnt++;
2198         }
2199     }
2200     //comp inter probs
2201     for (i = 0; i < CODEC_VP9_COMP_INTER_CONTEXTS; i++)
2202     {
2203         if (!setToKey)
2204         {
2205             ctxBuffer[byteCnt++] = DefaultCompInterProb[i];
2206         }
2207         else
2208         {
2209             //zeros for key frame
2210             byteCnt++;
2211         }
2212     }
2213     //single ref probs
2214     for (i = 0; i < CODEC_VP9_REF_CONTEXTS; i++)
2215     {
2216         for (j = 0; j < 2; j++)
2217         {
2218             if (!setToKey)
2219             {
2220                 ctxBuffer[byteCnt++] = DefaultSingleRefProb[i][j];
2221             }
2222             else
2223             {
2224                 //zeros for key frame
2225                 byteCnt++;
2226             }
2227         }
2228     }
2229     //comp ref probs
2230     for (i = 0; i < CODEC_VP9_REF_CONTEXTS; i++)
2231     {
2232         if (!setToKey)
2233         {
2234             ctxBuffer[byteCnt++] = DefaultCompRefProb[i];
2235         }
2236         else
2237         {
2238             //zeros for key frame
2239             byteCnt++;
2240         }
2241     }
2242     //y mode probs
2243     for (i = 0; i < CODEC_VP9_BLOCK_SIZE_GROUPS; i++)
2244     {
2245         for (j = 0; j < CODEC_VP9_INTRA_MODES - 1; j++)
2246         {
2247             if (!setToKey)
2248             {
2249                 ctxBuffer[byteCnt++] = DefaultIFYProb[i][j];
2250             }
2251             else
2252             {
2253                 //zeros for key frame, since HW will not use this buffer, but default right buffer.
2254                 byteCnt++;
2255             }
2256         }
2257     }
2258     //partition probs, key & intra-only frames use key type, other inter frames use inter type
2259     for (i = 0; i < CODECHAL_VP9_PARTITION_CONTEXTS; i++)
2260     {
2261         for (j = 0; j < CODEC_VP9_PARTITION_TYPES - 1; j++)
2262         {
2263             if (setToKey)
2264             {
2265                 ctxBuffer[byteCnt++] = DefaultKFPartitionProb[i][j];
2266             }
2267             else
2268             {
2269                 ctxBuffer[byteCnt++] = DefaultPartitionProb[i][j];
2270             }
2271         }
2272     }
2273     //nmvc joints
2274     for (i = 0; i < (CODEC_VP9_MV_JOINTS - 1); i++)
2275     {
2276         if (!setToKey)
2277         {
2278             ctxBuffer[byteCnt++] = DefaultNmvContext.joints[i];
2279         }
2280         else
2281         {
2282             //zeros for key frame
2283             byteCnt++;
2284         }
2285     }
2286     //nmvc comps
2287     for (i = 0; i < 2; i++)
2288     {
2289         if (!setToKey)
2290         {
2291             ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].sign;
2292             for (j = 0; j < (CODEC_VP9_MV_CLASSES - 1); j++)
2293             {
2294                 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].classes[j];
2295             }
2296             for (j = 0; j < (CODECHAL_VP9_CLASS0_SIZE - 1); j++)
2297             {
2298                 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0[j];
2299             }
2300             for (j = 0; j < CODECHAL_VP9_MV_OFFSET_BITS; j++)
2301             {
2302                 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].bits[j];
2303             }
2304         }
2305         else
2306         {
2307             byteCnt += 1;
2308             byteCnt += (CODEC_VP9_MV_CLASSES - 1);
2309             byteCnt += (CODECHAL_VP9_CLASS0_SIZE - 1);
2310             byteCnt += (CODECHAL_VP9_MV_OFFSET_BITS);
2311         }
2312     }
2313     for (i = 0; i < 2; i++)
2314     {
2315         if (!setToKey)
2316         {
2317             for (j = 0; j < CODECHAL_VP9_CLASS0_SIZE; j++)
2318             {
2319                 for (int32_t k = 0; k < (CODEC_VP9_MV_FP_SIZE - 1); k++)
2320                 {
2321                     ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0_fp[j][k];
2322                 }
2323             }
2324             for (j = 0; j < (CODEC_VP9_MV_FP_SIZE - 1); j++)
2325             {
2326                 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].fp[j];
2327             }
2328         }
2329         else
2330         {
2331             byteCnt += (CODECHAL_VP9_CLASS0_SIZE * (CODEC_VP9_MV_FP_SIZE - 1));
2332             byteCnt += (CODEC_VP9_MV_FP_SIZE - 1);
2333         }
2334     }
2335     for (i = 0; i < 2; i++)
2336     {
2337         if (!setToKey)
2338         {
2339             ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0_hp;
2340             ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].hp;
2341         }
2342         else
2343         {
2344             byteCnt += 2;
2345         }
2346     }
2347 
2348     //47 bytes of zeros
2349     byteCnt += 47;
2350 
2351     //uv mode probs
2352     for (i = 0; i < CODEC_VP9_INTRA_MODES; i++)
2353     {
2354         for (j = 0; j < CODEC_VP9_INTRA_MODES - 1; j++)
2355         {
2356             if (setToKey)
2357             {
2358                 ctxBuffer[byteCnt++] = DefaultKFUVModeProb[i][j];
2359             }
2360             else
2361             {
2362                 ctxBuffer[byteCnt++] = DefaultIFUVProbs[i][j];
2363             }
2364         }
2365     }
2366 
2367     return MOS_STATUS_SUCCESS;
2368 }
2369 
ContextBufferInit(uint8_t * ctxBuffer,bool setToKey)2370 MOS_STATUS CodechalDecodeVp9::ContextBufferInit(
2371     uint8_t             *ctxBuffer,
2372     bool                 setToKey)
2373 {
2374 
2375     MOS_ZeroMemory(ctxBuffer, CODEC_VP9_SEG_PROB_OFFSET);
2376 
2377     int32_t i, j;
2378     uint32_t byteCnt = 0;
2379     //TX probs
2380     for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++)
2381     {
2382         for (j = 0; j < CODEC_VP9_TX_SIZES - 3; j++)
2383         {
2384             ctxBuffer[byteCnt++] = DefaultTxProbs.p8x8[i][j];
2385         }
2386     }
2387     for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++)
2388     {
2389         for (j = 0; j < CODEC_VP9_TX_SIZES - 2; j++)
2390         {
2391             ctxBuffer[byteCnt++] = DefaultTxProbs.p16x16[i][j];
2392         }
2393     }
2394     for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++)
2395     {
2396         for (j = 0; j < CODEC_VP9_TX_SIZES - 1; j++)
2397         {
2398             ctxBuffer[byteCnt++] = DefaultTxProbs.p32x32[i][j];
2399         }
2400     }
2401 
2402     //52 bytes of zeros
2403     byteCnt += 52;
2404 
2405     uint8_t blocktype = 0;
2406     uint8_t reftype = 0;
2407     uint8_t coeffbands = 0;
2408     uint8_t unConstrainedNodes = 0;
2409     uint8_t prevCoefCtx = 0;
2410     //coeff probs
2411     for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++)
2412     {
2413         for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++)
2414         {
2415             for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++)
2416             {
2417                 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
2418                 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++)
2419                 {
2420                     for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++)
2421                     {
2422                         ctxBuffer[byteCnt++] = DefaultCoefProbs4x4[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
2423                     }
2424                 }
2425             }
2426         }
2427     }
2428 
2429     for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++)
2430     {
2431         for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++)
2432         {
2433             for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++)
2434             {
2435                 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
2436                 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++)
2437                 {
2438                     for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++)
2439                     {
2440                         ctxBuffer[byteCnt++] = DefaultCoefPprobs8x8[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
2441                     }
2442                 }
2443             }
2444         }
2445     }
2446 
2447     for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++)
2448     {
2449         for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++)
2450         {
2451             for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++)
2452             {
2453                 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
2454                 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++)
2455                 {
2456                     for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++)
2457                     {
2458                         ctxBuffer[byteCnt++] = DefaultCoefProbs16x16[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
2459                     }
2460                 }
2461             }
2462         }
2463     }
2464 
2465     for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++)
2466     {
2467         for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++)
2468         {
2469             for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++)
2470             {
2471                 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
2472                 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++)
2473                 {
2474                     for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++)
2475                     {
2476                         ctxBuffer[byteCnt++] = DefaultCoefProbs32x32[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
2477                     }
2478                 }
2479             }
2480         }
2481     }
2482 
2483     //16 bytes of zeros
2484     byteCnt += 16;
2485 
2486     // mb skip probs
2487     for (i = 0; i < CODEC_VP9_MBSKIP_CONTEXTS; i++)
2488     {
2489         ctxBuffer[byteCnt++] = DefaultMbskipProbs[i];
2490     }
2491 
2492     // populate prob values which are different between Key and Non-Key frame
2493     CtxBufDiffInit(ctxBuffer, setToKey);
2494 
2495     //skip Seg tree/pred probs, updating not done in this function.
2496     byteCnt = CODEC_VP9_SEG_PROB_OFFSET;
2497     byteCnt += 7;
2498     byteCnt += 3;
2499 
2500     //28 bytes of zeros
2501     for (i = 0; i < 28; i++)
2502     {
2503         ctxBuffer[byteCnt++] = 0;
2504     }
2505 
2506     //Just a check.
2507     if (byteCnt > CODEC_VP9_PROB_MAX_NUM_ELEM)
2508     {
2509         CODECHAL_PUBLIC_ASSERTMESSAGE("Error: FrameContext array out-of-bounds, byteCnt = %d!\n", byteCnt);
2510         return MOS_STATUS_NO_SPACE;
2511     }
2512     else
2513     {
2514         return MOS_STATUS_SUCCESS;
2515     }
2516 }
2517