Skip to content

Commit

Permalink
Revert "Revert "[AV1e/lib] Refine ref frame for pyramid cases (#8749)…
Browse files Browse the repository at this point in the history
…" (#8970)"

This reverts commit c1573ab
  • Loading branch information
MaximIntel authored and gfxVPLsdm committed Sep 9, 2024
1 parent 0265964 commit 9a8f295
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ namespace Base
};

using DpbType = std::vector<std::shared_ptr<DpbFrame>>;
using DpbIterType = DpbType::iterator;
using RefListType = std::array<mfxU8, REFS_PER_FRAME>;
using DpbRefreshType = std::array<mfxU8, NUM_REF_FRAMES>;

Expand Down
67 changes: 52 additions & 15 deletions _studio/mfx_lib/encode_hw/av1/agnostic/base/av1ehw_base_general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1483,9 +1483,9 @@ void General::PostReorderTask(const FeatureBlocks& blocks, TPushPostRT Push)

auto& glob_fh = Glob::FH::Get(global);
auto def = GetRTDefaults(global);
ConfigureTask(task, def, recPool, encodedInfo, glob_fh);

auto& framesToShowInfo = Glob::FramesToShowInfo::Get(global);

ConfigureTask(task, def, recPool, framesToShowInfo, encodedInfo, glob_fh);
SetTaskFramesToShow(task, framesToShowInfo);

auto& repeatFrameSizeInfo = Glob::RepeatFrameSizeInfo::Get(global);
Expand Down Expand Up @@ -1820,8 +1820,11 @@ static void FillSortedFwdBwd(
for (mfxU8 refIdx = 0; refIdx < task.DPB.size(); refIdx++)
{
auto& refFrm = task.DPB.at(refIdx);
if (refFrm && refFrm->TemporalID <= task.TemporalID && preferedFwd.count(refIdx) == 0)
if (refFrm && refFrm->PyramidLevel <= task.PyramidLevel
&& refFrm->TemporalID <= task.TemporalID && preferedFwd.count(refIdx) == 0)
{
uniqueRefs.insert({ refFrm->DisplayOrderInGOP, refIdx });
}
}
uniqueRefs.erase(task.DisplayOrderInGOP);

Expand Down Expand Up @@ -2393,21 +2396,44 @@ inline void SetTaskRefList(
FillRefListRAB(fwd, maxFwdRefs, bwd, maxBwdRefs, refList);
}

template <typename DPBIter>
DPBIter FindOldestSTR(DPBIter dpbBegin, DPBIter dpbEnd, mfxU8 tid)
DpbIterType FindOldestLowestPrioritySTR(DpbIterType dpbBegin, DpbIterType dpbEnd, const TFramesToShowInfo& framesToShowInfo, mfxU16 numRefP, mfxU32 currentLevel, mfxU8 tid)
{
DPBIter oldestSTR = dpbEnd;
std::map<mfxU32, std::vector<DpbIterType>> refsInDPB;
for (auto it = dpbBegin; it != dpbEnd; ++it)
{
if ((*it) && !(*it)->isLTR && (*it)->TemporalID >= tid)
auto& pRef = *it;
if (!pRef || pRef->isLTR || pRef->TemporalID < tid || (pRef->PyramidLevel == 0 && currentLevel > 0))
continue;

if (framesToShowInfo.find(pRef->DisplayOrder) != framesToShowInfo.end())
continue;

refsInDPB[pRef->PyramidLevel].push_back(it);
}

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
{
targetLevel = 0;
}

std::vector<DpbIterType> refsInLevel = refsInDPB[targetLevel];
DpbIterType slot = refsInLevel.size() > 0 ? refsInLevel[0] : dpbEnd;
for (size_t idx = 1; idx < refsInLevel.size(); ++idx)
{
if ((*refsInLevel[idx])->DisplayOrder < (*slot)->DisplayOrder)
{
if (oldestSTR == dpbEnd)
oldestSTR = it;
else if ((*oldestSTR)->DisplayOrder > (*it)->DisplayOrder)
oldestSTR = it;
slot = refsInLevel[idx];
}
}
return oldestSTR;

return slot;
}

inline void SetVCLowDelayFlatDPBRefresh(
Expand Down Expand Up @@ -2531,6 +2557,7 @@ inline mfxU8 SetTaskDPBRefreshLowDelayFlat(
inline void SetTaskDPBRefresh(
TaskCommonPar& task
, const mfxVideoParam& par
, const TFramesToShowInfo& framesToShowInfo
, bool useLTR)
{
auto& refreshRefFrames = task.RefreshFrameFlags;
Expand Down Expand Up @@ -2562,13 +2589,22 @@ inline void SetTaskDPBRefresh(
// If no LTR was refreshed, then find duplicate reference frame
// Some frames can be included multiple times into DPB
for (auto it = dpbBegin + 1; it < dpbEnd && slotToRefresh == dpbEnd; ++it)
{
if (std::find(dpbBegin, it, *it) != it)
{
slotToRefresh = it;
break;
}
}

// If no duplicates, then find the oldest STR
// If no duplicates, then find the lowest priority short term ref slot with oldest display order
// For temporal scalability frame must not overwrite frames from lower layers
if (slotToRefresh == dpbEnd)
slotToRefresh = FindOldestSTR(dpbBegin, dpbEnd, task.TemporalID);
{
const mfxExtCodingOption3& CO3 = ExtBuffer::Get(par);
mfxU16 numRefP = CO3.NumRefActiveP[0];
slotToRefresh = FindOldestLowestPrioritySTR(dpbBegin, dpbEnd, framesToShowInfo, numRefP, task.PyramidLevel, task.TemporalID);
}

// If failed, just do not refresh any reference frame.
// This should not happend since we maintain at least 1 STR in DPB
Expand Down Expand Up @@ -2686,6 +2722,7 @@ void General::ConfigureTask(
TaskCommonPar& task
, const Defaults::Param& dflts
, IAllocation& recPool
, const TFramesToShowInfo& framesToShowInfo
, EncodedInfoAv1& encodedInfo
, FH& fh)
{
Expand All @@ -2701,7 +2738,7 @@ void General::ConfigureTask(

bool useLTR = false;
SetTaskRefList(task, par, useLTR);
SetTaskDPBRefresh(task, par, useLTR);
SetTaskDPBRefresh(task, par, framesToShowInfo, useLTR);
SetTaskInsertHeaders(task, m_prevTask, par, m_insertIVFSeq);

const mfxExtCodingOption3* pCO3 = ExtBuffer::Get(par);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ namespace Base
TaskCommonPar& task
, const Defaults::Param& dflts
, IAllocation& recPool
, const TFramesToShowInfo& framesToShowInfo
, EncodedInfoAv1& encodedInfo
, FH& fh);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ class GetDefault
return std::max<mfxU16>({ NumRefFrame, NumRefActiveP[0], maxBL0, maxBL1 });
});

// Need to have one more DPB buffer slot to enable two L0 for non-ref B frames in AV1
if (*std::max_element(NumRefActiveBL0, NumRefActiveBL0 + NumLayers) == 2)
// Need to have one more DPB buffer slot to enable 3 P refs or 2 BL0 refs in AV1
if (NumRefActiveP[0] == 3 || *std::max_element(NumRefActiveBL0, NumRefActiveBL0 + NumLayers) == 2)
{
NumRefFrame++;
}
Expand Down

0 comments on commit 9a8f295

Please sign in to comment.