Newer
Older

Karsten Suehring
committed
else
{
m_pcReshaper->setCTUFlag(false);
}
}
class BIFCabacEstImp : public BIFCabacEst
{
CABACWriter* CABACEstimator;
public:
BIFCabacEstImp(CABACWriter* _CABACEstimator) : CABACEstimator(_CABACEstimator) {};
virtual ~BIFCabacEstImp() {};
virtual uint64_t getBits(const Slice& slice, const BifParams& htdfParams)
{
CABACEstimator->initCtxModels(slice);
CABACEstimator->resetBits();
CABACEstimator->bif(slice, htdfParams);
return CABACEstimator->getEstFracBits();
}
};
#endif
#if JVET_X0071_CHROMA_BILATERAL_FILTER
class ChromaBIFCabacEstImp : public ChromaBIFCabacEst
CABACWriter* CABACEstimator;
public:
ChromaBIFCabacEstImp(CABACWriter* _CABACEstimator) : CABACEstimator(_CABACEstimator) {};
virtual ~ChromaBIFCabacEstImp() {};
virtual uint64_t getBitsCb(const Slice& slice, const ChromaBifParams& chromaBifParams)
{
CABACEstimator->initCtxModels(slice);
CABACEstimator->resetBits();
CABACEstimator->chromaBifCb(slice, chromaBifParams);
return CABACEstimator->getEstFracBits();
}
virtual uint64_t getBitsCr(const Slice& slice, const ChromaBifParams& chromaBifParams)
{
CABACEstimator->initCtxModels(slice);
CABACEstimator->resetBits();
CABACEstimator->chromaBifCr(slice, chromaBifParams);
return CABACEstimator->getEstFracBits();
}
};
#endif

Karsten Suehring
committed
// ====================================================================================================================
// Public member functions
// ====================================================================================================================
void EncGOP::compressGOP(int iPOCLast, int iNumPicRcvd, PicList &rcListPic, std::list<PelUnitBuf *> &rcListPicYuvRecOut,
bool isField, bool isTff, const InputColourSpaceConversion snr_conversion,
const bool printFrameMSE,
#if MSSIM_UNIFORM_METRICS_LOG
const bool printMSSSIM,
#endif
bool isEncodeLtRef, const int picIdInGOP)

Karsten Suehring
committed
{
// TODO: Split this function up.
Picture* pcPic = NULL;

Karsten Suehring
committed
Slice* pcSlice;
OutputBitstream *pcBitstreamRedirect;
pcBitstreamRedirect = new OutputBitstream;
AccessUnit::iterator itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted

Karsten Suehring
committed
xInitGOP( iPOCLast, iNumPicRcvd, isField, isEncodeLtRef );

Karsten Suehring
committed
m_iNumPicCoded = 0;
SEIMessages leadingSeiMessages;
SEIMessages nestedSeiMessages;
SEIMessages duInfoSeiMessages;
SEIMessages trailingSeiMessages;
std::deque<DUData> duData;
EfficientFieldIRAPMapping effFieldIRAPMap;
if (m_pcCfg->getEfficientFieldIRAPEnabled())
{
effFieldIRAPMap.initialize(isField, m_iGopSize, iPOCLast, iNumPicRcvd, m_iLastIDR, this, m_pcCfg);
}
if( isField && picIdInGOP == 0 )
{
for( int iGOPid = 0; iGOPid < max(2, m_iGopSize); iGOPid++ )
{
m_pcCfg->setEncodedFlag( iGOPid, false );
}
}
for( int iGOPid = picIdInGOP; iGOPid <= picIdInGOP; iGOPid++ )
{
// reset flag indicating whether pictures have been encoded
m_pcCfg->setEncodedFlag( iGOPid, false );

Karsten Suehring
committed
if (m_pcCfg->getEfficientFieldIRAPEnabled())
{
iGOPid=effFieldIRAPMap.adjustGOPid(iGOPid);
}
//-- For time output for each slice
auto beforeTime = std::chrono::steady_clock::now();
#if !X0038_LAMBDA_FROM_QP_CAPABILITY
uint32_t uiColDir = calculateCollocatedFromL1Flag(m_pcCfg, iGOPid, m_iGopSize);
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
int iTimeOffset;
int pocCurr;
int multipleFactor = m_pcCfg->getUseCompositeRef() ? 2 : 1;

Karsten Suehring
committed
if(iPOCLast == 0) //case first frame or first top field
{
pocCurr=0;

Haiwei Sun
committed
iTimeOffset = isField ? (1 - multipleFactor) : multipleFactor;

Karsten Suehring
committed
}
else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
{
pocCurr = 1;

Haiwei Sun
committed
iTimeOffset = multipleFactor + 1;

Karsten Suehring
committed
}
else
{
pocCurr = iPOCLast - iNumPicRcvd * multipleFactor + m_pcCfg->getGOPEntry(iGOPid).m_POC - ((isField && m_iGopSize>1) ? 1 : 0);

Karsten Suehring
committed
iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
}
if (m_pcCfg->getUseCompositeRef() && isEncodeLtRef)
{
pocCurr++;
iTimeOffset--;
}
if (pocCurr / multipleFactor >= m_pcCfg->getFramesToBeEncoded())

Karsten Suehring
committed
{
if (m_pcCfg->getEfficientFieldIRAPEnabled())
{
iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
}
continue;
}
if( getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP )
{
m_iLastIDR = pocCurr;
}
// start a new access unit: create an entry in the list of output access units
AccessUnit accessUnit;
Vadim Seregin
committed
accessUnit.temporalId = m_pcCfg->getGOPEntry( iGOPid ).m_temporalId;

Karsten Suehring
committed
xGetBuffer( rcListPic, rcListPicYuvRecOut,
iNumPicRcvd, iTimeOffset, pcPic, pocCurr, isField );
picHeader->setSPSId( pcPic->cs->pps->getSPSId() );
picHeader->setPPSId( pcPic->cs->pps->getPPSId() );
picHeader->setMinQTSizes(pcPic->cs->sps->getMinQTSizes());
picHeader->setMaxMTTHierarchyDepths(pcPic->cs->sps->getMaxMTTHierarchyDepths());
picHeader->setMaxBTSizes(pcPic->cs->sps->getMaxBTSizes());
picHeader->setMaxTTSizes(pcPic->cs->sps->getMaxTTSizes());
// initial two flags to be false
picHeader->setPicInterSliceAllowedFlag(false);
picHeader->setPicIntraSliceAllowedFlag(false);
#if ER_CHROMA_QP_WCG_PPS

Karsten Suehring
committed
// th this is a hot fix for the choma qp control
if( m_pcEncLib->getWCGChromaQPControl().isEnabled() && m_pcEncLib->getSwitchPOC() != -1 )
{
static int usePPS = 0; /* TODO: MT */
if( pocCurr == m_pcEncLib->getSwitchPOC() )
{
usePPS = 1;
}
const PPS *pPPS = m_pcEncLib->getPPS(usePPS);
// replace the pps with a more appropriated one
pcPic->cs->pps = pPPS;
}

Karsten Suehring
committed
// create objects based on the picture size
const int picWidth = pcPic->cs->pps->getPicWidthInLumaSamples();
const int picHeight = pcPic->cs->pps->getPicHeightInLumaSamples();
const int maxCUWidth = pcPic->cs->sps->getMaxCUWidth();
const int maxCUHeight = pcPic->cs->sps->getMaxCUHeight();
const ChromaFormat chromaFormatIDC = pcPic->cs->sps->getChromaFormatIdc();
const int maxTotalCUDepth = floorLog2(maxCUWidth) - pcPic->cs->sps->getLog2MinCodingBlockSize();
m_pcSliceEncoder->create( picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth );

Karsten Suehring
committed
pcPic->scheduler.init( pcPic->cs->pcv->heightInCtus, pcPic->cs->pcv->widthInCtus, 1 , 0 , m_pcCfg->getNumSplitThreads() );
#endif
pcPic->createTempBuffers( pcPic->cs->pps->pcv->maxCUWidth );
pcPic->cs->createCoeffs((bool)pcPic->cs->sps->getPLTMode());

Karsten Suehring
committed
// Slice data initialization
pcPic->clearSliceBuffer();
pcPic->allocateNewSlice();
m_pcSliceEncoder->setSliceSegmentIdx(0);
m_pcSliceEncoder->initEncSlice(pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField, isEncodeLtRef, m_pcEncLib->getLayerId() );

Karsten Suehring
committed
DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "poc", pocCurr ) ) );
DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 0 ) ) );
#if !SHARP_LUMA_DELTA_QP
//Set Frame/Field coding
pcPic->fieldPic = isField;
#endif
pcSlice->setLastIDR(m_iLastIDR);

Karsten Suehring
committed
pcSlice->setIndependentSliceIdx(0);
if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
{
pcSlice->setSliceType(P_SLICE);
}
if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='I')
{
pcSlice->setSliceType(I_SLICE);
}
pcSlice->setTLayer(m_pcCfg->getGOPEntry(iGOPid).m_temporalId);
if (m_pcCfg->getGdrEnabled() && pocCurr >= m_pcCfg->getGdrPocStart())
else if (m_pcCfg->getGdrEnabled() && (pocCurr != 0) && (pocCurr < m_pcCfg->getGdrPocStart()))
{
pcSlice->setSliceType(B_SLICE);
}
// note : first picture is GDR(I_SLICE)
if (m_pcCfg->getGdrEnabled() && pocCurr == 0)
{
pcSlice->setSliceType(I_SLICE);
}
#endif
// Set the nal unit type
pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
// set two flags according to slice type presented in the picture
if (pcSlice->getSliceType() != I_SLICE)
picHeader->setPicInterSliceAllowedFlag(true);
if (pcSlice->getSliceType() == I_SLICE)
picHeader->setPicIntraSliceAllowedFlag(true);
picHeader->setGdrOrIrapPicFlag(picHeader->getGdrPicFlag() || pcSlice->isIRAP());

Karsten Suehring
committed
if (m_pcCfg->getEfficientFieldIRAPEnabled())
{
if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) // IRAP picture

Karsten Suehring
committed
{
m_associatedIRAPType[pcPic->layerId] = pcSlice->getNalUnitType();
m_associatedIRAPPOC[pcPic->layerId] = pocCurr;

Karsten Suehring
committed
}
pcSlice->setAssociatedIRAPType(m_associatedIRAPType[pcPic->layerId]);
pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC[pcPic->layerId]);

Karsten Suehring
committed
}
pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcCfg->getEfficientFieldIRAPEnabled());
if (m_pcCfg->getUseCompositeRef() && isEncodeLtRef)
{
setUseLTRef(true);
setPrepareLTRef(false);
setNewestBgPOC(pocCurr);
setLastLTRefPoc(pocCurr);
}
else if (m_pcCfg->getUseCompositeRef() && getLastLTRefPoc() >= 0 && getEncodedLTRef()==false && !getPicBg()->getSpliceFull() && (pocCurr - getLastLTRefPoc()) > (m_pcCfg->getFrameRate() * 2))
{
setUseLTRef(false);
setPrepareLTRef(false);
setEncodedLTRef(true);
setNewestBgPOC(-1);
setLastLTRefPoc(-1);
}
if (m_pcCfg->getUseCompositeRef() && m_picBg->getSpliceFull() && getUseLTRef())
{
m_pcEncLib->selectReferencePictureList(pcSlice, pocCurr, iGOPid, m_bgPOC);
}
else
{
m_pcEncLib->selectReferencePictureList(pcSlice, pocCurr, iGOPid, -1);
}

Karsten Suehring
committed
if (!m_pcCfg->getEfficientFieldIRAPEnabled())
{
if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) // IRAP picture

Karsten Suehring
committed
{
m_associatedIRAPType[pcPic->layerId] = pcSlice->getNalUnitType();
m_associatedIRAPPOC[pcPic->layerId] = pocCurr;

Karsten Suehring
committed
}
pcSlice->setAssociatedIRAPType(m_associatedIRAPType[pcPic->layerId]);
pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC[pcPic->layerId]);

Karsten Suehring
committed
}
pcSlice->setEnableDRAPSEI(m_pcEncLib->getDependentRAPIndicationSEIEnabled());
if (m_pcEncLib->getDependentRAPIndicationSEIEnabled())
{
// Only mark the picture as DRAP if all of the following applies:
// 1) DRAP indication SEI messages are enabled
// 2) The current picture is not an intra picture
// 3) The current picture is in the DRAP period
// 4) The current picture is a trailing picture
pcSlice->setDRAP(m_pcEncLib->getDependentRAPIndicationSEIEnabled() && m_pcEncLib->getDrapPeriod() > 0 && !pcSlice->isIntra() &&
pocCurr % m_pcEncLib->getDrapPeriod() == 0 && pocCurr > pcSlice->getAssociatedIRAPPOC());
if (pcSlice->isDRAP())
{
int pocCycle = 1 << (pcSlice->getSPS()->getBitsForPOC());
int deltaPOC = pocCurr > pcSlice->getAssociatedIRAPPOC() ? pocCurr - pcSlice->getAssociatedIRAPPOC() : pocCurr - ( pcSlice->getAssociatedIRAPPOC() & (pocCycle -1) );
CHECK(deltaPOC > (pocCycle >> 1), "Use a greater value for POC wraparound to enable a POC distance between IRAP and DRAP of " << deltaPOC << ".");
pcSlice->setTLayer(0); // Force DRAP picture to have temporal layer 0
}
pcSlice->setLatestDRAPPOC(m_latestDRAPPOC);
pcSlice->setUseLTforDRAP(false); // When set, sets the associated IRAP as long-term in RPL0 at slice level, unless the associated IRAP is already included in RPL0 or RPL1 defined in SPS
PicList::iterator iterPic = rcListPic.begin();
Picture *rpcPic;
while (iterPic != rcListPic.end())
{
rpcPic = *(iterPic++);
if ( pcSlice->isDRAP() && rpcPic->getPOC() != pocCurr )
{
rpcPic->precedingDRAP = true;
}
else if ( !pcSlice->isDRAP() && rpcPic->getPOC() == pocCurr )
{
rpcPic->precedingDRAP = false;
}
}
}
if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 ||
(m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) )
|| ((m_pcEncLib->getAvoidIntraInDepLayer() || !pcSlice->isIRAP()) && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId())))
xCreateExplicitReferencePictureSetFromReference( pcSlice, rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1() );
Jonatan Samuelsson-Allendes
committed
pcSlice->applyReferencePictureListBasedMarking( rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1(), pcSlice->getPic()->layerId, *(pcSlice->getPPS()));

Karsten Suehring
committed
if(pcSlice->getTLayer() > 0
&& !(pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL // Check if not a leading picture
|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL)

Karsten Suehring
committed
)
{
if (pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))

Karsten Suehring
committed
{
bool isSTSA=true;
for(int ii=0;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)

Karsten Suehring
committed
{
int lTid = m_pcCfg->getRPLEntry(0, ii).m_temporalId;
if (lTid == pcSlice->getTLayer())
{
const ReferencePictureList* rpl0 = pcSlice->getSPS()->getRPLList0()->getReferencePictureList(ii);
for (int jj = 0; jj < pcSlice->getRPL0()->getNumberOfActivePictures(); jj++)
{
#if JVET_S0045_SIGN
int tPoc = pcSlice->getPOC() + rpl0->getRefPicIdentifier(jj);
#else
int tPoc = pcSlice->getPOC() - rpl0->getRefPicIdentifier(jj);
int kk = 0;
for (kk = 0; kk<m_pcCfg->getGOPSize(); kk++)
{
if (m_pcCfg->getRPLEntry(0, kk).m_POC == tPoc)
{
break;
}
}
int tTid = m_pcCfg->getRPLEntry(0, kk).m_temporalId;
if (tTid >= pcSlice->getTLayer())
{
isSTSA = false;
break;
}
}
const ReferencePictureList* rpl1 = pcSlice->getSPS()->getRPLList1()->getReferencePictureList(ii);
for (int jj = 0; jj < pcSlice->getRPL1()->getNumberOfActivePictures(); jj++)
{
#if JVET_S0045_SIGN
int tPoc = pcSlice->getPOC() + rpl1->getRefPicIdentifier(jj);
#else
int tPoc = pcSlice->getPOC() - rpl1->getRefPicIdentifier(jj);
int kk = 0;
for (kk = 0; kk<m_pcCfg->getGOPSize(); kk++)
{
if (m_pcCfg->getRPLEntry(1, kk).m_POC == tPoc)
{
break;
}
}
int tTid = m_pcCfg->getRPLEntry(1, kk).m_temporalId;
if (tTid >= pcSlice->getTLayer())
{
isSTSA = false;
break;
}
}
}

Karsten Suehring
committed
}
if(isSTSA==true)
{
pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA);

Karsten Suehring
committed
}
}
}
if (m_pcCfg->getUseCompositeRef() && getUseLTRef() && (pocCurr > getLastLTRefPoc()))
{
pcSlice->setNumRefIdx(REF_PIC_LIST_0, (pcSlice->isIntra()) ? 0 : min(m_pcCfg->getRPLEntry(0, iGOPid).m_numRefPicsActive + 1, pcSlice->getRPL0()->getNumberOfActivePictures()));
pcSlice->setNumRefIdx(REF_PIC_LIST_1, (!pcSlice->isInterB()) ? 0 : min(m_pcCfg->getRPLEntry(1, iGOPid).m_numRefPicsActive + 1, pcSlice->getRPL1()->getNumberOfActivePictures()));
}
else
{
pcSlice->setNumRefIdx(REF_PIC_LIST_0, (pcSlice->isIntra()) ? 0 : pcSlice->getRPL0()->getNumberOfActivePictures());
pcSlice->setNumRefIdx(REF_PIC_LIST_1, (!pcSlice->isInterB()) ? 0 : pcSlice->getRPL1()->getNumberOfActivePictures());
}
if (m_pcCfg->getUseCompositeRef() && getPrepareLTRef()) {
arrangeCompositeReference(pcSlice, rcListPic, pocCurr);
}

Karsten Suehring
committed
// Set reference list
// store sub-picture numbers, sizes, and locations with a picture
#if JVET_S0258_SUBPIC_CONSTRAINTS
pcSlice->getPic()->subPictures.clear();
for( int subPicIdx = 0; subPicIdx < pcPic->cs->pps->getNumSubPics(); subPicIdx++ )
{
pcSlice->getPic()->subPictures.push_back( pcPic->cs->pps->getSubPic( subPicIdx ) );
}
#else
pcSlice->getPic()->numSubpics = pcPic->cs->pps->getNumSubPics();
pcSlice->getPic()->subpicWidthInCTUs.clear();
pcSlice->getPic()->subpicHeightInCTUs.clear();
pcSlice->getPic()->subpicCtuTopLeftX.clear();
pcSlice->getPic()->subpicCtuTopLeftY.clear();
for (int subPicIdx = 0; subPicIdx < pcPic->cs->pps->getNumSubPics(); subPicIdx++)
{
pcSlice->getPic()->subpicWidthInCTUs.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicWidthInCTUs());
pcSlice->getPic()->subpicHeightInCTUs.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicHeightInCTUs());
pcSlice->getPic()->subpicCtuTopLeftX.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicCtuTopLeftX());
pcSlice->getPic()->subpicCtuTopLeftY.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicCtuTopLeftY());
const VPS* vps = pcPic->cs->vps;
int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx(pcPic->layerId);
if (vps && !vps->getIndependentLayerFlag(layerIdx) && pcPic->cs->pps->getNumSubPics() > 1)
{
xPicInitHashME( pcPic, pcSlice->getPPS(), rcListPic );

Karsten Suehring
committed
if( m_pcCfg->getUseAMaxBT() )
{
if( !pcSlice->isIntra() )

Karsten Suehring
committed
{
int refLayer = pcSlice->getDepth();
if( refLayer > 9 ) refLayer = 9; // Max layer is 10
#if JVET_X0144_MAX_MTT_DEPTH_TID
if( m_pcCfg->getMaxMTTHierarchyDepthByTid( refLayer ) != m_pcCfg->getMaxMTTHierarchyDepth() )
{
picHeader->setSplitConsOverrideFlag( true );
picHeader->setMaxMTTHierarchyDepth( P_SLICE, m_pcCfg->getMaxMTTHierarchyDepthByTid( refLayer ) );
}
#endif

Karsten Suehring
committed
if( m_bInitAMaxBT && pcSlice->getPOC() > m_uiPrevISlicePOC )
{
::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
::memset( m_uiNumBlk, 0, sizeof( m_uiNumBlk ) );
m_bInitAMaxBT = false;
}
if( refLayer >= 0 && m_uiNumBlk[refLayer] != 0 )
{
picHeader->setSplitConsOverrideFlag(true);
double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] );
unsigned int newMaxBtSize = picHeader->getMaxBTSize(pcSlice->getSliceType(), CHANNEL_TYPE_LUMA);
if( dBlkSize < AMAXBT_TH32 )
else if( dBlkSize < AMAXBT_TH64 )
#if CTU_256
else if( dBlkSize < AMAXBT_TH128 )
{
newMaxBtSize = 128;
}
else
{
newMaxBtSize = 256;
}
#else
newMaxBtSize = Clip3(picHeader->getMinQTSize(pcSlice->getSliceType()), pcPic->cs->sps->getCTUSize(), newMaxBtSize);
picHeader->setMaxBTSize(1, newMaxBtSize);

Karsten Suehring
committed
m_uiBlkSize[refLayer] = 0;
m_uiNumBlk [refLayer] = 0;
}
}
else
{
if( m_bInitAMaxBT )
{
::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
::memset( m_uiNumBlk, 0, sizeof( m_uiNumBlk ) );
}
m_uiPrevISlicePOC = pcSlice->getPOC();
m_bInitAMaxBT = true;
}
#if JVET_S0133_PH_SYNTAX_OVERRIDE_ENC_FIX
bool identicalToSPS=true;
const SPS* sps =pcSlice->getSPS();
if (picHeader->getPicInterSliceAllowedFlag())
{
if (picHeader->getMinQTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMinQTSize(pcSlice->getSliceType()) ||
picHeader->getMaxMTTHierarchyDepth(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxMTTHierarchyDepth() ||
picHeader->getMaxBTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxBTSize() ||
picHeader->getMaxTTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxTTSize()
)
{
identicalToSPS=false;
}
}
if (identicalToSPS && picHeader->getPicIntraSliceAllowedFlag())
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
{
if (picHeader->getMinQTSize(I_SLICE) != sps->getMinQTSize(I_SLICE) ||
picHeader->getMaxMTTHierarchyDepth(I_SLICE) != sps->getMaxMTTHierarchyDepthI() ||
picHeader->getMaxBTSize(I_SLICE) != sps->getMaxBTSizeI() ||
picHeader->getMaxTTSize(I_SLICE) != sps->getMaxTTSizeI()
)
{
identicalToSPS=false;
}
if (identicalToSPS && sps->getUseDualITree())
{
if (picHeader->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA) ||
picHeader->getMaxMTTHierarchyDepth(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxMTTHierarchyDepthIChroma() ||
picHeader->getMaxBTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxBTSizeIChroma() ||
picHeader->getMaxTTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxTTSizeIChroma()
)
{
identicalToSPS=false;
}
}
}
if (identicalToSPS)
{
picHeader->setSplitConsOverrideFlag(false);
}
#endif

Karsten Suehring
committed
}
// Slice info. refinement
if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
{
pcSlice->setSliceType ( P_SLICE );
}

Karsten Suehring
committed
xUpdateRasInit( pcSlice );
if ( pcSlice->getPendingRasInit() )
{
// this ensures that independently encoded bitstream chunks can be combined to bit-equal
pcSlice->setEncCABACTableIdx( pcSlice->getSliceType() );
}
else
{
pcSlice->setEncCABACTableIdx( m_pcSliceEncoder->getEncCABACTableIdx() );
}
if (pcSlice->getSliceType() == B_SLICE)
{

Karsten Suehring
committed
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
bool bLowDelay = true;
int iCurrPOC = pcSlice->getPOC();
int iRefIdx = 0;
for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
{
if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
{
bLowDelay = false;
}
}
for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
{
if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
{
bLowDelay = false;
}
}
pcSlice->setCheckLDC(bLowDelay);
}
else
{
pcSlice->setCheckLDC(true);
}
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
#if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
if (!pcSlice->isIntra() && pcSlice->getSPS()->getUseAML())
{
int index = pcSlice->getSPS()->getQPOffsetsIdx(pcSlice->getSliceQp() - (pcSlice->getPPS()->getPicInitQPMinus26() + 26));
if (index != -1)
{
const SPS* sps = pcSlice->getSPS();
pcSlice->setCostForARMC(sps->getLambdaVal(index));
}
else
{
pcSlice->setCostForARMC((uint32_t) LAMBDA_DEC_SIDE[min(max(pcSlice->getSliceQp(), 0), MAX_QP)]);
}
if (pcSlice->getCheckLDC())
{
int iCurrPOC = pcSlice->getPOC();
int iRefIdx = 0;
int mindist = MAX_INT;
for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0); iRefIdx++)
{
if (abs(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() - iCurrPOC) < mindist)
{
mindist = abs(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() - iCurrPOC);
}
}
if (pcSlice->isInterB())
{
for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1); iRefIdx++)
{
if (abs(pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() - iCurrPOC) < mindist)
{
mindist = abs(pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() - iCurrPOC);
}
}
}
if (mindist != 1 )
{
pcSlice->setCostForARMC((uint32_t) LAMBDA_DEC_SIDE[min(max(pcSlice->getSliceQp() - 4, 0), MAX_QP)]);
}
}
else
{
pcSlice->setCostForARMC((uint32_t) LAMBDA_DEC_SIDE[min(max(pcSlice->getSliceQp() - 4, 0), MAX_QP)]);
}
}
#endif

Karsten Suehring
committed
//-------------------------------------------------------------
#if MULTI_HYP_PRED
pcSlice->setNumMultiHypRefPics(pcSlice->getSPS()->getMaxNumAddHypRefFrames());
#endif

Karsten Suehring
committed
pcSlice->setRefPOCList();
#if MULTI_HYP_PRED
pcSlice->setNumMultiHypRefPics((int)pcSlice->getMultiHypRefPicList().size());
#endif

Karsten Suehring
committed
pcSlice->setList1IdxToList0Idx();

Karsten Suehring
committed
if (m_pcEncLib->getTMVPModeId() == 2)
{
if (iGOPid == 0) // first picture in SOP (i.e. forward B)
{

Karsten Suehring
committed
}
else
{
// Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.

Karsten Suehring
committed
}
}
else if (m_pcEncLib->getTMVPModeId() == 1)

Karsten Suehring
committed
{

Karsten Suehring
committed
}
else
{

Karsten Suehring
committed
}
// disable TMVP when current picture is the only ref picture
if (pcSlice->isIRAP() && pcSlice->getSPS()->getIBCFlag())
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
int poc1stCol = -1;
int list1stCol = 0;
int list2ndCol = 0;
#endif
if (pcSlice->getSliceType() != I_SLICE && picHeader->getEnableTMVPFlag())
{
int colRefIdxL0 = -1, colRefIdxL1 = -1;
const bool isResamplingPossible = pcSlice->getSPS()->getRprEnabledFlag();
for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0); refIdx++)
CHECK(pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->unscaledPic == nullptr, "unscaledPic is not set for L0 reference picture");
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
if ((!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->isRefScaled(pcSlice->getPPS())) /*&& (pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->slices[0]->getSliceType() != I_SLICE)*/)
#else
if (!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->isRefScaled(pcSlice->getPPS()))
#endif
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
poc1stCol = pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->getPOC();
list1stCol = 0;
#endif
colRefIdxL0 = refIdx;
break;
}
}
if (pcSlice->getSliceType() == B_SLICE)
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
list2ndCol = 1;
if (colRefIdxL0 < 0)
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1); refIdx++)
{
CHECK(pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->unscaledPic == nullptr, "unscaledPic is not set for L1 reference picture");
if ((!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->isRefScaled(pcSlice->getPPS())) /*&& (pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->slices[0]->getSliceType() != I_SLICE)*/)
{
poc1stCol = pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->getPOC();
list1stCol = 1;
colRefIdxL0 = refIdx;
break;
}
}
}
#endif
for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1); refIdx++)
{
CHECK(pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->unscaledPic == nullptr, "unscaledPic is not set for L1 reference picture");
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
int poc2ndCol = pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->getPOC();
if ((poc1stCol != poc2ndCol) && (!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->isRefScaled(pcSlice->getPPS())) /*&& (pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->slices[0]->getSliceType() != I_SLICE)*/)
#else
if (!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->isRefScaled(pcSlice->getPPS()))
#endif
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
list2ndCol = 1;
#endif
colRefIdxL1 = refIdx;
break;
}
}
}
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
else
{
for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0); refIdx++)
{
int poc2ndCol = pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->getPOC();
CHECK(pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->unscaledPic == nullptr, "unscaledPic is not set for L0 reference picture");
if ((poc1stCol != poc2ndCol) && (!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->isRefScaled(pcSlice->getPPS())) /*&& (pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->slices[0]->getSliceType() != I_SLICE)*/)
{
colRefIdxL1 = refIdx;
break;
}
}
}
#endif
if (colRefIdxL0 >= 0 && colRefIdxL1 >= 0)
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
const Picture *refPicL0 = pcSlice->getRefPic(RefPicList(list1stCol), colRefIdxL0);
if (!refPicL0->slices.size())
{
refPicL0 = refPicL0->unscaledPic;
}
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
const Picture *refPicL1 = pcSlice->getRefPic(RefPicList(list2ndCol), colRefIdxL1);
if (!refPicL1->slices.size())
{
refPicL1 = refPicL1->unscaledPic;
}
picHeader->setPicColFromL0Flag(1 - list1stCol);
pcSlice->setColFromL0Flag(1 - list1stCol);
pcSlice->setColRefIdx(colRefIdxL0);
picHeader->setColRefIdx(colRefIdxL0);
picHeader->setPicColFromL0Flag2nd(1 - list2ndCol);
pcSlice->setColFromL0Flag2nd(1 - list2ndCol);
pcSlice->setColRefIdx2nd(colRefIdxL1);
picHeader->setColRefIdx2nd(colRefIdxL1);
int poc1st = refPicL0->getPOC();
int poc2nd = refPicL1->getPOC();
int pocCur = pcSlice->getPOC();
if ((abs(poc1st - pocCur) == abs(poc2nd - pocCur)) && (refPicL0->slices[0]->getSliceQp() < refPicL1->slices[0]->getSliceQp()))
{
picHeader->setPicColFromL0Flag2nd(1 - list1stCol);
pcSlice->setColFromL0Flag2nd(1 - list1stCol);
pcSlice->setColRefIdx2nd(colRefIdxL0);
picHeader->setColRefIdx2nd(colRefIdxL0);
picHeader->setPicColFromL0Flag(1 - list2ndCol);
pcSlice->setColFromL0Flag(1 - list2ndCol);
pcSlice->setColRefIdx(colRefIdxL1);
picHeader->setColRefIdx(colRefIdxL1);
}
#else
const Picture *refPicL0 = pcSlice->getRefPic(REF_PIC_LIST_0, colRefIdxL0);
if (!refPicL0->slices.size())
{
refPicL0 = refPicL0->unscaledPic;
}
const Picture *refPicL1 = pcSlice->getRefPic(REF_PIC_LIST_1, colRefIdxL1);
if (!refPicL1->slices.size())
{
refPicL1 = refPicL1->unscaledPic;
}
CHECK(!refPicL0->slices.size(), "Wrong L0 reference picture");
CHECK(!refPicL1->slices.size(), "Wrong L1 reference picture");
const uint32_t uiColFromL0 = refPicL0->slices[0]->getSliceQp() > refPicL1->slices[0]->getSliceQp();
picHeader->setPicColFromL0Flag(uiColFromL0);
pcSlice->setColFromL0Flag(uiColFromL0);
pcSlice->setColRefIdx(uiColFromL0 ? colRefIdxL0 : colRefIdxL1);
picHeader->setColRefIdx(uiColFromL0 ? colRefIdxL0 : colRefIdxL1);
#endif
#if !JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
else if (colRefIdxL0 < 0 && colRefIdxL1 >= 0)
picHeader->setPicColFromL0Flag(false);
pcSlice->setColFromL0Flag(false);
pcSlice->setColRefIdx(colRefIdxL1);
picHeader->setColRefIdx(colRefIdxL1);
#endif
else if (colRefIdxL0 >= 0 && colRefIdxL1 < 0)
{
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
picHeader->setPicColFromL0Flag(1 - list1stCol);
pcSlice->setColFromL0Flag(1 - list1stCol);
pcSlice->setColRefIdx(colRefIdxL0);
picHeader->setColRefIdx(colRefIdxL0);
picHeader->setPicColFromL0Flag2nd(1 - list2ndCol);
pcSlice->setColFromL0Flag2nd(1 - list2ndCol);
pcSlice->setColRefIdx2nd(0);
picHeader->setColRefIdx2nd(0);
#else
picHeader->setPicColFromL0Flag(true);
pcSlice->setColFromL0Flag(true);
pcSlice->setColRefIdx(colRefIdxL0);
picHeader->setColRefIdx(colRefIdxL0);
#endif
}
else
{
picHeader->setEnableTMVPFlag(0);
#if JVET_Y0134_TMVP_NAMVP_CAND_REORDERING
if (picHeader->getEnableTMVPFlag())
{
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
for (int colFrameIdx = 0; colFrameIdx < (pcSlice->isInterB() ? 2 : 1); colFrameIdx++)
{
const Picture* const pColPic = pcSlice->getRefPic(RefPicList(colFrameIdx == 0 ? 1 - pcSlice->getColFromL0Flag() : 1 - pcSlice->getColFromL0Flag2nd()), colFrameIdx == 0 ? pcSlice->getColRefIdx() : pcSlice->getColRefIdx2nd());
#else
const Picture* const pColPic = pcSlice->getRefPic(RefPicList(pcSlice->isInterB() ? 1 - pcSlice->getColFromL0Flag() : 0), pcSlice->getColRefIdx());
if (pColPic)
{
const int currPOC = pcSlice->getPOC();
const int colPOC = pColPic->getPOC();
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
pcSlice->resizeImBuf(pColPic->numSlices, colFrameIdx);
#else
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
Slice *pColSlice = nullptr;
for (int sliceIdx = 0; sliceIdx < pColPic->numSlices; sliceIdx++)
{
pColSlice = pColPic->slices[sliceIdx];
if (pColSlice->isIntra())
{
continue;
}
for (int colRefPicListIdx = 0; colRefPicListIdx < (pColSlice->isInterB() ? 2 : 1); colRefPicListIdx++)
{
for (int colRefIdx = 0; colRefIdx < pColSlice->getNumRefIdx(RefPicList(colRefPicListIdx)); colRefIdx++)
{
const bool bIsColRefLongTerm = pColSlice->getIsUsedAsLongTerm(RefPicList(colRefPicListIdx), colRefIdx);
const int colRefPOC = pColSlice->getRefPOC(RefPicList(colRefPicListIdx), colRefIdx);
for (int curRefPicListIdx = 0; curRefPicListIdx < (pcSlice->isInterB() ? 2 : 1); curRefPicListIdx++)
{
double bestDistScale = 1000;
int targetRefIdx = -1;
for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx)); curRefIdx++)
{
const int currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
const bool bIsCurrRefLongTerm = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
if (bIsCurrRefLongTerm != bIsColRefLongTerm)
{
continue;
}
if (bIsCurrRefLongTerm)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
break;
}
else if (colPOC - colRefPOC == currPOC - currRefPOC)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
break;
}
else
{
//printf("colRefPicListIdx:%d, curRefPicListIdx:%d, colRefIdx:%d, targetRefIdx:%d, curRefIdx:%d\n", colRefPicListIdx, curRefPicListIdx, colRefIdx, targetRefIdx, curRefIdx);
//printf("currPOC:%d, currRefPOC:%d, colPOC:%d, colRefPOC:%d\n", currPOC, currRefPOC, colPOC, colRefPOC);
//printf("bestDistScale:%.2f %.2f\n", bestDistScale, abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)));
if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)) < bestDistScale)
{
bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
targetRefIdx = curRefIdx;
}
}
} // curRefIdx
//printf("sliceIdx:%d, colRefPicListIdx:%d, curRefPicListIdx:%d, colRefIdx:%d, targetRefIdx:%d\n", sliceIdx, colRefPicListIdx, curRefPicListIdx, colRefIdx, targetRefIdx);
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx, colFrameIdx);
#else
pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx);
} // curRefPicListIdx
}
}
}
}
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
}
#endif
}
#if JVET_Y0128_NON_CTC
bool bDisableTMVP;
if (pcPic->cs->isGdrEnabled())
{
PicHeader *picHeader = new PicHeader;
*picHeader = *pcPic->cs->picHeader;
bDisableTMVP = pcSlice->scaleRefPicList(scaledRefPic, picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
}
else
{
bDisableTMVP = pcSlice->scaleRefPicList(scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
}
bool bDisableTMVP = pcSlice->scaleRefPicList( scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
if ( picHeader->getEnableTMVPFlag() && bDisableTMVP )
{