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