Skip to content

Commit

Permalink
[AV1e/lib] Fix VPl RT hang issue for adaptive
Browse files Browse the repository at this point in the history
In Enctools AdaptiveB cases, there are chances that all ref in DBP are at level 0.
It leads to no available for hiden B frames in current algorithm, and VPL RT hang in waitting for repeat frame.
  • Loading branch information
MaximIntel authored and gfxVPLsdm committed Sep 11, 2024
1 parent 6291cf2 commit 7b32bd5
Showing 1 changed file with 13 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2402,7 +2402,10 @@ DpbIterType FindOldestLowestPrioritySTR(DpbIterType dpbBegin, DpbIterType dpbEnd
for (auto it = dpbBegin; it != dpbEnd; ++it)
{
auto& pRef = *it;
if (!pRef || pRef->isLTR || pRef->TemporalID < tid || (pRef->PyramidLevel == 0 && currentLevel > 0))
// Note: B-frames may refresh I-frames and P-frames in certain cases
// This is necessary to keep hidden frames in the Decoded Picture Buffer (DPB)
// These hidden frames are required for potential future insertion of repeat frames
if (!pRef || pRef->isLTR || pRef->TemporalID < tid)
continue;

if (framesToShowInfo.find(pRef->DisplayOrder) != framesToShowInfo.end())
Expand All @@ -2414,16 +2417,19 @@ DpbIterType FindOldestLowestPrioritySTR(DpbIterType dpbBegin, DpbIterType dpbEnd
if (refsInDPB.size() == 0)
return dpbEnd;

mfxU32 targetLevel = refsInDPB.rbegin()->first; // refresh highest level
// P frames will refresh level 0 refs first if there are too many candidates and leads to no slots for ref-B
if (currentLevel == 0
&& ((numRefP > 1 && refsInDPB[0].size() >= numRefP)
|| (numRefP == 1 && refsInDPB[0].size() > numRefP))) // P not refresh I directly
// Attempt to refresh the highest level reference frame first, as it has the lowest priority
mfxU32 targetLevel = refsInDPB.rbegin()->first;

// For P-frames:
// - If the number of level 0 reference frames exceeds the threshold (numRefP for P-frames, 2 for BL0 frames),
// - Fall back to refreshing a level 0 reference frame,
// - This avoids refreshing all B-frames that might be used in future predictions
if (currentLevel == 0 && refsInDPB[0].size() >= std::max(numRefP, mfxU16(2)))
{
targetLevel = 0;
}

std::vector<DpbIterType> refsInLevel = refsInDPB[targetLevel];
std::vector<DpbIterType>& refsInLevel = refsInDPB[targetLevel];
DpbIterType slot = refsInLevel.size() > 0 ? refsInLevel[0] : dpbEnd;
for (size_t idx = 1; idx < refsInLevel.size(); ++idx)
{
Expand Down

0 comments on commit 7b32bd5

Please sign in to comment.