This source file includes following definitions.
- recycleUnreferenced
- prepareEncode
- computeRPS
- decodingRefreshMarking
- applyReferencePictureSet
- getNalUnitType
#include "common.h"
#include "frame.h"
#include "framedata.h"
#include "picyuv.h"
#include "slice.h"
#include "dpb.h"
using namespace X265_NS;
DPB::~DPB()
{
while (!m_freeList.empty())
{
Frame* curFrame = m_freeList.popFront();
curFrame->destroy();
delete curFrame;
}
while (!m_picList.empty())
{
Frame* curFrame = m_picList.popFront();
curFrame->destroy();
delete curFrame;
}
while (m_frameDataFreeList)
{
FrameData* next = m_frameDataFreeList->m_freeListNext;
m_frameDataFreeList->destroy();
m_frameDataFreeList->m_reconPic->destroy();
delete m_frameDataFreeList->m_reconPic;
delete m_frameDataFreeList;
m_frameDataFreeList = next;
}
}
void DPB::recycleUnreferenced()
{
Frame *iterFrame = m_picList.first();
while (iterFrame)
{
Frame *curFrame = iterFrame;
iterFrame = iterFrame->m_next;
if (!curFrame->m_encData->m_bHasReferences && !curFrame->m_countRefEncoders)
{
curFrame->m_bChromaExtended = false;
X265_CHECK(curFrame->m_reconRowFlag != NULL, "curFrame->m_reconRowFlag check failure");
X265_CHECK(curFrame->m_reconColCount != NULL, "curFrame->m_reconColCount check failure");
X265_CHECK(curFrame->m_numRows > 0, "curFrame->m_numRows check failure");
for(int32_t row = 0; row < curFrame->m_numRows; row++)
{
curFrame->m_reconRowFlag[row].set(0);
curFrame->m_reconColCount[row].set(0);
}
m_picList.remove(*curFrame);
iterFrame = m_picList.first();
m_freeList.pushBack(*curFrame);
curFrame->m_encData->m_freeListNext = m_frameDataFreeList;
m_frameDataFreeList = curFrame->m_encData;
if (curFrame->m_encData->m_meBuffer)
{
for (int i = 0; i < INTEGRAL_PLANE_NUM; i++)
{
if (curFrame->m_encData->m_meBuffer[i] != NULL)
{
X265_FREE(curFrame->m_encData->m_meBuffer[i]);
curFrame->m_encData->m_meBuffer[i] = NULL;
}
}
}
if (curFrame->m_ctuInfo != NULL)
{
uint32_t widthInCU = (curFrame->m_param->sourceWidth + curFrame->m_param->maxCUSize - 1) >> curFrame->m_param->maxLog2CUSize;
uint32_t heightInCU = (curFrame->m_param->sourceHeight + curFrame->m_param->maxCUSize - 1) >> curFrame->m_param->maxLog2CUSize;
uint32_t numCUsInFrame = widthInCU * heightInCU;
for (uint32_t i = 0; i < numCUsInFrame; i++)
{
X265_FREE((*curFrame->m_ctuInfo + i)->ctuInfo);
(*curFrame->m_ctuInfo + i)->ctuInfo = NULL;
}
X265_FREE(*curFrame->m_ctuInfo);
*(curFrame->m_ctuInfo) = NULL;
X265_FREE(curFrame->m_ctuInfo);
curFrame->m_ctuInfo = NULL;
X265_FREE(curFrame->m_prevCtuInfoChange);
curFrame->m_prevCtuInfoChange = NULL;
}
curFrame->m_encData = NULL;
curFrame->m_reconPic = NULL;
}
}
}
void DPB::prepareEncode(Frame *newFrame)
{
Slice* slice = newFrame->m_encData->m_slice;
slice->m_poc = newFrame->m_poc;
int pocCurr = slice->m_poc;
int type = newFrame->m_lowres.sliceType;
bool bIsKeyFrame = newFrame->m_lowres.bKeyframe;
slice->m_nalUnitType = getNalUnitType(pocCurr, bIsKeyFrame);
if (slice->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL)
m_lastIDR = pocCurr;
slice->m_lastIDR = m_lastIDR;
slice->m_sliceType = IS_X265_TYPE_B(type) ? B_SLICE : (type == X265_TYPE_P) ? P_SLICE : I_SLICE;
if (type == X265_TYPE_B)
{
newFrame->m_encData->m_bHasReferences = false;
switch (slice->m_nalUnitType)
{
case NAL_UNIT_CODED_SLICE_TRAIL_R:
slice->m_nalUnitType = m_bTemporalSublayer ? NAL_UNIT_CODED_SLICE_TSA_N : NAL_UNIT_CODED_SLICE_TRAIL_N;
break;
case NAL_UNIT_CODED_SLICE_RADL_R:
slice->m_nalUnitType = NAL_UNIT_CODED_SLICE_RADL_N;
break;
case NAL_UNIT_CODED_SLICE_RASL_R:
slice->m_nalUnitType = NAL_UNIT_CODED_SLICE_RASL_N;
break;
default:
break;
}
}
else
{
newFrame->m_encData->m_bHasReferences = true;
}
m_picList.pushFront(*newFrame);
decodingRefreshMarking(pocCurr, slice->m_nalUnitType);
computeRPS(pocCurr, slice->isIRAP(), &slice->m_rps, slice->m_sps->maxDecPicBuffering);
applyReferencePictureSet(&slice->m_rps, pocCurr);
slice->m_numRefIdx[0] = X265_MIN(newFrame->m_param->maxNumReferences, slice->m_rps.numberOfNegativePictures);
slice->m_numRefIdx[1] = X265_MIN(newFrame->m_param->bBPyramid ? 2 : 1, slice->m_rps.numberOfPositivePictures);
slice->setRefPicList(m_picList);
X265_CHECK(slice->m_sliceType != B_SLICE || slice->m_numRefIdx[1], "B slice without L1 references (non-fatal)\n");
if (slice->m_sliceType == B_SLICE)
{
slice->m_colFromL0Flag = false;
slice->m_colRefIdx = 0;
slice->m_bCheckLDC = false;
}
else
{
slice->m_bCheckLDC = true;
slice->m_colFromL0Flag = true;
slice->m_colRefIdx = 0;
}
slice->m_sLFaseFlag = (newFrame->m_param->maxSlices > 1) ? false : ((SLFASE_CONSTANT & (1 << (pocCurr % 31))) > 0);
int numPredDir = slice->isInterP() ? 1 : slice->isInterB() ? 2 : 0;
for (int l = 0; l < numPredDir; l++)
{
for (int ref = 0; ref < slice->m_numRefIdx[l]; ref++)
{
Frame *refpic = slice->m_refFrameList[l][ref];
ATOMIC_INC(&refpic->m_countRefEncoders);
}
}
}
void DPB::computeRPS(int curPoc, bool isRAP, RPS * rps, unsigned int maxDecPicBuffer)
{
unsigned int poci = 0, numNeg = 0, numPos = 0;
Frame* iterPic = m_picList.first();
while (iterPic && (poci < maxDecPicBuffer - 1))
{
if ((iterPic->m_poc != curPoc) && iterPic->m_encData->m_bHasReferences)
{
rps->poc[poci] = iterPic->m_poc;
rps->deltaPOC[poci] = rps->poc[poci] - curPoc;
(rps->deltaPOC[poci] < 0) ? numNeg++ : numPos++;
rps->bUsed[poci] = !isRAP;
poci++;
}
iterPic = iterPic->m_next;
}
rps->numberOfPictures = poci;
rps->numberOfPositivePictures = numPos;
rps->numberOfNegativePictures = numNeg;
rps->sortDeltaPOC();
}
void DPB::decodingRefreshMarking(int pocCurr, NalUnitType nalUnitType)
{
if (nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL)
{
Frame* iterFrame = m_picList.first();
while (iterFrame)
{
if (iterFrame->m_poc != pocCurr)
iterFrame->m_encData->m_bHasReferences = false;
iterFrame = iterFrame->m_next;
}
}
else
{
if (m_bRefreshPending && pocCurr > m_pocCRA)
{
Frame* iterFrame = m_picList.first();
while (iterFrame)
{
if (iterFrame->m_poc != pocCurr && iterFrame->m_poc != m_pocCRA)
iterFrame->m_encData->m_bHasReferences = false;
iterFrame = iterFrame->m_next;
}
m_bRefreshPending = false;
}
if (nalUnitType == NAL_UNIT_CODED_SLICE_CRA)
{
m_bRefreshPending = true;
m_pocCRA = pocCurr;
}
}
}
void DPB::applyReferencePictureSet(RPS *rps, int curPoc)
{
Frame* iterFrame = m_picList.first();
while (iterFrame)
{
if (iterFrame->m_poc != curPoc && iterFrame->m_encData->m_bHasReferences)
{
bool referenced = false;
for (int i = 0; i < rps->numberOfPositivePictures + rps->numberOfNegativePictures; i++)
{
if (iterFrame->m_poc == curPoc + rps->deltaPOC[i])
{
referenced = true;
break;
}
}
if (!referenced)
iterFrame->m_encData->m_bHasReferences = false;
}
iterFrame = iterFrame->m_next;
}
}
NalUnitType DPB::getNalUnitType(int curPOC, bool bIsKeyFrame)
{
if (!curPOC)
return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
if (bIsKeyFrame)
return m_bOpenGOP ? NAL_UNIT_CODED_SLICE_CRA : NAL_UNIT_CODED_SLICE_IDR_W_RADL;
if (m_pocCRA && curPOC < m_pocCRA)
return NAL_UNIT_CODED_SLICE_RASL_R;
if (m_lastIDR && curPOC < m_lastIDR)
return NAL_UNIT_CODED_SLICE_RADL_R;
return NAL_UNIT_CODED_SLICE_TRAIL_R;
}