1 /*
2 * Copyright (c) 2019-2023, 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     decode_av1_basic_feature.cpp
24 //! \brief    Defines the common interface for decode av1 parameter
25 //!
26 
27 #include "decode_av1_basic_feature.h"
28 #include "decode_utils.h"
29 #include "decode_allocator.h"
30 
31 namespace decode
32 {
~Av1BasicFeature()33     Av1BasicFeature::~Av1BasicFeature()
34     {
35         if (m_allocator)
36         {
37             for (uint8_t i = 0; i < av1DefaultCdfTableNum; i++)
38             {
39                 if (!m_allocator->ResourceIsNull(&m_defaultCdfBuffers[i]->OsResource))
40                 {
41                     m_allocator->Destroy(m_defaultCdfBuffers[i]);
42                 }
43             }
44             if (m_usingDummyWl == true)
45             {
46                 m_allocator->Destroy(m_destSurfaceForDummyWL);
47             }
48             if (m_fgInternalSurf != nullptr && !m_allocator->ResourceIsNull(&m_fgInternalSurf->OsResource))
49             {
50                 m_allocator->Destroy(m_fgInternalSurf);
51             }
52         }
53     }
54 
Init(void * setting)55     MOS_STATUS Av1BasicFeature::Init(void *setting)
56     {
57         DECODE_FUNC_CALL();
58 
59         PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
60 
61         DECODE_CHK_NULL(setting);
62 
63         DECODE_CHK_STATUS(DecodeBasicFeature::Init(setting));
64         CodechalSetting *codecSettings = (CodechalSetting*)setting;
65 
66         if (m_osInterface != nullptr)
67         {
68             MEDIA_WA_TABLE* waTable = m_osInterface->pfnGetWaTable(m_osInterface);
69 
70             m_usingDummyWl = ((waTable != nullptr) ? MEDIA_IS_WA(waTable, Wa_1508208842) : false)
71                 && !m_osInterface->bSimIsActive;
72             if (m_usingDummyWl == true)
73             {
74                 //Allocate a dest surface for dummy WL
75                 m_destSurfaceForDummyWL = m_allocator->AllocateSurface(
76                     16,
77                     16,
78                     "Dummy Decode Output Frame Buffer",
79                     Format_NV12,
80                     false,
81                     resourceOutputPicture,
82                     notLockableVideoMem);
83                 DECODE_CHK_NULL(m_destSurfaceForDummyWL);
84             }
85         }
86 
87         DECODE_CHK_STATUS(m_refFrames.Init(this, *m_allocator));
88         DECODE_CHK_STATUS(m_tempBuffers.Init(m_hwInterface, *m_allocator, *this, CODEC_NUM_REF_AV1_TEMP_BUFFERS));
89         DECODE_CHK_STATUS(m_tileCoding.Init(this, codecSettings));
90         DECODE_CHK_STATUS(m_internalTarget.Init(*m_allocator));
91 
92         return MOS_STATUS_SUCCESS;
93     }
94 
Update(void * params)95     MOS_STATUS Av1BasicFeature::Update(void *params)
96     {
97         DECODE_FUNC_CALL();
98 
99         PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
100 
101         DECODE_CHK_NULL(params);
102 
103         DECODE_CHK_STATUS(DecodeBasicFeature::Update(params));
104 
105         CodechalDecodeParams* decodeParams = (CodechalDecodeParams*)params;
106         m_dataSize = decodeParams->m_dataSize;
107         m_av1PicParams  = static_cast<CodecAv1PicParams*>(decodeParams->m_picParams);
108         DECODE_CHK_NULL(m_av1PicParams);
109 
110         if (decodeParams->m_destSurface->OsResource.Format == Format_P010)
111         {
112             m_bitDepth = 10;
113         }
114 
115         // Do error detection and concealment
116         DECODE_CHK_STATUS(ErrorDetectAndConceal());
117 
118         if (m_av1PicParams->m_bitDepthIdx == 0) m_av1DepthIndicator = 0;
119         if (m_av1PicParams->m_bitDepthIdx == 1) m_av1DepthIndicator = 1;
120         if (m_av1PicParams->m_bitDepthIdx == 2) m_av1DepthIndicator = 2;
121 
122         m_pictureCodingType = m_av1PicParams->m_picInfoFlags.m_fields.m_frameType ? P_TYPE : I_TYPE;
123 
124         // Derive Large Scale Tile output frame width/height
125         if (m_av1PicParams->m_picInfoFlags.m_fields.m_largeScaleTile &&
126             !m_av1PicParams->m_anchorFrameInsertion &&
127             m_av1PicParams->m_outputFrameWidthInTilesMinus1 == 0xffff &&
128             m_av1PicParams->m_outputFrameHeightInTilesMinus1 == 0xffff)
129         {
130             m_av1PicParams->m_outputFrameWidthInTilesMinus1  = (uint16_t)((m_destSurface.dwWidth / (m_av1PicParams->m_widthInSbsMinus1[0] + 1))
131                                                                 >> (m_av1PicParams->m_seqInfoFlags.m_fields.m_use128x128Superblock ? 7 : 6)) - 1;
132             m_av1PicParams->m_outputFrameHeightInTilesMinus1 = (uint16_t)((m_destSurface.dwHeight / (m_av1PicParams->m_heightInSbsMinus1[0] + 1))
133                                                                 >> (m_av1PicParams->m_seqInfoFlags.m_fields.m_use128x128Superblock ? 7 : 6)) - 1;
134         }
135 
136         if (m_av1PicParams->m_picInfoFlags.m_fields.m_largeScaleTile && m_av1PicParams->m_anchorFrameInsertion)
137         {
138             DECODE_CHK_STATUS(m_refFrames.InsertAnchorFrame(*m_av1PicParams));
139             return MOS_STATUS_SUCCESS;
140         }
141 
142         m_av1TileParams = static_cast<CodecAv1TileParams*>(decodeParams->m_sliceParams);
143         DECODE_CHK_NULL(m_av1TileParams);
144 
145         m_segmentParams = &m_av1PicParams->m_av1SegData;
146         DECODE_CHK_NULL(m_segmentParams);
147 
148         m_tileCoding.m_numTiles = decodeParams->m_numSlices;
149 
150         m_filmGrainEnabled = m_av1PicParams->m_filmGrainParams.m_filmGrainInfoFlags.m_fields.m_applyGrain;
151 
152         DECODE_CHK_STATUS(SetPictureStructs(decodeParams));
153         DECODE_CHK_STATUS(SetTileStructs());
154 
155         return MOS_STATUS_SUCCESS;
156     }
157 
CheckProfileAndSubsampling()158     MOS_STATUS Av1BasicFeature::CheckProfileAndSubsampling()
159     {
160         DECODE_FUNC_CALL();
161 
162         // Profile and subsampling
163         if (m_av1PicParams->m_seqInfoFlags.m_fields.m_monoChrome ||
164             m_av1PicParams->m_profile != 0 ||
165             !(m_av1PicParams->m_seqInfoFlags.m_fields.m_subsamplingX == 1 &&
166                 m_av1PicParams->m_seqInfoFlags.m_fields.m_subsamplingY == 1))
167         {
168             DECODE_ASSERTMESSAGE("Only 4:2:0 8bit and 10bit are supported!");
169             return MOS_STATUS_INVALID_PARAMETER;
170         }
171 
172         return MOS_STATUS_SUCCESS;
173     }
174 
CheckBitdepth()175     MOS_STATUS Av1BasicFeature::CheckBitdepth()
176     {
177         DECODE_FUNC_CALL();
178 
179         if ((m_av1PicParams->m_bitDepthIdx == 0 && m_bitDepth != 8) ||
180             (m_av1PicParams->m_bitDepthIdx == 1 && m_bitDepth != 10))
181         {
182             DECODE_ASSERTMESSAGE("Bit depth not align!");
183             return MOS_STATUS_INVALID_PARAMETER;
184         }
185 
186         return MOS_STATUS_SUCCESS;
187     }
188 
ErrorDetectAndConceal()189     MOS_STATUS Av1BasicFeature::ErrorDetectAndConceal()
190     {
191         DECODE_FUNC_CALL()
192         DECODE_CHK_NULL(m_av1PicParams);
193 
194         DECODE_CHK_STATUS(CheckProfileAndSubsampling());
195 
196         DECODE_CHK_STATUS(CheckBitdepth());
197 
198         // Frame Width/Frame Height, valid range is [15, 16383]
199         if (m_av1PicParams->m_frameWidthMinus1 < 15 || m_av1PicParams->m_frameHeightMinus1 < 15)
200         {
201             DECODE_ASSERTMESSAGE("Frame Width/Height is invalid, out of [15, 16383].");
202             return MOS_STATUS_INVALID_PARAMETER;
203         }
204 
205         if (!m_av1PicParams->m_seqInfoFlags.m_fields.m_enableOrderHint &&
206             (m_av1PicParams->m_orderHint != 0))
207         {
208             DECODE_ASSERTMESSAGE("orderHint Conflict with AV1 Spec!");
209             return MOS_STATUS_INVALID_PARAMETER;
210         }
211         if(m_av1PicParams->m_picInfoFlags.m_fields.m_allowIntrabc &&
212             (!(m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == keyFrame ||
213                 m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == intraOnlyFrame) ||
214                 !m_av1PicParams->m_picInfoFlags.m_fields.m_allowScreenContentTools ||
215                 m_av1PicParams->m_picInfoFlags.m_fields.m_useSuperres))
216         {
217             DECODE_ASSERTMESSAGE("Superres use Conflict with AV1 Spec.");
218             return MOS_STATUS_INVALID_PARAMETER;
219         }
220 
221         //Tx Mode
222         if(m_av1PicParams->m_losslessMode &&
223             m_av1PicParams->m_modeControlFlags.m_fields.m_txMode != (uint32_t)CodecAv1TxType::ONLY_4X4)
224         {
225             DECODE_ASSERTMESSAGE("Conflict with AV1 Spec! Coded Lossless only allows TX_4X4.\n");
226             return MOS_STATUS_INVALID_PARAMETER;
227         }
228 
229         if (m_av1PicParams->m_picInfoFlags.m_fields.m_forceIntegerMv &&
230             m_av1PicParams->m_picInfoFlags.m_fields.m_allowHighPrecisionMv &&
231             !(m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == intraOnlyFrame ||
232              m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == keyFrame))
233         {
234             DECODE_ASSERTMESSAGE("Conflict with AV1 Spec!");
235             return MOS_STATUS_INVALID_PARAMETER;
236         }
237 
238         if (m_av1PicParams->m_picInfoFlags.m_fields.m_forceIntegerMv &&
239             (!m_av1PicParams->m_picInfoFlags.m_fields.m_allowScreenContentTools &&
240              !(m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == intraOnlyFrame
241                  || m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == keyFrame)))
242         {
243             DECODE_ASSERTMESSAGE("Conflict with AV1 Spec!");
244             return MOS_STATUS_INVALID_PARAMETER;
245         }
246 
247         //Order Hint
248         if (!m_av1PicParams->m_seqInfoFlags.m_fields.m_enableOrderHint &&
249             (m_av1PicParams->m_seqInfoFlags.m_fields.m_enableJntComp ||
250                 m_av1PicParams->m_picInfoFlags.m_fields.m_useRefFrameMvs))
251         {
252             DECODE_ASSERTMESSAGE("Conflict with AV1 Spec!");
253             return MOS_STATUS_INVALID_PARAMETER;
254         }
255 
256         //CDF Upate
257         if (!m_av1PicParams->m_picInfoFlags.m_fields.m_disableFrameEndUpdateCdf &&
258             m_av1PicParams->m_picInfoFlags.m_fields.m_disableCdfUpdate)
259         {
260             DECODE_ASSERTMESSAGE("Illegal Cdf update params combination!");
261             return MOS_STATUS_INVALID_PARAMETER;
262         }
263 
264         //Reference Mode
265         if ((m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == keyFrame ||
266             m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == intraOnlyFrame) &&
267                 (m_av1PicParams->m_modeControlFlags.m_fields.m_referenceMode != singleReference))
268         {
269             DECODE_ASSERTMESSAGE("Reference mode shouldn't be singleReference for keyFrame or intraOnlyFrame.");
270             return MOS_STATUS_INVALID_PARAMETER;
271         }
272 
273         //Skip Mode
274         if (((m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == keyFrame ||
275                 m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == intraOnlyFrame ||
276                 m_av1PicParams->m_modeControlFlags.m_fields.m_referenceMode == singleReference) ||
277                 !m_av1PicParams->m_seqInfoFlags.m_fields.m_enableOrderHint) &&
278                 m_av1PicParams->m_modeControlFlags.m_fields.m_skipModePresent)
279         {
280             DECODE_ASSERTMESSAGE("SkipModePresent should be 0 for keyFrame, intraOnlyFrame or singleReference.");
281             return MOS_STATUS_INVALID_PARAMETER;
282         }
283 
284         if ((m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == keyFrame ||
285             m_av1PicParams->m_picInfoFlags.m_fields.m_frameType == intraOnlyFrame) &&
286             (m_av1PicParams->m_picInfoFlags.m_fields.m_allowWarpedMotion ||
287                 (m_av1PicParams->m_primaryRefFrame != av1PrimaryRefNone)))
288         {
289             DECODE_ASSERTMESSAGE("Conflict with AV1 Spec!");
290             return MOS_STATUS_INVALID_PARAMETER;
291         }
292 
293         if (m_av1PicParams->m_seqInfoFlags.m_fields.m_enableOrderHint &&
294             m_av1PicParams->m_orderHintBitsMinus1 > 7)
295         {
296             DECODE_ASSERTMESSAGE("Conflict with AV1 Spec!");
297             return MOS_STATUS_INVALID_PARAMETER;
298         }
299 
300         // Film grain parameter check
301         if (m_av1PicParams->m_seqInfoFlags.m_fields.m_filmGrainParamsPresent &&
302             m_av1PicParams->m_filmGrainParams.m_filmGrainInfoFlags.m_fields.m_applyGrain)
303         {
304             // Check film grain parameter of the luma component
305             if (m_av1PicParams->m_filmGrainParams.m_numYPoints > 14)
306             {
307                 DECODE_ASSERTMESSAGE("Invalid film grain num_y_points (should be in [0, 14]) in pic parameter!");
308                 return MOS_STATUS_INVALID_PARAMETER;
309             }
310             for (auto i = 1; i < m_av1PicParams->m_filmGrainParams.m_numYPoints; i++)
311             {
312                 if (m_av1PicParams->m_filmGrainParams.m_pointYValue[i] <= m_av1PicParams->m_filmGrainParams.m_pointYValue[i - 1])
313                 {
314                     DECODE_ASSERTMESSAGE("Invalid film grain point_y_value (point_y_value[%d] should be greater than point_y_value[%d]) in pic parameter!", i, i - 1);
315                     return MOS_STATUS_INVALID_PARAMETER;
316                 }
317             }
318             // Check film grain parameter of the cb component
319             if (m_av1PicParams->m_filmGrainParams.m_numCbPoints > 10)
320             {
321                 DECODE_ASSERTMESSAGE("Invalid film grain num_cb_points (should be in [0, 10]) in pic parameter!");
322                 return MOS_STATUS_INVALID_PARAMETER;
323             }
324             for (auto i = 1; i < m_av1PicParams->m_filmGrainParams.m_numCbPoints; i++)
325             {
326                 if (m_av1PicParams->m_filmGrainParams.m_pointCbValue[i] <= m_av1PicParams->m_filmGrainParams.m_pointCbValue[i - 1])
327                 {
328                     DECODE_ASSERTMESSAGE("Invalid film grain point_cb_value (point_cb_value[%d] should be greater than point_cb_value[%d]) in pic parameter!", i, i - 1);
329                     return MOS_STATUS_INVALID_PARAMETER;
330                 }
331             }
332             // Check film grain parameter of the cr component
333             if (m_av1PicParams->m_filmGrainParams.m_numCrPoints > 10)
334             {
335                 DECODE_ASSERTMESSAGE("Invalid film grain num_cr_points (should be in [0, 10]) in pic parameter!");
336                 return MOS_STATUS_INVALID_PARAMETER;
337             }
338             for (auto i = 1; i < m_av1PicParams->m_filmGrainParams.m_numCrPoints; i++)
339             {
340                 if (m_av1PicParams->m_filmGrainParams.m_pointCrValue[i] <= m_av1PicParams->m_filmGrainParams.m_pointCrValue[i - 1])
341                 {
342                     DECODE_ASSERTMESSAGE("Invalid film grain point_cr_value (point_cr_value[%d] should be greater than point_cr_value[%d]) in pic parameter!", i, i - 1);
343                     return MOS_STATUS_INVALID_PARAMETER;
344                 }
345             }
346         }
347 
348         //Error Concealment for CDEF
349         if (m_av1PicParams->m_losslessMode ||
350             m_av1PicParams->m_picInfoFlags.m_fields.m_allowIntrabc ||
351             !m_av1PicParams->m_seqInfoFlags.m_fields.m_enableCdef)
352         {
353             m_av1PicParams->m_cdefBits            = 0;
354             m_av1PicParams->m_cdefYStrengths[0]   = 0;
355             m_av1PicParams->m_cdefUvStrengths[0]  = 0;
356             m_av1PicParams->m_cdefDampingMinus3   = 0;
357         }
358 
359         //Error Concealment for Loop Filter
360         if (m_av1PicParams->m_losslessMode ||
361             m_av1PicParams->m_picInfoFlags.m_fields.m_allowIntrabc)
362         {
363             m_av1PicParams->m_filterLevel[0] = 0;
364             m_av1PicParams->m_filterLevel[1] = 0;
365 
366             m_av1PicParams->m_refDeltas[intraFrame]     = 1;
367             m_av1PicParams->m_refDeltas[lastFrame]      = 0;
368             m_av1PicParams->m_refDeltas[last2Frame]     = 0;
369             m_av1PicParams->m_refDeltas[last3Frame]     = 0;
370             m_av1PicParams->m_refDeltas[bwdRefFrame]    = 0;
371             m_av1PicParams->m_refDeltas[goldenFrame]    = -1;
372             m_av1PicParams->m_refDeltas[altRef2Frame]   = -1;
373             m_av1PicParams->m_refDeltas[altRefFrame]    = -1;
374 
375             m_av1PicParams->m_modeDeltas[0] = 0;
376             m_av1PicParams->m_modeDeltas[1] = 0;
377 
378             m_av1PicParams->m_loopFilterInfoFlags.m_value = 0;
379         }
380 
381         // Error Concealment for Loop Restoration
382         if ((!m_av1PicParams->m_picInfoFlags.m_fields.m_useSuperres &&
383             m_av1PicParams->m_losslessMode) ||
384             m_av1PicParams->m_picInfoFlags.m_fields.m_allowIntrabc)
385         {
386             m_av1PicParams->m_loopRestorationFlags.m_value = 0;
387         }
388 
389         // LRU Luma Size cannot < Superblock Size. If Superblock Size is 128x128, LRU Luma Size cannot be 64x64.
390         if (m_av1PicParams->m_seqInfoFlags.m_fields.m_use128x128Superblock)
391         {
392             if (m_av1PicParams->m_loopRestorationFlags.m_fields.m_lrUnitShift == 0 &&
393                 (m_av1PicParams->m_loopRestorationFlags.m_fields.m_yframeRestorationType ||
394                     m_av1PicParams->m_loopRestorationFlags.m_fields.m_cbframeRestorationType ||
395                     m_av1PicParams->m_loopRestorationFlags.m_fields.m_crframeRestorationType))
396             {
397                 DECODE_ASSERTMESSAGE("Superblock use Conflict with AV1 Spec!");
398                 m_av1PicParams->m_loopRestorationFlags.m_value = 0;
399             }
400         }
401 
402         // Error Concealment for DeltaLF and DeltaQ
403         if (m_av1PicParams->m_baseQindex == 0)
404         {
405             m_av1PicParams->m_modeControlFlags.m_fields.m_deltaQPresentFlag = 0;
406         }
407         if (m_av1PicParams->m_modeControlFlags.m_fields.m_deltaQPresentFlag)
408         {
409             if (m_av1PicParams->m_picInfoFlags.m_fields.m_allowIntrabc)
410             {
411                 m_av1PicParams->m_modeControlFlags.m_fields.m_deltaLfPresentFlag = 0;
412             }
413         }
414         else
415         {
416             m_av1PicParams->m_modeControlFlags.m_fields.m_log2DeltaQRes = 0;
417             m_av1PicParams->m_modeControlFlags.m_fields.m_log2DeltaLfRes = 0;
418             m_av1PicParams->m_modeControlFlags.m_fields.m_deltaLfPresentFlag = 0;
419             m_av1PicParams->m_modeControlFlags.m_fields.m_deltaLfMulti = 0;
420         }
421         if (m_av1PicParams->m_modeControlFlags.m_fields.m_deltaLfPresentFlag == 0)
422         {
423             m_av1PicParams->m_modeControlFlags.m_fields.m_log2DeltaLfRes = 0;
424             m_av1PicParams->m_modeControlFlags.m_fields.m_deltaLfMulti = 0;
425         }
426 
427         // Error Concealment for Film Grain
428         if (!m_av1PicParams->m_seqInfoFlags.m_fields.m_filmGrainParamsPresent ||
429             !(m_av1PicParams->m_picInfoFlags.m_fields.m_showFrame ||
430               m_av1PicParams->m_picInfoFlags.m_fields.m_showableFrame))
431         {
432             memset(&m_av1PicParams->m_filmGrainParams, 0, sizeof(CodecAv1FilmGrainParams));
433         }
434 
435         // Error Concealment for Reference List
436         if (m_av1PicParams->m_picInfoFlags.m_fields.m_frameType != keyFrame && m_av1PicParams->m_picInfoFlags.m_fields.m_frameType != intraOnlyFrame)
437         {
438             DECODE_CHK_STATUS(m_refFrames.ErrorConcealment(*m_av1PicParams));
439         }
440 
441         return MOS_STATUS_SUCCESS;
442     }
443 
444     //Currently, m_bsBytesInBuffer of current bitstream buffer is not passed by application.
SetRequiredBitstreamSize(uint32_t requiredSize)445     MOS_STATUS Av1BasicFeature::SetRequiredBitstreamSize(uint32_t requiredSize)
446     {
447         DECODE_FUNC_CALL();
448         m_dataSize = requiredSize;
449         DECODE_NORMALMESSAGE("Estimate bitstream size in this Frame: %u", requiredSize);
450         return MOS_STATUS_SUCCESS;
451     }
452 
GetDecodeTargetFormat(MOS_FORMAT & format)453     MOS_STATUS Av1BasicFeature::GetDecodeTargetFormat(MOS_FORMAT& format)
454     {
455         if (m_av1PicParams->m_profile == 0)
456         {
457             if (m_av1PicParams->m_bitDepthIdx == 0)
458             {
459                 format = Format_NV12;
460             }
461             else if (m_av1PicParams->m_bitDepthIdx == 1)
462             {
463                 format = Format_P010;
464             }
465             else
466             {
467                 DECODE_ASSERTMESSAGE("Unsupported sub-sampling format!");
468                 return MOS_STATUS_UNKNOWN;
469             }
470         }
471         else
472         {
473             DECODE_ASSERTMESSAGE("The profile has not been supported yet!");
474             return MOS_STATUS_UNKNOWN;
475         }
476 
477         return MOS_STATUS_SUCCESS;
478     }
479 
SetPictureStructs(CodechalDecodeParams * decodeParams)480     MOS_STATUS Av1BasicFeature::SetPictureStructs(CodechalDecodeParams *decodeParams)
481     {
482         DECODE_FUNC_CALL();
483         m_curRenderPic                  = m_av1PicParams->m_currPic;
484         m_width                         = MOS_MAX(m_width, (uint32_t)m_av1PicParams->m_frameWidthMinus1 + 1);
485         m_height                        = MOS_MAX(m_height, (uint32_t)m_av1PicParams->m_frameHeightMinus1 + 1);
486         m_frameWidthAlignedMinBlk       = MOS_ALIGN_CEIL(m_av1PicParams->m_frameWidthMinus1 + 1, av1MinBlockWidth);
487         m_frameHeightAlignedMinBlk      = MOS_ALIGN_CEIL(m_av1PicParams->m_frameHeightMinus1 + 1, av1MinBlockHeight);
488 
489         m_refFrameIndexList.clear();
490         for (auto i = 0; i < av1TotalRefsPerFrame; i++)
491         {
492             uint8_t index = m_av1PicParams->m_refFrameMap[i].FrameIdx;
493             if (index < CODECHAL_MAX_DPB_NUM_AV1)
494             {
495                 m_refFrameIndexList.push_back(index);
496             }
497         }
498 
499         DECODE_CHK_STATUS(m_internalTarget.UpdateRefList(m_av1PicParams->m_currPic.FrameIdx, m_refFrameIndexList));
500 
501         if (m_filmGrainEnabled)
502         {
503             m_filmGrainProcParams = (FilmGrainProcParams*)&decodeParams->m_filmGrainProcParams;
504 
505             MOS_SURFACE surface = {};
506             MOS_ZeroMemory(&surface, sizeof(surface));
507             // if SFC enabled
508 #ifdef _DECODE_PROCESSING_SUPPORTED
509             if (decodeParams->m_procParams != nullptr)
510             {
511                 surface.dwWidth  = m_width;
512                 surface.dwHeight = m_height;
513                 DECODE_CHK_STATUS(GetDecodeTargetFormat(surface.Format));
514 
515                 auto procParams = (DecodeProcessingParams *)decodeParams->m_procParams;
516                 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(procParams->m_outputSurface));
517                 surface.TileModeGMM = procParams->m_outputSurface->TileModeGMM;
518             }
519             else
520             {
521 #endif
522                 surface = m_destSurface;
523 #ifdef _DECODE_PROCESSING_SUPPORTED
524             }
525 #endif
526             if (m_filmGrainProcParams->m_inputSurface == nullptr)
527             {
528                 DECODE_CHK_STATUS(m_internalTarget.ActiveCurSurf(
529                     m_av1PicParams->m_currPic.FrameIdx,
530                     &surface,
531                     IsMmcEnabled(), resourceOutputPicture, notLockableVideoMem));
532 
533                 m_filmGrainProcParams->m_inputSurface = m_internalTarget.GetCurSurf();
534             }
535             else
536             {
537                 DECODE_CHK_NULL(m_filmGrainProcParams->m_inputSurface);
538                 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(m_filmGrainProcParams->m_inputSurface));
539             }
540             m_filmGrainProcParams->m_inputSurface->UPlaneOffset.iYOffset
541                 = (m_filmGrainProcParams->m_inputSurface->UPlaneOffset.iSurfaceOffset - m_filmGrainProcParams->m_inputSurface->dwOffset) / m_filmGrainProcParams->m_inputSurface->dwPitch
542                   + m_filmGrainProcParams->m_inputSurface->RenderOffset.YUV.U.YOffset;
543 
544             // For AVP+FilmGrain+SFC scenario, SFC will be the final unit,
545             // set temp surface for film grain output
546 #ifdef _DECODE_PROCESSING_SUPPORTED
547             if (decodeParams->m_procParams != nullptr)
548             {
549                 if (m_fgInternalSurf == nullptr || m_allocator->ResourceIsNull(&m_fgInternalSurf->OsResource))
550                 {
551                     m_fgInternalSurf = m_allocator->AllocateSurface(
552                         m_width, m_height, "Internal film grain target surface", surface.Format, IsMmcEnabled(),
553                         resourceOutputPicture, notLockableVideoMem, surface.TileModeGMM);
554                 }
555                 else
556                 {
557                     DECODE_CHK_STATUS(m_allocator->Resize(m_fgInternalSurf, m_width, MOS_ALIGN_CEIL(m_height, 8),
558                         notLockableVideoMem, false, "Internal film grain target surface"));
559                 }
560                 DECODE_CHK_NULL(m_fgInternalSurf);
561 
562                 m_filmGrainProcParams->m_outputSurface = m_fgInternalSurf;
563             }
564 #endif
565             m_destSurface = *m_filmGrainProcParams->m_inputSurface;
566 
567             DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(m_filmGrainProcParams->m_outputSurface));
568             m_fgOutputSurf = *m_filmGrainProcParams->m_outputSurface;
569 #if (_DEBUG || _RELEASE_INTERNAL)
570             m_fgOutputSurfList[m_curRenderPic.FrameIdx] = m_fgOutputSurf;
571 #endif
572         }
573 
574         DECODE_CHK_STATUS(UpdateDefaultCdfTable());
575         DECODE_CHK_STATUS(m_refFrames.UpdatePicture(*m_av1PicParams));
576         DECODE_CHK_STATUS(m_tempBuffers.UpdatePicture(m_av1PicParams->m_currPic.FrameIdx, m_refFrameIndexList));
577         DECODE_CHK_STATUS(SetSegmentData(*m_av1PicParams));
578 
579         DECODE_CHK_STATUS(CalculateGlobalMotionParams());
580 
581         return MOS_STATUS_SUCCESS;
582     }
583 
SetTileStructs()584     MOS_STATUS Av1BasicFeature::SetTileStructs()
585     {
586         DECODE_FUNC_CALL();
587 
588         DECODE_CHK_STATUS(m_tileCoding.Update(*m_av1PicParams, m_av1TileParams));
589 
590         return MOS_STATUS_SUCCESS;
591     }
592 
SetSegmentData(CodecAv1PicParams & picParams)593     MOS_STATUS Av1BasicFeature::SetSegmentData(CodecAv1PicParams &picParams)
594     {
595         DECODE_FUNC_CALL();
596 
597         // Configure Segment ID read buffer SegmentMapIsZeroFlag
598         picParams.m_av1SegData.m_segmentMapIsZeroFlag    = false;
599         picParams.m_av1SegData.m_segIdBufStreamInEnable  = false;
600         picParams.m_av1SegData.m_segIdBufStreamOutEnable = false;
601         uint8_t prevFrameIdx = m_refFrames.GetPrimaryRefIdx();
602 
603         if (picParams.m_av1SegData.m_enabled &&
604             (picParams.m_av1SegData.m_temporalUpdate || !picParams.m_av1SegData.m_updateMap))
605         {
606             if(picParams.m_av1SegData.m_temporalUpdate)
607             {
608                 DECODE_ASSERT((picParams.m_primaryRefFrame != av1PrimaryRefNone) &&
609                                         picParams.m_av1SegData.m_updateMap);
610             }
611 
612             if (!picParams.m_av1SegData.m_updateMap)
613             {
614                 DECODE_ASSERT((picParams.m_primaryRefFrame != av1PrimaryRefNone) &&
615                                        !picParams.m_av1SegData.m_temporalUpdate);
616             }
617 
618             if (m_refFrames.CheckSegForPrimFrame(*m_av1PicParams))
619             {
620                 picParams.m_av1SegData.m_segmentMapIsZeroFlag = false;
621                 picParams.m_av1SegData.m_segIdBufStreamInEnable = true;
622             }
623             else
624             {
625                 picParams.m_av1SegData.m_segmentMapIsZeroFlag = true;
626                 picParams.m_av1SegData.m_segIdBufStreamInEnable = false;
627             }
628         }
629 
630         if(picParams.m_av1SegData.m_enabled && picParams.m_av1SegData.m_updateMap)
631         {
632             picParams.m_av1SegData.m_segIdBufStreamOutEnable = true;
633         }
634 
635         // Calculate m_lastActiveSegmentId/m_preSkipSegmentIdFlag
636         if (!picParams.m_av1SegData.m_enabled)
637         {
638             picParams.m_av1SegData.m_lastActiveSegmentId = 0;
639             picParams.m_av1SegData.m_preSkipSegmentIdFlag = 0;
640         }
641         else if (picParams.m_av1SegData.m_updateData)
642         {
643             picParams.m_av1SegData.m_lastActiveSegmentId = 0;
644             picParams.m_av1SegData.m_preSkipSegmentIdFlag = 0;
645 
646             for (uint8_t seg = 0; seg < av1MaxSegments; seg++)
647             {
648                 for (int lvl = 0; lvl < segLvlMax; lvl++)
649                 {
650                     if (picParams.m_av1SegData.m_featureMask[seg] & (1 << lvl))
651                     {
652                         picParams.m_av1SegData.m_preSkipSegmentIdFlag |= (lvl >= segLvlRefFrame);
653                         picParams.m_av1SegData.m_lastActiveSegmentId = seg;
654                     }
655                 }
656             }
657         }
658         else if (picParams.m_primaryRefFrame != av1PrimaryRefNone)//copy from primary_ref_frame
659         {
660             picParams.m_av1SegData.m_lastActiveSegmentId = m_refFrames.m_refList[prevFrameIdx]->m_lastActiveSegmentId;
661             picParams.m_av1SegData.m_preSkipSegmentIdFlag = m_refFrames.m_refList[prevFrameIdx]->m_preSkipSegmentIdFlag;
662         }
663 
664         //record m_lastActiveSegmentId/m_preSkipSegmentIdFlag into DPB for future frame decoding
665         m_refFrames.m_currRefList->m_lastActiveSegmentId = picParams.m_av1SegData.m_lastActiveSegmentId;
666         m_refFrames.m_currRefList->m_preSkipSegmentIdFlag = picParams.m_av1SegData.m_preSkipSegmentIdFlag;
667 
668         return MOS_STATUS_SUCCESS;
669     }
670 
CalculateGlobalMotionParams()671     MOS_STATUS Av1BasicFeature::CalculateGlobalMotionParams()
672     {
673         DECODE_FUNC_CALL();
674 
675         for (uint32_t ref = (uint32_t)lastFrame; ref <= (uint32_t)altRefFrame; ref++)
676         {
677             if (m_av1PicParams->m_wm[ref - lastFrame].m_wmtype >= rotzoom)
678             {
679                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[2] -= (1 << av1WarpedModelPrecBits);
680                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[2] >>= av1GmAlphaPrecDiff;
681                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[3] >>= av1GmAlphaPrecDiff;
682             }
683 
684             if (m_av1PicParams->m_wm[ref - lastFrame].m_wmtype == affine)
685             {
686                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[4] >>= av1GmAlphaPrecDiff;
687                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[5] -= (1 << av1WarpedModelPrecBits);
688                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[5] >>= av1GmAlphaPrecDiff;
689             }
690             else
691             {
692                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[4] = -m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[3];
693                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[5] = m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[2];
694             }
695 
696             if (m_av1PicParams->m_wm[ref - lastFrame].m_wmtype >= translation)
697             {
698                 int32_t transDecFactorShift = (m_av1PicParams->m_wm[ref - lastFrame].m_wmtype == translation) ?
699                     (av1GmTransOnlyPrecDiff + (m_av1PicParams->m_picInfoFlags.m_fields.m_allowHighPrecisionMv ? 0 : 1)) : av1GmTransPrecDiff;
700 
701                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[0] >>= transDecFactorShift;
702                 m_av1PicParams->m_wm[ref - lastFrame].m_wmmat[1] >>= transDecFactorShift;
703             }
704         }
705 
706         return MOS_STATUS_SUCCESS;
707     }
708 
InitDefaultFrameContextBuffer(uint16_t * ctxBuffer,uint8_t index)709     MOS_STATUS Av1BasicFeature::InitDefaultFrameContextBuffer(
710         uint16_t              *ctxBuffer,
711         uint8_t               index)
712     {
713         DECODE_CHK_NULL(ctxBuffer);
714 
715         //initialize the layout and default table info for each syntax element
716         struct SyntaxElementCdfTableLayout syntaxElementsLayout[syntaxElementMax] =
717         {
718         //m_entryCountPerCL, m_entryCountTotal, m_startCL, *m_srcInitBuffer
719         //PartI: Intra
720         { 30,    12  ,    0  ,    (uint16_t *)&defaultPartitionCdf8x8[0][0] },        //    partition_8x8
721         { 27,    108 ,    1  ,    (uint16_t *)&defaultPartitionCdfNxN[0][0] },        //    partition
722         { 28,    28  ,    5  ,    (uint16_t *)&defaultPartitionCdf128x128[0][0] },    //    partition_128x128
723         { 32,    3   ,    6  ,    (uint16_t *)&defaultSkipCdfs[0][0] },               //    skip
724         { 30,    3   ,    7  ,    (uint16_t *)&defaultDeltaQCdf[0] },                 //    delta_q
725         { 30,    3   ,    8  ,    (uint16_t *)&defaultDeltaLfCdf[0] },                //    delta_lf
726         { 30,    12  ,    9  ,    (uint16_t *)&defaultDeltaLfMultiCdf[0][0] },        //    delta_lf_multi
727         { 28,    21  ,    10 ,    (uint16_t *)&defaultSpatialPredSegTreeCdf[0][0] },  //    segment_id
728         { 24,    300 ,    11 ,    (uint16_t *)&defaultKfYModeCdf[0][0][0] },          //    intra_y_mode
729         { 24,    156 ,    24 ,    (uint16_t *)&defaultUvModeCdf0[0][0] },             //    uv_mode_0
730         { 26,    169 ,    31 ,    (uint16_t *)&defaultUvModeCdf1[0][0] },             //    uv_mode_1
731         { 32,    21  ,    38 ,    (uint16_t *)&defaultPaletteYModeCdf[0][0][0] },     //    palette_y_mode
732         { 32,    2   ,    39 ,    (uint16_t *)&defaultPaletteUvModeCdf[0][0] },       //    palette_uv_mode
733         { 30,    42  ,    40 ,    (uint16_t *)&defaultPaletteYSizeCdf[0][0] },        //    palette_y_size
734         { 30,    42  ,    42 ,    (uint16_t *)&defaultPaletteUvSizeCdf[0][0] },       //    palette_uv_size
735         { 30,    312 ,    44 ,    (uint16_t *)&defaultIntraExtTxCdf1[0][0][0] },      //    intra_tx_type_1
736         { 32,    208 ,    55 ,    (uint16_t *)&defaultIntraExtTxCdf2[0][0][0] },      //    intra_tx_type_2
737         { 32,    3   ,    62 ,    (uint16_t *)&defaultTxSizeCdf0[0][0] },             //    depth_0
738         { 32,    18  ,    63 ,    (uint16_t *)&defaultTxSizeCdf[0][0][0] },           //    depth
739         { 28,    7   ,    64 ,    (uint16_t *)&defaultCflSignCdf[0] },                //    cfl_joint_sign
740         { 30,    90  ,    65 ,    (uint16_t *)&defaultCflAlphaCdf[0][0] },            //    cdf_alpha
741         { 30,    48  ,    68 ,    (uint16_t *)&defaultAngleDeltaCdf[0][0] },          //    angle_delta
742         { 32,    5   ,    70 ,    (uint16_t *)&defaultPaletteYColorIndexCdf0[0][0] }, //    palette_y_color_idx_0
743         { 32,    10  ,    71 ,    (uint16_t *)&defaultPaletteYColorIndexCdf1[0][0] }, //    palette_y_color_idx_1
744         { 30,    15  ,    72 ,    (uint16_t *)&defaultPaletteYColorIndexCdf2[0][0] }, //    palette_y_color_idx_2
745         { 32,    20  ,    73 ,    (uint16_t *)&defaultPaletteYColorIndexCdf3[0][0] }, //    palette_y_color_idx_3
746         { 30,    25  ,    74 ,    (uint16_t *)&defaultPaletteYColorIndexCdf4[0][0] }, //    palette_y_color_idx_4
747         { 30,    30  ,    75 ,    (uint16_t *)&defaultPaletteYColorIndexCdf5[0][0] }, //    palette_y_color_idx_5
748         { 28,    35  ,    76 ,    (uint16_t *)&defaultPaletteYColorIndexCdf6[0][0] }, //    palette_y_color_idx_6
749         { 32,    5   ,    78 ,    (uint16_t *)&defaultPaletteUvColorIndexCdf0[0][0] }, //    palette_uv_color_idx_0
750         { 32,    10  ,    79 ,    (uint16_t *)&defaultPaletteUvColorIndexCdf1[0][0] }, //    palette_uv_color_idx_1
751         { 30,    15  ,    80 ,    (uint16_t *)&defaultPaletteUvColorIndexCdf2[0][0] }, //    palette_uv_color_idx_2
752         { 32,    20  ,    81 ,    (uint16_t *)&defaultPaletteUvColorIndexCdf3[0][0] }, //    palette_uv_color_idx_3
753         { 30,    25  ,    82 ,    (uint16_t *)&defaultPaletteUvColorIndexCdf4[0][0] }, //    palette_uv_color_idx_4
754         { 30,    30  ,    83 ,    (uint16_t *)&defaultPaletteUvColorIndexCdf5[0][0] }, //    palette_uv_color_idx_5
755         { 28,    35  ,    84 ,    (uint16_t *)&defaultPaletteUvColorIndexCdf6[0][0] }, //    palette_uv_color_idx_6
756         //coeff cdfs addressed by index
757         { 32,    65  ,    86 ,    (uint16_t *)&av1DefaultTxbSkipCdfs[index][0][0][0] },               //    txb_skip
758         { 32,    16  ,    89 ,    (uint16_t *)&av1DefaultEobMulti16Cdfs[index][0][0][0] },            //    eob_pt_0
759         { 30,    20  ,    90 ,    (uint16_t *)&av1DefaultEobMulti32Cdfs[index][0][0][0] },            //    eob_pt_1
760         { 30,    24  ,    91 ,    (uint16_t *)&av1DefaultEobMulti64Cdfs[index][0][0][0] },            //    eob_pt_2
761         { 28,    28  ,    92 ,    (uint16_t *)&av1DefaultEobMulti128Cdfs[index][0][0][0] },           //    eob_pt_3
762         { 32,    32  ,    93 ,    (uint16_t *)&av1DefaultEobMulti256Cdfs[index][0][0][0] },           //    eob_pt_4
763         { 27,    36  ,    94 ,    (uint16_t *)&av1DefaultEobMulti512Cdfs[index][0][0][0] },           //    eob_pt_5
764         { 30,    40  ,    96 ,    (uint16_t *)&av1DefaultEobMulti1024Cdfs[index][0][0][0] },          //    eob_pt_6
765         { 32,    90  ,    98 ,    (uint16_t *)&av1DefaultEobExtraCdfs[index][0][0][0][0] },           //    eob_extra
766         { 32,    80  ,    101,    (uint16_t *)&av1DefaultCoeffBaseEobMultiCdfs[index][0][0][0][0] },  //    coeff_base_eob
767         { 30,    1260,    104,    (uint16_t *)&av1DefaultCoeffBaseMultiCdfs[index][0][0][0][0] },     //    coeff_base
768         { 32,    6   ,    146,    (uint16_t *)&av1DefaultDcSignCdfs[index][0][0][0] },                //    dc_sign
769         { 30,    630 ,    147,    (uint16_t *)&av1DefaultCoeffLpsMultiCdfs[index][0][0][0][0] },      //    coeff_br
770         { 32,    2   ,    168,    (uint16_t *)&defaultSwitchableRestoreCdf[0] },  //    switchable_restore
771         { 32,    1   ,    169,    (uint16_t *)&defaultWienerRestoreCdf[0] },      //    wiener_restore
772         { 32,    1   ,    170,    (uint16_t *)&defaultSgrprojRestoreCdf[0] },     //    sgrproj_restore
773         { 32,    1   ,    171,    (uint16_t *)&defaultIntrabcCdf[0] },            //    use_intrabc
774         { 32,    22  ,    172,    (uint16_t *)&default_filter_intra_cdfs[0][0] }, //    use_filter_intra
775         { 32,    4   ,    173,    (uint16_t *)&defaultFilterIntraModeCdf[0] },    //    filter_intra_mode
776         { 30,    3   ,    174,    (uint16_t *)&defaultJointCdf[0] },              //    dv_joint_type
777         { 32,    2   ,    175,    (uint16_t *)&defaultSignCdf[0][0] },            //    dv_sign
778         { 32,    20  ,    176,    (uint16_t *)&defaultBitsCdf[0][0][0] },         //    dv_sbits
779         { 30,    20  ,    177,    (uint16_t *)&defaultClassesCdf[0][0] },         //    dv_class
780         { 32,    2   ,    178,    (uint16_t *)&defaultClass0Cdf[0][0] },          //    dv_class0
781         { 30,    6   ,    179,    (uint16_t *)&defaultFpCdf[0][0] },              //    dv_fr
782         { 30,    12  ,    180,    (uint16_t *)&defaultClass0FpCdf[0][0][0] },     //    dv_class0_fr
783         { 32,    2   ,    181,    (uint16_t *)&defaultHpCdf[0][0] },              //    dv_hp
784         { 32,    2   ,    182,    (uint16_t *)&defaultClass0HpCdf[0][0] },        //    dv_class0_hp
785         //PartII: Inter
786         { 32,    3   ,    183,    (uint16_t *)&defaultSkipModeCdfs[0][0] },           //    skip_mode
787         { 32,    3   ,    184,    (uint16_t *)&defaultSegmentPredCdf[0][0] },         //    pred_seg_id
788         { 24,    48  ,    185,    (uint16_t *)&defaultIfYModeCdf[0][0] },             //    y_mode
789         { 30,    60  ,    187,    (uint16_t *)&defaultInterExtTxCdf1[0][0] },         //    inter_tx_type_1
790         { 22,    44  ,    189,    (uint16_t *)&defaultInterExtTxCdf2[0][0] },         //    inter_tx_type_2
791         { 32,    4   ,    191,    (uint16_t *)&defaultInterExtTxCdf3[0][0] },         //    inter_tx_type_3
792         { 32,    4   ,    192,    (uint16_t *)&defaultIntraInterCdf[0][0] },          //    is_inter
793         { 32,    21  ,    193,    (uint16_t *)&defaultTxfmPartitionCdf[0][0] },       //    tx_split
794         { 32,    5   ,    194,    (uint16_t *)&defaultCompInterCdf[0][0] },           //    ref_mode
795         { 32,    5   ,    195,    (uint16_t *)&defaultCompRefTypeCdf[0][0] },         //    comp_ref_type
796         { 32,    9   ,    196,    (uint16_t *)&defaultUniCompRefCdf[0][0][0] },       //    unidir_comp_ref
797         { 32,    9   ,    197,    (uint16_t *)&defaultCompRefCdf[0][0][0] },          //    ref_bit
798         { 32,    6   ,    198,    (uint16_t *)&defaultCompBwdrefCdf[0][0][0] },       //    ref_bit_bwd
799         { 32,    18  ,    199,    (uint16_t *)&defaultSingleRefCdf[0][0][0] },        //    single_ref_bit
800         { 28,    56  ,    200,    (uint16_t *)&defaultInterCompoundModeCdf[0][0] },   // inter_compound_mode
801         { 32,    6   ,    202,    (uint16_t *)&defaultNewmvCdf[0][0] },               //    is_newmv
802         { 32,    2   ,    203,    (uint16_t *)&defaultZeromvCdf[0][0] },              //    is_zeromv
803         { 32,    6   ,    204,    (uint16_t *)&defaultRefmvCdf[0][0] },               //    is_refmv
804         { 30,    3   ,    205,    (uint16_t *)&defaultJointCdf[0] },                  //    mv_joint_type
805         { 32,    2   ,    206,    (uint16_t *)&defaultSignCdf[0][0] },                //    mv_sign
806         { 32,    20  ,    207,    (uint16_t *)&defaultBitsCdf[0][0][0] },             //    mv_sbits
807         { 30,    20  ,    208,    (uint16_t *)&defaultClassesCdf[0][0] },             //    mv_class
808         { 32,    2   ,    209,    (uint16_t *)&defaultClass0Cdf[0][0] },              //    mv_class0
809         { 30,    6   ,    210,    (uint16_t *)&defaultFpCdf[0][0] },                  //    mv_fr
810         { 30,    12  ,    211,    (uint16_t *)&defaultClass0FpCdf[0][0][0] },         //    mv_class0_fr
811         { 32,    2   ,    212,    (uint16_t *)&defaultHpCdf[0][0] },                  //    mv_hp
812         { 32,    2   ,    213,    (uint16_t *)&defaultClass0HpCdf[0][0] },            //    mv_class0_hp
813         { 32,    4   ,    214,    (uint16_t *)&defaultInterintraCdf[0][0] },          //    interintra
814         { 30,    12  ,    215,    (uint16_t *)&defaultInterintraModeCdf[0][0] },      //    interintra_mode
815         { 32,    22  ,    216,    (uint16_t *)&defaultWedgeInterintraCdf[0][0] },     //    use_wedge_interintra
816         { 30,    330 ,    217,    (uint16_t *)&defaultWedgeIdxCdf[0][0] },            //    wedge_index
817         { 32,    3   ,    228,    (uint16_t *)&defaultDrlCdf[0][0] },                 //    drl_idx
818         { 32,    22  ,    229,    (uint16_t *)&defaultObmcCdf[0][0] },                //    obmc_motion_mode
819         { 32,    44  ,    230,    (uint16_t *)&defaultMotionModeCdf[0][0] },          //    non_obmc_motion_mode
820         { 32,    6   ,    232,    (uint16_t *)&defaultCompGroupIdxCdfs[0][0] },       //    comp_group_idx
821         { 32,    6   ,    233,    (uint16_t *)&defaultCompoundIdxCdfs[0][0] },        //    compound_idx
822         { 32,    22  ,    234,    (uint16_t *)&defaultCompoundTypeCdf[0][0] },        //    interinter_compound_type
823         { 32,    32  ,    235,    (uint16_t *)&defaultSwitchableInterpCdf[0][0] },    //    switchable_interp
824         };
825 
826         for (auto idx = (uint32_t)partition8x8; idx < (uint32_t)syntaxElementMax; idx++)
827         {
828             DECODE_CHK_STATUS(SyntaxElementCdfTableInit(
829                 ctxBuffer,
830                 syntaxElementsLayout[idx]));
831         }
832 
833         return MOS_STATUS_SUCCESS;
834     }
835 
SyntaxElementCdfTableInit(uint16_t * ctxBuffer,SyntaxElementCdfTableLayout SyntaxElement)836     MOS_STATUS Av1BasicFeature::SyntaxElementCdfTableInit(
837         uint16_t                    *ctxBuffer,
838         SyntaxElementCdfTableLayout SyntaxElement)
839     {
840         DECODE_CHK_NULL(SyntaxElement.m_srcInitBuffer);
841 
842         uint16_t    entryCountPerCL = SyntaxElement.m_entryCountPerCL;  //one entry means one uint16_t value
843         uint16_t    entryCountTotal = SyntaxElement.m_entryCountTotal;  //total number of entrie for this Syntax element's CDF tables
844         uint16_t    startCL         = SyntaxElement.m_startCL;
845 
846         uint16_t *src = SyntaxElement.m_srcInitBuffer;
847         uint16_t *dst = ctxBuffer + startCL * 32;   //one CL equals to 32 uint16_t
848         uint16_t entryCountLeft = entryCountTotal;
849         while (entryCountLeft >= entryCountPerCL)
850         {
851             //copy one CL
852             MOS_SecureMemcpy(dst, entryCountPerCL * sizeof(uint16_t), src, entryCountPerCL * sizeof(uint16_t));
853             entryCountLeft -= entryCountPerCL;
854 
855             //go to next CL
856             src += entryCountPerCL;
857             dst += 32;
858         };
859         //copy the remaining which are less than a CL
860         if (entryCountLeft > 0)
861         {
862             MOS_SecureMemcpy(dst, entryCountLeft * sizeof(uint16_t), src, entryCountLeft * sizeof(uint16_t));
863         }
864 
865         return MOS_STATUS_SUCCESS;
866     }
867 
UpdateDefaultCdfTable()868     MOS_STATUS Av1BasicFeature :: UpdateDefaultCdfTable()
869     {
870         DECODE_FUNC_CALL();
871 
872         if (!m_defaultFcInitialized)
873         {
874             for (uint8_t index = 0; index < av1DefaultCdfTableNum; index++)
875             {
876                 m_defaultCdfBuffers[index] = m_allocator->AllocateBuffer(
877                     MOS_ALIGN_CEIL(m_cdfMaxNumBytes, CODECHAL_PAGE_SIZE), "TempCdfTableBuffer",
878                     resourceInternalRead, lockableVideoMem);
879                 DECODE_CHK_NULL(m_defaultCdfBuffers[index]);
880 
881                 auto data = (uint16_t *)m_allocator->LockResourceForWrite(&m_defaultCdfBuffers[index]->OsResource);
882                 DECODE_CHK_NULL(data);
883 
884                 // reset all CDF tables to default values
885                 DECODE_CHK_STATUS(InitDefaultFrameContextBuffer(data, index));
886             }
887 
888             m_defaultFcInitialized = true;//set only once, won't set again
889         }
890 
891         //Calculate the current frame's Coeff CDF Q Context ID, that is the Coeff CDF Buffer index
892         if (m_av1PicParams->m_baseQindex <= 20)    m_curCoeffCdfQCtx = 0;
893         else if (m_av1PicParams->m_baseQindex <= 60)    m_curCoeffCdfQCtx = 1;
894         else if (m_av1PicParams->m_baseQindex <= 120)   m_curCoeffCdfQCtx = 2;
895         else m_curCoeffCdfQCtx = 3;
896 
897         m_defaultCdfBufferInUse = m_defaultCdfBuffers[m_curCoeffCdfQCtx];
898 
899         return MOS_STATUS_SUCCESS;
900     }
901 
902 }  // namespace decode
903