Newer
Older
{
ReferencePictureList* rpl;
int numRPLCandidates = getRPLCandidateSize(0);
// To allocate one additional memory for RPL of POC1 (first bottom field) which is not specified in cfg file
sps.createRPLList0(numRPLCandidates + (isFieldCoding ? 1 : 0));
sps.createRPLList1(numRPLCandidates + (isFieldCoding ? 1 : 0));
RPLList* rplList = 0;
for (int i = 0; i < 2; i++)
{
rplList = (i == 0) ? sps.getRPLList0() : sps.getRPLList1();
for (int j = 0; j < numRPLCandidates; j++)
{
const RPLEntry &ge = getRPLEntry(i, j);
rpl = rplList->getReferencePictureList(j);
rpl->setNumberOfShorttermPictures(ge.m_numRefPics);
rpl->setNumberOfLongtermPictures(0); //Hardcoded as 0 for now. need to update this when implementing LTRP
rpl->setNumberOfActivePictures(ge.m_numRefPicsActive);
Philip Cowan
committed
rpl->setLtrpInSliceHeaderFlag(ge.m_ltrp_in_slice_header_flag);
rpl->setInterLayerPresentFlag( sps.getInterLayerPresentFlag() );
// inter-layer reference picture is not signaled in SPS RPL, SPS is shared currently
rpl->setNumberOfInterLayerPictures( 0 );
for (int k = 0; k < ge.m_numRefPics; k++)
{
#if JVET_S0045_SIGN
rpl->setRefPicIdentifier(k, -ge.m_deltaRefPics[k], 0, false, 0);
#else
rpl->setRefPicIdentifier( k, ge.m_deltaRefPics[k], 0, false, 0 );
if (isFieldCoding)
{
// To set RPL of POC1 (first bottom field) which is not specified in cfg file
for (int i = 0; i < 2; i++)
{
rplList = (i == 0) ? sps.getRPLList0() : sps.getRPLList1();
rpl = rplList->getReferencePictureList(numRPLCandidates);
rpl->setNumberOfShorttermPictures(1);
rpl->setNumberOfLongtermPictures(0);
rpl->setNumberOfActivePictures(1);
rpl->setLtrpInSliceHeaderFlag(0);
#if JVET_S0045_SIGN
rpl->setRefPicIdentifier(0, -1, 0, false, 0);
#else
rpl->setRefPicIdentifier(0, 1, 0, false, 0);
rpl->setPOC(0, 0);
}
}
bool isRpl1CopiedFromRpl0 = true;
for( int i = 0; isRpl1CopiedFromRpl0 && i < numRPLCandidates; i++)
{
if( sps.getRPLList0()->getReferencePictureList(i)->getNumRefEntries() == sps.getRPLList1()->getReferencePictureList(i)->getNumRefEntries() )
{
for( int j = 0; isRpl1CopiedFromRpl0 && j < sps.getRPLList0()->getReferencePictureList(i)->getNumRefEntries(); j++ )
{
if( sps.getRPLList0()->getReferencePictureList(i)->getRefPicIdentifier(j) != sps.getRPLList1()->getReferencePictureList(i)->getRefPicIdentifier(j) )
{
isRpl1CopiedFromRpl0 = false;
}
}
}
else
{
isRpl1CopiedFromRpl0 = false;
}
}
sps.setRPL1CopyFromRPL0Flag(isRpl1CopiedFromRpl0);
//Check if all delta POC of STRP in each RPL has the same sign
//Check RPLL0 first
const RPLList* rplList0 = sps.getRPLList0();
const RPLList* rplList1 = sps.getRPLList1();
uint32_t numberOfRPL = sps.getNumRPL0();
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
bool isAllEntriesinRPLHasSameSignFlag = true;
bool isFirstEntry = true;
bool lastSign = true; //true = positive ; false = negative
for (uint32_t ii = 0; isAllEntriesinRPLHasSameSignFlag && ii < numberOfRPL; ii++)
{
const ReferencePictureList* rpl = rplList0->getReferencePictureList(ii);
for (uint32_t jj = 0; isAllEntriesinRPLHasSameSignFlag && jj < rpl->getNumberOfActivePictures(); jj++)
{
if (!rpl->isRefPicLongterm(jj) && isFirstEntry)
{
lastSign = (rpl->getRefPicIdentifier(jj) >= 0) ? true : false;
isFirstEntry = false;
}
else if (!rpl->isRefPicLongterm(jj) && (((rpl->getRefPicIdentifier(jj) - rpl->getRefPicIdentifier(jj - 1)) >= 0 && lastSign == false) || ((rpl->getRefPicIdentifier(jj) - rpl->getRefPicIdentifier(jj - 1)) < 0 && lastSign == true)))
{
isAllEntriesinRPLHasSameSignFlag = false;
}
}
}
//Check RPLL1. Skip it if it is already found out that this flag is not true for RPL0 or if RPL1 is the same as RPL0
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
isFirstEntry = true;
lastSign = true;
for (uint32_t ii = 0; isAllEntriesinRPLHasSameSignFlag && !sps.getRPL1CopyFromRPL0Flag() && ii < numberOfRPL; ii++)
{
isFirstEntry = true;
const ReferencePictureList* rpl = rplList1->getReferencePictureList(ii);
for (uint32_t jj = 0; isAllEntriesinRPLHasSameSignFlag && jj < rpl->getNumberOfActivePictures(); jj++)
{
if (!rpl->isRefPicLongterm(jj) && isFirstEntry)
{
lastSign = (rpl->getRefPicIdentifier(jj) >= 0) ? true : false;
isFirstEntry = false;
}
else if (!rpl->isRefPicLongterm(jj) && (((rpl->getRefPicIdentifier(jj) - rpl->getRefPicIdentifier(jj - 1)) >= 0 && lastSign == false) || ((rpl->getRefPicIdentifier(jj) - rpl->getRefPicIdentifier(jj - 1)) < 0 && lastSign == true)))
{
isAllEntriesinRPLHasSameSignFlag = false;
}
}
}
sps.setAllActiveRplEntriesHasSameSignFlag(isAllEntriesinRPLHasSameSignFlag);
}
void EncLib::getActiveRefPicListNumForPOC(const SPS *sps, int POCCurr, int GOPid, uint32_t *activeL0, uint32_t *activeL1)
{
{
*activeL0 = *activeL1 = 0;
return;
}
uint32_t rpl0Idx = GOPid;
uint32_t rpl1Idx = GOPid;
int fullListNum = m_iGOPSize;
int partialListNum = getRPLCandidateSize(0) - m_iGOPSize;
int extraNum = fullListNum;
int candidateIdx = (POCCurr + m_iGOPSize - 1 >= fullListNum + partialListNum) ? GOPid : POCCurr + m_iGOPSize - 1;
rpl0Idx = candidateIdx;
rpl1Idx = candidateIdx;
}
else
{
rpl0Idx = (POCCurr%m_iGOPSize == 0) ? m_iGOPSize - 1 : POCCurr%m_iGOPSize - 1;
rpl1Idx = (POCCurr%m_iGOPSize == 0) ? m_iGOPSize - 1 : POCCurr%m_iGOPSize - 1;
}
extraNum = fullListNum + partialListNum;
}
for (; extraNum<fullListNum + partialListNum; extraNum++)
{
if (m_intraPeriod > 0 && getDecodingRefreshType() > 0)
int POCIndex = POCCurr % m_intraPeriod;
{
POCIndex = m_intraPeriod;
}
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
if (POCIndex == m_RPLList0[extraNum].m_POC)
{
rpl0Idx = extraNum;
rpl1Idx = extraNum;
extraNum++;
}
}
}
const ReferencePictureList *rpl0 = sps->getRPLList0()->getReferencePictureList(rpl0Idx);
*activeL0 = rpl0->getNumberOfActivePictures();
const ReferencePictureList *rpl1 = sps->getRPLList1()->getReferencePictureList(rpl1Idx);
*activeL1 = rpl1->getNumberOfActivePictures();
}
void EncLib::selectReferencePictureList(Slice* slice, int POCCurr, int GOPid, int ltPoc)
{
bool isEncodeLtRef = (POCCurr == ltPoc);
if (m_compositeRefEnabled && isEncodeLtRef)
{
POCCurr++;
}
slice->setRPL0idx(GOPid);
slice->setRPL1idx(GOPid);
int fullListNum = m_iGOPSize;
int partialListNum = getRPLCandidateSize(0) - m_iGOPSize;
int extraNum = fullListNum;
if( rplPeriod < 0 ) //Need to check if it is low delay or RA but with no RAP
{
if( slice->getSPS()->getRPLList0()->getReferencePictureList(1)->getRefPicIdentifier(0) * slice->getSPS()->getRPLList1()->getReferencePictureList(1)->getRefPicIdentifier(0) < 0)
{
rplPeriod = m_iGOPSize * 2;
}
}
if (rplPeriod < 0)
int candidateIdx = (POCCurr + m_iGOPSize - 1 >= fullListNum + partialListNum) ? GOPid : POCCurr + m_iGOPSize - 1;
slice->setRPL0idx(candidateIdx);
slice->setRPL1idx(candidateIdx);
}
else
{
slice->setRPL0idx((POCCurr%m_iGOPSize == 0) ? m_iGOPSize - 1 : POCCurr%m_iGOPSize - 1);
slice->setRPL1idx((POCCurr%m_iGOPSize == 0) ? m_iGOPSize - 1 : POCCurr%m_iGOPSize - 1);
}
extraNum = fullListNum + partialListNum;
}
for (; extraNum < fullListNum + partialListNum; extraNum++)
{
if (POCIndex == m_RPLList0[extraNum].m_POC)
{
slice->setRPL0idx(extraNum);
slice->setRPL1idx(extraNum);
extraNum++;
}
}
}
if (slice->getPic()->fieldPic)
{
// To set RPL index of POC1 (first bottom field)
if (POCCurr == 1)
{
slice->setRPL0idx(getRPLCandidateSize(0));
slice->setRPL1idx(getRPLCandidateSize(0));
}
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
{
// To set RPL indexes for LD
int numRPLCandidates = getRPLCandidateSize(0);
if (POCCurr < numRPLCandidates - m_iGOPSize + 2)
{
slice->setRPL0idx(POCCurr + m_iGOPSize - 2);
slice->setRPL1idx(POCCurr + m_iGOPSize - 2);
}
else
{
if (POCCurr%m_iGOPSize == 0)
{
slice->setRPL0idx(m_iGOPSize - 2);
slice->setRPL1idx(m_iGOPSize - 2);
}
else if (POCCurr%m_iGOPSize == 1)
{
slice->setRPL0idx(m_iGOPSize - 1);
slice->setRPL1idx(m_iGOPSize - 1);
}
else
{
slice->setRPL0idx(POCCurr % m_iGOPSize - 2);
slice->setRPL1idx(POCCurr % m_iGOPSize - 2);
}
}
}
}
const ReferencePictureList *rpl0 = (slice->getSPS()->getRPLList0()->getReferencePictureList(slice->getRPL0idx()));
const ReferencePictureList *rpl1 = (slice->getSPS()->getRPLList1()->getReferencePictureList(slice->getRPL1idx()));
slice->setRPL0(rpl0);
slice->setRPL1(rpl1);
}

Karsten Suehring
committed
void EncLib::setParamSetChanged(int spsId, int ppsId)
{
m_ppsMap.setChangedFlag(ppsId);
m_spsMap.setChangedFlag(spsId);
}
Hendry
committed
bool isChanged = m_apsMap.getChangedFlag(apsId);
Hendry
committed
return isChanged;

Karsten Suehring
committed
bool EncLib::PPSNeedsWriting(int ppsId)
{
bool bChanged=m_ppsMap.getChangedFlag(ppsId);
m_ppsMap.clearChangedFlag(ppsId);
return bChanged;
}
bool EncLib::SPSNeedsWriting(int spsId)
{
bool bChanged=m_spsMap.getChangedFlag(spsId);
m_spsMap.clearChangedFlag(spsId);
return bChanged;
}
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
void EncLib::checkPltStats( Picture* pic )
{
int totalArea = 0;
int pltArea = 0;
for (auto apu : pic->cs->pus)
{
for (int i = 0; i < MAX_NUM_TBLOCKS; ++i)
{
int puArea = apu->blocks[i].width * apu->blocks[i].height;
if (apu->blocks[i].width > 0 && apu->blocks[i].height > 0)
{
totalArea += puArea;
if (CU::isPLT(*apu->cu) || CU::isIBC(*apu->cu))
{
pltArea += puArea;
}
break;
}
}
}
if (pltArea * PLT_FAST_RATIO < totalArea)
{
m_doPlt = false;
}
else
{
m_doPlt = true;
}
}

Karsten Suehring
committed
#if X0038_LAMBDA_FROM_QP_CAPABILITY
int EncCfg::getQPForPicture(const uint32_t gopIndex, const Slice *pSlice) const
{
const int lumaQpBDOffset = pSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA);
int qp;
if (getCostMode()==COST_LOSSLESS_CODING)
{
qp = getBaseQP();

Karsten Suehring
committed
}
else
{
const SliceType sliceType=pSlice->getSliceType();
qp = getBaseQP();
// switch at specific qp and keep this qp offset
static int appliedSwitchDQQ = 0; /* TODO: MT */
if( pSlice->getPOC() == getSwitchPOC() )
{
appliedSwitchDQQ = getSwitchDQP();
}
qp += appliedSwitchDQQ;
#if QP_SWITCHING_FOR_PARALLEL
const int* pdQPs = getdQPs();
if ( pdQPs )
{
qp += pdQPs[pSlice->getPOC() / (m_compositeRefEnabled ? 2 : 1)];

Karsten Suehring
committed
}
#endif
if(sliceType==I_SLICE)
{
qp += getIntraQPOffset();
}
else
{
const GOPEntry &gopEntry=getGOPEntry(gopIndex);
// adjust QP according to the QP offset for the GOP entry.
qp +=gopEntry.m_QPOffset;
// adjust QP according to QPOffsetModel for the GOP entry.
double dqpOffset=qp*gopEntry.m_QPOffsetModelScale+gopEntry.m_QPOffsetModelOffset+0.5;
int qpOffset = (int)floor(Clip3<double>(0.0, 3.0, dqpOffset));
qp += qpOffset ;
}
#if JVET_AC0096
if (m_rprFunctionalityTestingEnabledFlag)
{
int currPoc = pSlice->getPOC() + EncCfg::m_FrameSkip;
int rprSegment = EncCfg::getRprSwitchingSegment(currPoc);
qp += EncCfg::m_rprSwitchingQPOffsetOrderList[rprSegment];
}
#endif
#if JVET_AG0116
if (m_gopBasedRPREnabledFlag)
{
if (pSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR)
{
qp += EncCfg::m_qpOffsetRPR;
}
if (pSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR2)
{
qp += EncCfg::m_qpOffsetRPR2;
}
if (pSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR3)
{
qp += EncCfg::m_qpOffsetRPR3;
}
}
#endif

Karsten Suehring
committed
#if !QP_SWITCHING_FOR_PARALLEL
// modify QP if a fractional QP was originally specified, cause dQPs to be 0 or 1.
const int* pdQPs = getdQPs();
if ( pdQPs )
{
qp += pdQPs[ pSlice->getPOC() ];
}
#endif
}
qp = Clip3( -lumaQpBDOffset, MAX_QP, qp );
return qp;
}
#endif