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