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, ©DataSyncParams));
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, ©DataSyncParams));
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