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