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_reference_frames_g12.cpp
24 //! \brief    Defines reference list related logic for av1 decode
25 //!
26 
27 #include "decode_av1_basic_feature_g12.h"
28 #include "decode_utils.h"
29 #include "codechal_utilities.h"
30 #include "decode_av1_reference_frames_g12.h"
31 #include "codec_def_decode_av1.h"
32 
33 namespace decode
34 {
Av1ReferenceFramesG12()35     Av1ReferenceFramesG12::Av1ReferenceFramesG12()
36     {
37         memset(m_refList, 0, sizeof(m_refList));
38     }
39 
Init(Av1BasicFeatureG12 * basicFeature,DecodeAllocator & allocator)40     MOS_STATUS Av1ReferenceFramesG12::Init(Av1BasicFeatureG12 *basicFeature, DecodeAllocator &allocator)
41     {
42         DECODE_FUNC_CALL();
43 
44         DECODE_CHK_NULL(basicFeature);
45         m_basicFeature = basicFeature;
46         m_allocator = &allocator;
47         DECODE_CHK_NULL(m_allocator);
48         DECODE_CHK_STATUS(
49             CodecHalAllocateDataList((CODEC_REF_LIST_AV1 **)m_refList, CODECHAL_MAX_DPB_NUM_LST_AV1));
50 
51         return MOS_STATUS_SUCCESS;
52     }
53 
~Av1ReferenceFramesG12()54     Av1ReferenceFramesG12::~Av1ReferenceFramesG12()
55     {
56         DECODE_FUNC_CALL();
57 
58         CodecHalFreeDataList(m_refList, CODECHAL_MAX_DPB_NUM_LST_AV1);
59         m_activeReferenceList.clear();
60     }
61 
UpdatePicture(CodecAv1PicParams & picParams)62     MOS_STATUS Av1ReferenceFramesG12::UpdatePicture(CodecAv1PicParams &picParams)
63     {
64         DECODE_FUNC_CALL();
65 
66         DECODE_CHK_STATUS(UpdateCurFrame(picParams));
67 
68         uint8_t refPicIndex = picParams.m_refFrameIdx[picParams.m_primaryRefFrame];
69         auto refPic = picParams.m_refFrameMap[refPicIndex];
70         if (!CodecHal_PictureIsInvalid(refPic))
71         {
72             m_prevFrameIdx = refPic.FrameIdx;
73         }
74 
75         if (picParams.m_picInfoFlags.m_fields.m_largeScaleTile && picParams.m_anchorFrameList != nullptr)
76         {
77             DECODE_CHK_STATUS(UpdateCurRefList(picParams));
78         }
79 
80         return MOS_STATUS_SUCCESS;
81     }
82 
GetActiveReferenceList(CodecAv1PicParams & picParams,CodecAv1TileParams & tileParams)83     const std::vector<uint8_t> &Av1ReferenceFramesG12::GetActiveReferenceList(CodecAv1PicParams &picParams, CodecAv1TileParams &tileParams)
84     {
85         DECODE_FUNC_CALL();
86 
87         m_activeReferenceList.clear();
88         for (auto i = 0; i < av1NumInterRefFrames; i++)
89         {
90             if (picParams.m_picInfoFlags.m_fields.m_largeScaleTile)
91             {
92                 DECODE_ASSERT(m_basicFeature->m_tileCoding.m_curTile < (int32_t)m_basicFeature->m_tileCoding.m_numTiles);
93                 uint8_t frameIdx = tileParams.m_anchorFrameIdx.FrameIdx;
94                 if (frameIdx >= CODECHAL_MAX_DPB_NUM_LST_AV1)
95                 {
96                     continue;
97                 }
98                 m_activeReferenceList.push_back(frameIdx);
99             }
100             else
101             {
102                 PCODEC_PICTURE refFrameList = &(picParams.m_refFrameMap[0]);
103                 uint8_t refPicIndex = picParams.m_refFrameIdx[i];
104                 if (refPicIndex >= av1TotalRefsPerFrame)
105                 {
106                     continue;
107                 }
108                 m_activeReferenceList.push_back(refFrameList[refPicIndex].FrameIdx);
109             }
110         }
111 
112         return m_activeReferenceList;
113     }
114 
GetReferenceByFrameIndex(uint8_t frameIndex)115     PMOS_RESOURCE Av1ReferenceFramesG12::GetReferenceByFrameIndex(uint8_t frameIndex)
116     {
117         DECODE_FUNC_CALL();
118 
119         if (frameIndex > CODECHAL_MAX_DPB_NUM_AV1)
120         {
121             DECODE_ASSERTMESSAGE("Invalid reference frame index");
122             return nullptr;
123         }
124 
125         PCODEC_REF_LIST_AV1 ref = m_refList[frameIndex];
126 
127         if (ref == nullptr || m_allocator->ResourceIsNull(&(ref->resRefPic)))
128         {
129             return nullptr;
130         }
131 
132         return &(ref->resRefPic);
133     }
134 
GetValidReference()135     PMOS_RESOURCE Av1ReferenceFramesG12::GetValidReference()
136     {
137         DECODE_FUNC_CALL();
138 
139         if (m_basicFeature->m_av1PicParams == nullptr)
140         {
141             return nullptr;
142         }
143         auto m_picParams = m_basicFeature->m_av1PicParams;
144 
145         for(auto i = 0; i < av1NumInterRefFrames; i++)
146         {
147             auto index = m_picParams->m_refFrameIdx[i];
148             if (index >= av1TotalRefsPerFrame)
149             {
150                 continue;
151             }
152             uint8_t frameIdx = m_picParams->m_refFrameMap[index].FrameIdx;
153             if (frameIdx >= m_basicFeature->m_maxFrameIndex)
154             {
155                 continue;
156             }
157             PMOS_RESOURCE buffer = GetReferenceByFrameIndex(frameIdx);
158             if (buffer != nullptr)
159             {
160                 return buffer;
161             }
162         }
163 
164         return &(m_basicFeature->m_destSurface.OsResource);
165     }
166 
GetValidReferenceIndex(uint8_t * validRefIndex)167     MOS_STATUS Av1ReferenceFramesG12::GetValidReferenceIndex(uint8_t *validRefIndex)
168     {
169         DECODE_FUNC_CALL();
170 
171         if (m_basicFeature->m_av1PicParams == nullptr)
172         {
173             return MOS_STATUS_INVALID_PARAMETER;
174         }
175         auto m_picParams = m_basicFeature->m_av1PicParams;
176 
177         for (auto i = 0; i < av1NumInterRefFrames; i++)
178         {
179             auto    index    = m_picParams->m_refFrameIdx[i];
180             uint8_t frameIdx = m_picParams->m_refFrameMap[index].FrameIdx;
181             if (frameIdx >= m_basicFeature->m_maxFrameIndex)
182             {
183                 continue;
184             }
185             PMOS_RESOURCE buffer = GetReferenceByFrameIndex(frameIdx);
186             if (buffer != nullptr)
187             {
188                 *validRefIndex = frameIdx;
189                 return MOS_STATUS_SUCCESS;
190             }
191         }
192 
193         *validRefIndex = m_basicFeature->m_av1PicParams->m_currPic.FrameIdx;
194         return MOS_STATUS_SUCCESS;
195     }
196 
InsertAnchorFrame(CodecAv1PicParams & picParams)197     MOS_STATUS Av1ReferenceFramesG12::InsertAnchorFrame(CodecAv1PicParams &picParams)
198     {
199         DECODE_FUNC_CALL();
200 
201         DECODE_CHK_COND(((!picParams.m_picInfoFlags.m_fields.m_largeScaleTile && (picParams.m_currPic.FrameIdx >= CODECHAL_MAX_DPB_NUM_AV1)) ||
202                             picParams.m_picInfoFlags.m_fields.m_largeScaleTile && (picParams.m_currPic.FrameIdx >= CODECHAL_MAX_DPB_NUM_LST_AV1)),
203             "Invalid frame index of current frame");
204 
205         m_currRefList = m_refList[picParams.m_currPic.FrameIdx];
206 
207         DECODE_CHK_STATUS(m_allocator->RegisterResource(&m_basicFeature->m_destSurface.OsResource));
208 
209         m_currRefList->resRefPic        = m_basicFeature->m_destSurface.OsResource;
210         m_currRefList->m_frameWidth     = picParams.m_superResUpscaledWidthMinus1 + 1;  //DPB buffer are always stored in full frame resolution (Super-Res up-scaled resolution)
211         m_currRefList->m_frameHeight    = picParams.m_superResUpscaledHeightMinus1 + 1;
212         m_currRefList->m_miCols         = MOS_ALIGN_CEIL(picParams.m_frameWidthMinus1 + 1, 8) >> av1MiSizeLog2;
213         m_currRefList->m_miRows         = MOS_ALIGN_CEIL(picParams.m_frameHeightMinus1 + 1, 8) >> av1MiSizeLog2;
214 
215         return MOS_STATUS_SUCCESS;
216     }
217 
UpdateCurRefList(const CodecAv1PicParams & picParams)218     MOS_STATUS Av1ReferenceFramesG12::UpdateCurRefList(const CodecAv1PicParams &picParams)
219     {
220         DECODE_FUNC_CALL();
221 
222         // override internal reference list with anchor_frame_list passed from APP
223         for (auto i = 0; i < picParams.m_anchorFrameNum; i++)
224         {
225             DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&picParams.m_anchorFrameList[i]));
226             DECODE_CHK_STATUS(m_allocator->RegisterResource(&(picParams.m_anchorFrameList[i].OsResource)));
227 
228             m_refList[i]->resRefPic        = picParams.m_anchorFrameList[i].OsResource;
229             m_refList[i]->m_frameWidth     = picParams.m_superResUpscaledWidthMinus1 + 1;  //DPB buffer are always stored in full frame resolution (Super-Res up-scaled resolution)
230             m_refList[i]->m_frameHeight    = picParams.m_superResUpscaledHeightMinus1 + 1;
231             m_refList[i]->m_miCols         = MOS_ALIGN_CEIL(picParams.m_frameWidthMinus1 + 1, 8) >> av1MiSizeLog2;
232             m_refList[i]->m_miRows         = MOS_ALIGN_CEIL(picParams.m_frameHeightMinus1 + 1, 8) >> av1MiSizeLog2;
233         }
234 
235         return MOS_STATUS_SUCCESS;
236     }
237 
UpdateCurResource(const PCODEC_REF_LIST_AV1 pCurRefList)238     MOS_STATUS Av1ReferenceFramesG12::UpdateCurResource(const PCODEC_REF_LIST_AV1 pCurRefList)
239     {
240         DECODE_FUNC_CALL();
241         DECODE_CHK_NULL(pCurRefList);
242         DECODE_CHK_NULL(m_basicFeature->m_av1PicParams);
243         auto m_picParams = m_basicFeature->m_av1PicParams;
244 
245         // Overwrite the actual surface height with the coded height and width of the frame
246         // for AV1 since it's possible for a AV1 frame to change size during playback
247         if (!m_picParams->m_picInfoFlags.m_fields.m_largeScaleTile)
248         {
249             m_basicFeature->m_destSurface.dwWidth  = m_picParams->m_superResUpscaledWidthMinus1 + 1;  //DPB buffer size may be larger than the YUV data size to put in it, so override it
250             m_basicFeature->m_destSurface.dwHeight = m_picParams->m_superResUpscaledHeightMinus1 + 1;
251         }
252 
253         pCurRefList->resRefPic = m_basicFeature->m_destSurface.OsResource;
254         return MOS_STATUS_SUCCESS;
255     }
256 
UpdateCurFrame(const CodecAv1PicParams & picParams)257     MOS_STATUS Av1ReferenceFramesG12::UpdateCurFrame(const CodecAv1PicParams &picParams)
258     {
259         DECODE_FUNC_CALL();
260 
261         DECODE_CHK_COND(((!picParams.m_picInfoFlags.m_fields.m_largeScaleTile && (picParams.m_currPic.FrameIdx >= CODECHAL_MAX_DPB_NUM_AV1)) ||
262                             picParams.m_picInfoFlags.m_fields.m_largeScaleTile && (picParams.m_currPic.FrameIdx >= CODECHAL_MAX_DPB_NUM_LST_AV1)),
263                         "Invalid frame index of current frame");
264         m_currRefList = m_refList[picParams.m_currPic.FrameIdx];
265         MOS_ZeroMemory(m_currRefList, sizeof(CODEC_REF_LIST_AV1));
266 
267         DECODE_CHK_STATUS(UpdateCurResource(m_currRefList));
268         m_currRefList->m_frameWidth     = picParams.m_superResUpscaledWidthMinus1 + 1;  //DPB buffer are always stored in full frame resolution (Super-Res up-scaled resolution)
269         m_currRefList->m_frameHeight    = picParams.m_superResUpscaledHeightMinus1 + 1;
270         m_currRefList->m_miCols         = MOS_ALIGN_CEIL(picParams.m_frameWidthMinus1 + 1, 8) >> av1MiSizeLog2;
271         m_currRefList->m_miRows         = MOS_ALIGN_CEIL(picParams.m_frameHeightMinus1 + 1, 8) >> av1MiSizeLog2;
272         m_currRefList->RefPic           = picParams.m_currPic;
273         m_currRefList->m_orderHint      = picParams.m_orderHint;
274         m_currRefList->m_segmentEnable  = picParams.m_av1SegData.m_enabled;
275         m_currRefList->m_frameType      = picParams.m_picInfoFlags.m_fields.m_frameType;
276 
277         if (!AV1_KEY_OR_INRA_FRAME(picParams.m_picInfoFlags.m_fields.m_frameType) &&
278             picParams.m_seqInfoFlags.m_fields.m_enableOrderHint)
279         {
280             for (auto i = 0; i < av1NumInterRefFrames; i++)
281             {
282                 auto index = picParams.m_refFrameIdx[i];
283                 if (!CodecHal_PictureIsInvalid(picParams.m_refFrameMap[index]))
284                 {
285                     uint8_t frameIdx = picParams.m_refFrameMap[index].FrameIdx;
286                     m_currRefList->m_refOrderHint[i] = m_refList[frameIdx]->m_orderHint;
287                 }
288             }
289         }
290 
291         return MOS_STATUS_SUCCESS;
292     }
293 
Identify1stNearRef(const CodecAv1PicParams & picParams,int32_t curFrameOffset,int32_t * refFrameOffset,int32_t * refIdx)294     MOS_STATUS Av1ReferenceFramesG12::Identify1stNearRef(const CodecAv1PicParams &picParams,
295         int32_t curFrameOffset, int32_t* refFrameOffset, int32_t* refIdx)
296     {
297         DECODE_FUNC_CALL();
298 
299         for (auto i = 0; i < av1NumInterRefFrames; ++i)
300         {
301             int32_t refOffset = -1;
302 
303             uint8_t refPicIndex = picParams.m_refFrameIdx[i];//i=0 corresponds to LAST_FRAME.
304             const CODEC_PICTURE*  refFrameList = &(picParams.m_refFrameMap[0]);
305 
306             if (!CodecHal_PictureIsInvalid(refFrameList[refPicIndex]))
307             {
308                 uint8_t refFrameIdx = refFrameList[refPicIndex].FrameIdx;
309                 refOffset = m_refList[refFrameIdx]->m_orderHint;
310             }
311 
312             if (GetRelativeDist(picParams, refOffset, curFrameOffset) < 0)
313             {
314                 // Forward reference
315                 if (refFrameOffset[0] == -1 || GetRelativeDist(picParams, refOffset, refFrameOffset[0]) > 0)
316                 {
317                     refFrameOffset[0] = refOffset;
318                     refIdx[0] = i;
319                 }
320             }
321             else if (GetRelativeDist(picParams,refOffset, curFrameOffset) > 0)
322             {
323                 // Backward reference
324                 if (refFrameOffset[1] == INT_MAX ||
325                     GetRelativeDist(picParams, refOffset, refFrameOffset[1]) < 0)
326                 {
327                     refFrameOffset[1] = refOffset;
328                     refIdx[1] = i;
329                 }
330             }
331         }
332 
333         return MOS_STATUS_SUCCESS;
334     }
335 
Identify2ndNearRef(const CodecAv1PicParams & picParams,int32_t curFrameOffset,int32_t * refFrameOffset,int32_t * refIdx)336     MOS_STATUS Av1ReferenceFramesG12::Identify2ndNearRef(const CodecAv1PicParams & picParams,
337         int32_t curFrameOffset,int32_t* refFrameOffset,int32_t* refIdx)
338     {
339         DECODE_FUNC_CALL();
340 
341         // == Forward prediction only ==
342         // Identify the second nearest forward reference.
343         refFrameOffset[1] = -1;
344         for (int i = 0; i < av1NumInterRefFrames; ++i)
345         {
346             int32_t refOffset = -1;
347 
348             uint8_t refPicIndex = picParams.m_refFrameIdx[i]; //i=0 corresponds to LAST_FRAME.
349             const CODEC_PICTURE* refFrameList = &(picParams.m_refFrameMap[0]);
350 
351             if (!CodecHal_PictureIsInvalid(refFrameList[refPicIndex]))
352             {
353                 uint8_t refFrameIdx = refFrameList[refPicIndex].FrameIdx;
354                 refOffset = m_refList[refFrameIdx]->m_orderHint;
355             }
356 
357             if ((refFrameOffset[0] != -1 &&
358                 GetRelativeDist(picParams, refOffset, refFrameOffset[0]) < 0) &&
359                 (refFrameOffset[1] == -1 ||
360                     GetRelativeDist(picParams, refOffset, refFrameOffset[1]) > 0))
361             {
362                 // Second closest forward reference
363                 refFrameOffset[1] = refOffset;
364                 refIdx[1] = i;
365             }
366         }
367 
368         return MOS_STATUS_SUCCESS;
369     }
370 
GetRelativeDist(const CodecAv1PicParams & picParams,int32_t a,int32_t b)371     int32_t Av1ReferenceFramesG12::GetRelativeDist(const CodecAv1PicParams &picParams, int32_t a, int32_t b)
372     {
373         DECODE_FUNC_CALL();
374 
375         if (!picParams.m_seqInfoFlags.m_fields.m_enableOrderHint)
376         {
377             return 0;
378         }
379 
380         int32_t bits = picParams.m_orderHintBitsMinus1 + 1;
381         DECODE_ASSERT(bits >= 1);
382         DECODE_ASSERT(a >= 0 && a < (1 << bits));
383         DECODE_ASSERT(b >= 0 && b < (1 << bits));
384 
385         int32_t diff = a - b;
386         int32_t m = 1 << (bits - 1);
387         diff = (diff & (m - 1)) - (diff & m);
388 
389         return diff;
390     }
391 
SetupMotionFieldProjection(CodecAv1PicParams & picParams)392     MOS_STATUS Av1ReferenceFramesG12::SetupMotionFieldProjection(CodecAv1PicParams &picParams)
393     {
394         DECODE_FUNC_CALL();
395 
396         int32_t refBufIdx[av1NumInterRefFrames] = {-1, -1, -1, -1, -1, -1, -1};
397         int32_t refOrderHint[av1NumInterRefFrames] = {0, 0, 0, 0, 0, 0, 0};
398         uint8_t curOrderHint = m_currRefList->m_orderHint;
399         int32_t refStamp = av1MfmvStackSize - 1;
400 
401         for (auto ref = 0; ref < av1NumInterRefFrames; ref++)
402         {
403             uint8_t refPicIndex = picParams.m_refFrameIdx[ref];
404             int8_t refFrameIdx = picParams.m_refFrameMap[refPicIndex].FrameIdx;
405             refBufIdx[ref] = refFrameIdx;
406             if (refFrameIdx >= 0)
407             {
408                 refOrderHint[ref] = m_refList[refFrameIdx]->m_orderHint;
409             }
410         }
411 
412         memset(picParams.m_activeRefBitMaskMfmv, 0, 7 * sizeof(bool));
413 
414         if(refBufIdx[lastFrame - lastFrame] >= 0)
415         {
416             uint8_t refPicIndex = picParams.m_refFrameIdx[0];//0 corresponds to LAST_FRAME
417             if (!CodecHal_PictureIsInvalid(picParams.m_refFrameMap[refPicIndex]))
418             {
419                 uint8_t refFrameIdx = picParams.m_refFrameMap[refPicIndex].FrameIdx;
420                 if (!(m_refList[refFrameIdx]->m_refOrderHint[altRefFrame - lastFrame] == refOrderHint[goldenFrame - lastFrame]))
421                 {
422                     MotionFieldProjection(picParams, lastFrame, 2);
423                 }
424                 --refStamp;
425             }
426         }
427 
428         if (GetRelativeDist(picParams, refOrderHint[bwdRefFrame - lastFrame], curOrderHint) > 0)
429         {
430             if (MotionFieldProjection(picParams, bwdRefFrame, 0))
431             {
432                 --refStamp;
433             }
434         }
435 
436         if (GetRelativeDist(picParams, refOrderHint[altRef2Frame - lastFrame], curOrderHint) > 0)
437         {
438             if (MotionFieldProjection(picParams, altRef2Frame, 0))
439             {
440                 --refStamp;
441             }
442         }
443 
444         if (GetRelativeDist(picParams, refOrderHint[altRefFrame - lastFrame], curOrderHint) > 0 && refStamp >= 0)
445         {
446             if (MotionFieldProjection(picParams, altRefFrame, 0))
447             {
448                 --refStamp;
449             }
450         }
451 
452         if (refStamp >= 0 && refBufIdx[last2Frame - lastFrame] >= 0)
453         {
454             if (MotionFieldProjection(picParams, last2Frame, 2))
455             {
456                 --refStamp;
457             }
458         }
459 
460         return MOS_STATUS_SUCCESS;
461     }
462 
MotionFieldProjection(CodecAv1PicParams & picParams,int32_t ref,int32_t dir)463     bool Av1ReferenceFramesG12::MotionFieldProjection(CodecAv1PicParams &picParams, int32_t ref, int32_t dir)
464     {
465         DECODE_FUNC_CALL();
466 
467         //Calculate active reference bit mask for motion field
468         uint8_t refPicIndex = picParams.m_refFrameIdx[ref - lastFrame];//0 corresponds to LAST_FRAME
469         uint8_t refFrameIdx = m_basicFeature->m_invalidFrameIndex;
470         uint32_t miCols = 0, miRows = 0, refFrameType = 0;
471 
472         if (!CodecHal_PictureIsInvalid(picParams.m_refFrameMap[refPicIndex]))
473         {
474             refFrameIdx     = picParams.m_refFrameMap[refPicIndex].FrameIdx;
475             miCols          = m_refList[refFrameIdx]->m_miCols;
476             miRows          = m_refList[refFrameIdx]->m_miRows;
477             refFrameType    = m_refList[refFrameIdx]->m_frameType;
478         }
479 
480         if ((refFrameIdx == m_basicFeature->m_invalidFrameIndex) || (refFrameType == intraOnlyFrame || refFrameType == keyFrame) ||
481             (m_basicFeature->m_tileCoding.m_miCols != miCols) || (m_basicFeature->m_tileCoding.m_miRows != miRows))
482         {
483             picParams.m_activeRefBitMaskMfmv[ref - lastFrame] = 0;
484         }
485         else
486         {
487             picParams.m_activeRefBitMaskMfmv[ref - lastFrame] = 1;
488         }
489 
490         return picParams.m_activeRefBitMaskMfmv[ref - lastFrame];
491     }
492 
CheckSegForPrimFrame(CodecAv1PicParams & picParams)493     bool Av1ReferenceFramesG12::CheckSegForPrimFrame(CodecAv1PicParams &picParams)
494     {
495         DECODE_FUNC_CALL();
496 
497         bool isMatched = false;
498         if (m_currRefList->m_miCols == m_refList[m_prevFrameIdx]->m_miCols &&
499             m_currRefList->m_miRows == m_refList[m_prevFrameIdx]->m_miRows &&
500             m_refList[m_prevFrameIdx]->m_segmentEnable)
501         {
502             auto tempBuffers = &(m_basicFeature->m_tempBuffers);
503             auto tempBuf = tempBuffers->GetBufferByFrameIndex(m_prevFrameIdx);
504             if ((tempBuf != nullptr) && (tempBuf->segIdBuf != nullptr))
505             {
506                 isMatched = true;
507             }
508         }
509 
510         return isMatched;
511     }
512 
ErrorConcealment(CodecAv1PicParams & picParams)513     MOS_STATUS Av1ReferenceFramesG12::ErrorConcealment(CodecAv1PicParams &picParams)
514     {
515         DECODE_FUNC_CALL();
516         MOS_STATUS             hr           = MOS_STATUS_SUCCESS;
517         Av1ReferenceFramesG12 &refFrames    = m_basicFeature->m_refFrames;
518         PCODEC_PICTURE         refFrameList = &(picParams.m_refFrameMap[0]);
519 
520         uint8_t validfPicIndex    = 0;
521         bool    hasValidRefIndex = false;
522 
523         for (auto i = 0; i < av1NumInterRefFrames; i++)
524         {
525             uint8_t refPicIndex = picParams.m_refFrameIdx[i];
526             if (refPicIndex >= av1TotalRefsPerFrame)
527             {
528                 continue;
529             }
530             uint8_t frameIdx = refFrameList[refPicIndex].FrameIdx;
531             auto    curframe = refFrames.GetReferenceByFrameIndex(frameIdx);
532             if (curframe == nullptr)
533             {
534                 if (hasValidRefIndex == false)
535                 {
536                     //Get valid reference frame index
537                     hr = GetValidReferenceIndex(&validfPicIndex);
538                     hasValidRefIndex = true;
539                 }
540                 //Use validfPicIndex to replace invalid Reference index for non-key frame
541                 refFrameList[refPicIndex].FrameIdx = validfPicIndex;
542                 DECODE_ASSERTMESSAGE("Hit invalid refFrameList[%d].FrameIdx=%d\n", refPicIndex, refFrameList[refPicIndex].FrameIdx);
543             }
544         }
545 
546         return hr;
547     }
548 
549 }  // namespace decode
550