Newer
Older
ioBeforeInLoop.write( pcPic->getRecoBuf().get( COMPONENT_Y ).width, pcPic->getRecoBuf().get( COMPONENT_Y ).height, pcPic->getRecoBuf(),
outputColourSpaceConvert,
packedYUVMode,
conf.getWindowLeftOffset() * SPS::getWinUnitX( chromaFormatIDC ),
conf.getWindowRightOffset() * SPS::getWinUnitX( chromaFormatIDC ),
conf.getWindowTopOffset() * SPS::getWinUnitY( chromaFormatIDC ),
conf.getWindowBottomOffset() * SPS::getWinUnitY( chromaFormatIDC ),
NUM_CHROMA_FORMAT, clipOutputVideoToRec709Range );
}
}
}
#endif

Karsten Suehring
committed
CodingStructure& cs = *pcPic->cs;
pcSlice = pcPic->slices[0];
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
if (cs.sps->getUseLmcs() && m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper())
{
picHeader->setLmcsEnabledFlag(true);
int apsId = std::min<int>(3, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx(m_pcEncLib->getLayerId()));
picHeader->setLmcsAPSId(apsId);
const PreCalcValues& pcv = *cs.pcv;
for (uint32_t yPos = 0; yPos < pcv.lumaHeight; yPos += pcv.maxCUHeight)
{
for (uint32_t xPos = 0; xPos < pcv.lumaWidth; xPos += pcv.maxCUWidth)
{
const CodingUnit* cu = cs.getCU(Position(xPos, yPos), CHANNEL_TYPE_LUMA);
if (cu->slice->getLmcsEnabledFlag())
{
const uint32_t width = (xPos + pcv.maxCUWidth > pcv.lumaWidth) ? (pcv.lumaWidth - xPos) : pcv.maxCUWidth;
const uint32_t height = (yPos + pcv.maxCUHeight > pcv.lumaHeight) ? (pcv.lumaHeight - yPos) : pcv.maxCUHeight;
const UnitArea area(cs.area.chromaFormat, Area(xPos, yPos, width, height));
cs.getRecoBuf(area).get(COMPONENT_Y).rspSignal(m_pcReshaper->getInvLUT());
}
}
}
m_pcReshaper->setRecReshaped(false);
if( m_pcCfg->getGopBasedTemporalFilterEnabled() )
{
pcPic->getOrigBuf().copyFrom( pcPic->getFilteredOrigBuf() );
}
else
{
pcPic->getOrigBuf().copyFrom( pcPic->getTrueOrigBuf() );
}
}
#if RPR_ENABLE
// create SAO object based on the picture size
if ( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() )
{
Size saoSize = m_pcSAO->getSaoSize();
if ( saoSize.width != picWidth || saoSize.height != picHeight ) {
const uint32_t widthInCtus = (picWidth + maxCUWidth - 1) / maxCUWidth;
const uint32_t heightInCtus = (picHeight + maxCUHeight - 1) / maxCUHeight;
const uint32_t numCtuInFrame = widthInCtus * heightInCtus;
const uint32_t log2SaoOffsetScaleLuma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - MAX_SAO_TRUNCATED_BITDEPTH);
const uint32_t log2SaoOffsetScaleChroma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - MAX_SAO_TRUNCATED_BITDEPTH);
m_pcSAO->create(picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, log2SaoOffsetScaleLuma, log2SaoOffsetScaleChroma);
m_pcSAO->destroyEncData();
m_pcSAO->createEncData(m_pcCfg->getSaoCtuBoundary(), numCtuInFrame);
m_pcSAO->setReshaper(m_pcReshaper);
}
}
#endif
if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
{
picHeader->setExplicitScalingListEnabledFlag(true);
pcSlice->setExplicitScalingListUsed(true);
int apsId = 0;
picHeader->setScalingListAPSId( apsId );
}

Karsten Suehring
committed
// SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
if( pcSlice->getSPS()->getSAOEnabledFlag() && m_pcCfg->getSaoCtuBoundary() )

Karsten Suehring
committed
{

Karsten Suehring
committed
m_pcSAO->getPreDBFStatistics( cs );
}
//-- Loop filter
if ( m_pcCfg->getDeblockingFilterMetric() )
{
#if W0038_DB_OPT
if ( m_pcCfg->getDeblockingFilterMetric()==2 )
{
applyDeblockingFilterParameterSelection(pcPic, uiNumSliceSegments, iGOPid);
}
else
{
#endif
applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);
#if W0038_DB_OPT
}
#endif
}
#if DB_PARAM_TID
else
{
applyDeblockingFilterParameterSelection( pcPic, pcSlice, uiNumSliceSegments, iGOPid );
}
#endif
if (m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
{
for (int s = 0; s < uiNumSliceSegments; s++)
{
if (pcPic->slices[s]->isLossless())
{
pcPic->slices[s]->setDeblockingFilterDisable(true);
}
}
}

Karsten Suehring
committed
m_pcLoopFilter->loopFilterPic( cs );
CS::setRefinedMotionField(cs);

Karsten Suehring
committed
#if JVET_W0066_CCSAO
if ( cs.sps->getCCSAOEnabledFlag() )
{
m_pcSAO->getCcSaoBuf().copyFrom( cs.getRecoBuf() );
}
#endif
// We need to do this step if at least one of BIF or SAO are enabled.
if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF())
#else
if( pcSlice->getSPS()->getSAOEnabledFlag() )

Karsten Suehring
committed
{
bool sliceEnabled[MAX_NUM_COMPONENT];
m_pcSAO->initCABACEstimator( m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice );
BIFCabacEstImp est(m_pcEncLib->getCABACEncoder()->getCABACEstimator(cs.slice->getSPS()));
#endif

Christian Helmrich
committed
m_pcSAO->SAOProcess( cs, sliceEnabled, pcSlice->getLambdas(),
#if ENABLE_QPA
(m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost (PARL_PARAM0 (0))->getChromaWeight() : 0.0),
#endif
m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary(), m_pcCfg->getSaoGreedyMergeEnc()

Karsten Suehring
committed
//assign SAO slice header
if( pcSlice->getSPS()->getSAOEnabledFlag() )
{
#endif
for (int s = 0; s < uiNumSliceSegments; s++)

Karsten Suehring
committed
{
if (pcPic->slices[s]->isLossless() && m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
{
pcPic->slices[s]->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, false);
pcPic->slices[s]->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, false);
}
else
{
pcPic->slices[s]->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, sliceEnabled[COMPONENT_Y]);
CHECK(!(sliceEnabled[COMPONENT_Cb] == sliceEnabled[COMPONENT_Cr]), "Unspecified error");
pcPic->slices[s]->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, sliceEnabled[COMPONENT_Cb]);
}

Karsten Suehring
committed
}

Karsten Suehring
committed
}
#if JVET_W0066_CCSAO
if ( pcSlice->getSPS()->getCCSAOEnabledFlag() )
{
m_pcSAO->initCABACEstimator( m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice );
m_pcSAO->CCSAOProcess( cs, pcSlice->getLambdas(), m_pcCfg->getIntraPeriod() );
//assign CCSAO slice header
for (int s = 0; s < uiNumSliceSegments; s++)
{
pcPic->slices[s]->m_ccSaoComParam = m_pcSAO->getCcSaoComParam();
pcPic->slices[s]->m_ccSaoControl[COMPONENT_Y] = m_pcSAO->getCcSaoControlIdc(COMPONENT_Y);
pcPic->slices[s]->m_ccSaoControl[COMPONENT_Cb] = m_pcSAO->getCcSaoControlIdc(COMPONENT_Cb);
pcPic->slices[s]->m_ccSaoControl[COMPONENT_Cr] = m_pcSAO->getCcSaoControlIdc(COMPONENT_Cr);
}
}
m_pcSAO->jointClipSaoBifCcSao( cs );
#endif
#if RPR_ENABLE
// create ALF object based on the picture size
if ( pcSlice->getSPS()->getALFEnabledFlag() )
{
Size alfSize = m_pcALF->getAlfSize();
if ( alfSize.width != picWidth || alfSize.height != picHeight )
{
m_pcALF->destroy();
m_pcALF->create( m_pcCfg, picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, m_pcCfg->getBitDepth(), m_pcCfg->getInputBitDepth() );
}
}
#endif
if( pcSlice->getSPS()->getALFEnabledFlag() )
for (int s = 0; s < uiNumSliceSegments; s++)
{
pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Y, false);
}
m_pcALF->initCABACEstimator(m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice, m_pcEncLib->getApsMap());
m_pcALF->ALFProcess(cs, pcSlice->getLambdas()
#if ENABLE_QPA
, (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost(PARL_PARAM0(0))->getChromaWeight() : 0.0)
#endif
, pcPic, uiNumSliceSegments
);

Christian Helmrich
committed
//assign ALF slice header
for (int s = 0; s < uiNumSliceSegments; s++)
{
//For the first slice, even if it is lossless, slice level ALF is not disabled and ALF-APS is signaled so that the later lossy slices can use APS of the first slice.
//However, if the first slice is lossless, the ALF process is disabled for all of the CTUs ( m_ctuEnableFlag == 0) of that slice which is implemented in the function void EncAdaptiveLoopFilter::ALFProcess.
if (pcPic->slices[s]->isLossless() && s && m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
{
pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Y, false);
pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Cb, false);
pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Cr, false);
}
else
{
pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Y, cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y));
pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Cb, cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Cb));
pcPic->slices[s]->setTileGroupAlfEnabledFlag(COMPONENT_Cr, cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Cr));
}
if (pcPic->slices[s]->getTileGroupAlfEnabledFlag(COMPONENT_Y))
{
#if ALF_IMPROVEMENT
pcPic->slices[s]->setTileGroupAlfFixedFilterSetIdx(cs.slice->getTileGroupAlfFixedFilterSetIdx());
#endif
pcPic->slices[s]->setTileGroupNumAps(cs.slice->getTileGroupNumAps());
pcPic->slices[s]->setAlfAPSs(cs.slice->getTileGroupApsIdLuma());
}
else
{
pcPic->slices[s]->setTileGroupNumAps(0);
}
if( s < uiNumSliceSegments - 1 )
{
pcPic->slices[s]->setAlfAPSs(cs.slice->getAlfAPSs());
}
pcPic->slices[s]->setTileGroupApsIdChroma(cs.slice->getTileGroupApsIdChroma());
pcPic->slices[s]->setTileGroupCcAlfCbApsId(cs.slice->getTileGroupCcAlfCbApsId());
pcPic->slices[s]->setTileGroupCcAlfCrApsId(cs.slice->getTileGroupCcAlfCrApsId());
pcPic->slices[s]->m_ccAlfFilterParam = m_pcALF->getCcAlfFilterParam();
pcPic->slices[s]->m_ccAlfFilterControl[0] = m_pcALF->getCcAlfControlIdc(COMPONENT_Cb);
pcPic->slices[s]->m_ccAlfFilterControl[1] = m_pcALF->getCcAlfControlIdc(COMPONENT_Cr);

Karsten Suehring
committed
}
DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 1 ) ) );
if (m_pcCfg->getUseCompositeRef() && getPrepareLTRef())
{
updateCompositeReference(pcSlice, rcListPic, pocCurr);
}

Karsten Suehring
committed
}
else // skip enc picture
{
pcSlice->setSliceQpBase( pcSlice->getSliceQp() );

Christian Helmrich
committed
#if ENABLE_QPA
if (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP())
{
const double picLambda = pcSlice->getLambdas()[0];
for (uint32_t ctuRsAddr = 0; ctuRsAddr < numberOfCtusInFrame; ctuRsAddr++)
{
pcPic->m_uEnerHpCtu[ctuRsAddr] = picLambda; // initialize to slice lambda (just for safety)
}
}
#endif
if( pcSlice->getSPS()->getSAOEnabledFlag() )

Karsten Suehring
committed
{

Karsten Suehring
committed
m_pcSAO->disabledRate( *pcPic->cs, pcPic->getSAO(1), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma());
}
3296
3297
3298
3299
3300
3301
3302
3303
3304
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
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
if (pcSlice->getSPS()->getALFEnabledFlag() && (pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y) || pcSlice->getTileGroupCcAlfCbEnabledFlag() || pcSlice->getTileGroupCcAlfCrEnabledFlag()))
{
// IRAP AU: reset APS map
{
int layerIdx = pcSlice->getVPS() == nullptr ? 0 : pcSlice->getVPS()->getGeneralLayerIdx( pcSlice->getPic()->layerId );
if( !layerIdx && ( pcSlice->getPendingRasInit() || pcSlice->isIDRorBLA() ) )
{
// We have to reset all APS on IRAP, but in not encoding case we have to keep the parsed APS of current slice
// Get active ALF APSs from picture/slice header
const std::vector<int> sliceApsIdsLuma = pcSlice->getTileGroupApsIdLuma();
m_pcALF->setApsIdStart( ALF_CTB_MAX_NUM_APS );
ParameterSetMap<APS>* apsMap = m_pcEncLib->getApsMap();
apsMap->clear();
for( int apsId = 0; apsId < ALF_CTB_MAX_NUM_APS; apsId++ )
{
int psId = ( apsId << NUM_APS_TYPE_LEN ) + ALF_APS;
APS* aps = apsMap->getPS( psId );
if( aps )
{
// Check if this APS is currently the active one (used in current slice)
bool activeAps = false;
bool activeApsCcAlf = false;
// Luma
for( int i = 0; i < sliceApsIdsLuma.size(); i++ )
{
if( aps->getAPSId() == sliceApsIdsLuma[i] )
{
activeAps = true;
break;
}
}
// Chroma
activeAps |= aps->getAPSId() == pcSlice->getTileGroupApsIdChroma();
// CC-ALF
activeApsCcAlf |= pcSlice->getTileGroupCcAlfCbEnabledFlag() && aps->getAPSId() == pcSlice->getTileGroupCcAlfCbApsId();
activeApsCcAlf |= pcSlice->getTileGroupCcAlfCrEnabledFlag() && aps->getAPSId() == pcSlice->getTileGroupCcAlfCrApsId();
if( !activeAps && !activeApsCcAlf )
{
apsMap->clearChangedFlag( psId );
}
if( !activeAps )
{
aps->getAlfAPSParam().reset();
}
if( !activeApsCcAlf )
{
aps->getCcAlfAPSParam().reset();
}
}
}
}
}
// Assign tne correct APS to slice and emulate the setting of ALF start APS ID
int changedApsId = -1;
for( int apsId = ALF_CTB_MAX_NUM_APS - 1; apsId >= 0; apsId-- )
{
ParameterSetMap<APS>* apsMap = m_pcEncLib->getApsMap();
int psId = ( apsId << NUM_APS_TYPE_LEN ) + ALF_APS;
APS* aps = apsMap->getPS( psId );
if( aps )
{
// In slice, replace the old APS (from decoder map) with the APS from encoder map due to later checks while bitstream writing
if( pcSlice->getAlfAPSs() && pcSlice->getAlfAPSs()[apsId] )
{
pcSlice->getAlfAPSs()[apsId] = aps;
}
if( apsMap->getChangedFlag( psId ) )
changedApsId = apsId;
}
}
if( changedApsId >= 0 )
m_pcALF->setApsIdStart( changedApsId );
}

Karsten Suehring
committed
}
pcSlice->freeScaledRefPicList( scaledRefPic );

Karsten Suehring
committed
if( m_pcCfg->getUseAMaxBT() )
{
for( const CodingUnit *cu : pcPic->cs->cus )
{
if( !pcSlice->isIntra() )

Karsten Suehring
committed
{
m_uiBlkSize[pcSlice->getDepth()] += cu->Y().area();
m_uiNumBlk [pcSlice->getDepth()]++;
}
}
}
if( encPic || decPic )
{
pcSlice = pcPic->slices[0];
/////////////////////////////////////////////////////////////////////////////////////////////////// File writing

Karsten Suehring
committed
// write various parameter sets
bool writePS = m_bSeqFirst || (m_pcCfg->getReWriteParamSets() && (pcSlice->isIRAP()));
if (writePS)
{
m_pcEncLib->setParamSetChanged(pcSlice->getSPS()->getSPSId(), pcSlice->getPPS()->getPPSId());
}
int layerIdx = m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() );
Zhipin Deng
committed
// it is assumed that layerIdx equal to 0 is always present
m_audIrapOrGdrAuFlag = pcSlice->getPicHeader()->getGdrPicFlag() || (pcSlice->isIRAP() && !pcSlice->getPPS()->getMixedNaluTypesInPicFlag());
if ((( m_pcEncLib->getVPS()->getMaxLayers() > 1 && m_audIrapOrGdrAuFlag) || m_pcCfg->getAccessUnitDelimiter()) && !layerIdx )
{
xWriteAccessUnitDelimiter(accessUnit, pcSlice);
}
// it is assumed that layerIdx equal to 0 is always present
actualTotalBits += xWriteParameterSets(accessUnit, pcSlice, writePS, layerIdx);

Karsten Suehring
committed
{
// create prefix SEI messages at the beginning of the sequence
CHECK(!(leadingSeiMessages.empty()), "Unspecified error");
xCreateIRAPLeadingSEIMessages(leadingSeiMessages, pcSlice->getSPS(), pcSlice->getPPS());
m_bSeqFirst = false;
}
//send LMCS APS when LMCSModel is updated. It can be updated even current slice does not enable reshaper.
//For example, in RA, update is on intra slice, but intra slice may not use reshaper
if (pcSlice->getSPS()->getUseLmcs())
{
//only 1 LMCS data for 1 picture
ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
APS* aps = apsMap->getPS((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
bool writeAPS = aps && apsMap->getChangedFlag((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
if (writeAPS)
{
#if JVET_R0433
aps->chromaPresentFlag = pcSlice->getSPS()->getChromaFormatIdc() != CHROMA_400;
#endif
actualTotalBits += xWriteAPS( accessUnit, aps, m_pcEncLib->getLayerId(), true );
apsMap->clearChangedFlag((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
CHECK(aps != picHeader->getLmcsAPS(), "Wrong LMCS APS pointer in compressGOP");
// only 1 SCALING LIST data for 1 picture
if( pcSlice->getSPS()->getScalingListFlag() && ( m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ ) )
{
ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
APS* aps = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
bool writeAPS = aps && apsMap->getChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
if( writeAPS )
{
#if JVET_R0433
aps->chromaPresentFlag = pcSlice->getSPS()->getChromaFormatIdc() != CHROMA_400;
#endif
actualTotalBits += xWriteAPS( accessUnit, aps, m_pcEncLib->getLayerId(), true );
apsMap->clearChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
CHECK( aps != picHeader->getScalingListAPS(), "Wrong SCALING LIST APS pointer in compressGOP" );
}
}
if (pcSlice->getSPS()->getALFEnabledFlag() && (pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y) || pcSlice->getTileGroupCcAlfCbEnabledFlag() || pcSlice->getTileGroupCcAlfCrEnabledFlag()))
for (int apsId = 0; apsId < ALF_CTB_MAX_NUM_APS; apsId++)
{
ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
APS* aps = apsMap->getPS((apsId << NUM_APS_TYPE_LEN) + ALF_APS);
bool writeAPS = aps && apsMap->getChangedFlag((apsId << NUM_APS_TYPE_LEN) + ALF_APS);
if (!aps && pcSlice->getAlfAPSs() && pcSlice->getAlfAPSs()[apsId])
{
writeAPS = true;
aps = pcSlice->getAlfAPSs()[apsId]; // use asp from slice header
*apsMap->allocatePS((apsId << NUM_APS_TYPE_LEN) + ALF_APS) = *aps; //allocate and cpy
m_pcALF->setApsIdStart( apsId );
}
else if (pcSlice->getTileGroupCcAlfCbEnabledFlag() && !aps && apsId == pcSlice->getTileGroupCcAlfCbApsId())
{
writeAPS = true;
aps = apsMap->getPS((pcSlice->getTileGroupCcAlfCbApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
}
else if (pcSlice->getTileGroupCcAlfCrEnabledFlag() && !aps && apsId == pcSlice->getTileGroupCcAlfCrApsId())
{
writeAPS = true;
aps = apsMap->getPS((pcSlice->getTileGroupCcAlfCrApsId() << NUM_APS_TYPE_LEN) + ALF_APS);
}
#if JVET_R0433
aps->chromaPresentFlag = pcSlice->getSPS()->getChromaFormatIdc() != CHROMA_400;
#endif
actualTotalBits += xWriteAPS( accessUnit, aps, m_pcEncLib->getLayerId(), true );
apsMap->clearChangedFlag((apsId << NUM_APS_TYPE_LEN) + ALF_APS);
CHECK(aps != pcSlice->getAlfAPSs()[apsId] && apsId != pcSlice->getTileGroupCcAlfCbApsId() && apsId != pcSlice->getTileGroupCcAlfCrApsId(), "Wrong APS pointer in compressGOP");
}
}
}

Karsten Suehring
committed
// reset presence of BP SEI indication
m_bufferingPeriodSEIPresentInAU = false;
// create prefix SEI associated with a picture
xCreatePerPictureSEIMessages(iGOPid, leadingSeiMessages, nestedSeiMessages, pcSlice);
// pcSlice is currently slice 0.
std::size_t binCountsInNalUnits = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
std::size_t numBytesInVclNalUnits = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
#if JVET_Q0406_CABAC_ZERO
std::size_t sumZeroWords = 0; // sum of cabac_zero_word inserted per sub-picture
std::vector<EncBitstreamParams> subPicStats (pcPic->cs->pps->getNumSubPics());
#endif

Karsten Suehring
committed
for(uint32_t sliceSegmentIdxCount = 0; sliceSegmentIdxCount < pcPic->cs->pps->getNumSlicesInPic(); sliceSegmentIdxCount++ )

Karsten Suehring
committed
{
pcSlice = pcPic->slices[sliceSegmentIdxCount];
if(sliceSegmentIdxCount > 0 && pcSlice->getSliceType()!= I_SLICE)
{
pcSlice->checkColRefIdx(sliceSegmentIdxCount, pcPic);
}
m_pcSliceEncoder->setSliceSegmentIdx(sliceSegmentIdxCount);
pcSlice->setRPL0(pcPic->slices[0]->getRPL0());
pcSlice->setRPL1(pcPic->slices[0]->getRPL1());
pcSlice->setRPL0idx(pcPic->slices[0]->getRPL0idx());
pcSlice->setRPL1idx(pcPic->slices[0]->getRPL1idx());

Karsten Suehring
committed
picHeader->setNoOutputBeforeRecoveryFlag( false );
if (pcSlice->isIRAP())
{
if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
{
picHeader->setNoOutputBeforeRecoveryFlag( true );
}
//the inference for NoOutputPriorPicsFlag
// KJS: This cannot happen at the encoder
if( !m_bFirst && ( pcSlice->isIRAP() || pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_GDR ) && picHeader->getNoOutputBeforeRecoveryFlag() )
{
if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_GDR)
{
#if JVET_S0193_NO_OUTPUT_PRIOR_PIC
pcSlice->setNoOutputOfPriorPicsFlag(true);
#else
}
}
}
// code picture header before first slice
if(sliceSegmentIdxCount == 0)
{
// code RPL in picture header or slice headers
if( !m_pcCfg->getSliceLevelRpl() && (!pcSlice->getIdrPicFlag() || pcSlice->getSPS()->getIDRRefParamListPresent()) )
{
picHeader->setRPL0idx(pcSlice->getRPL0idx());
picHeader->setRPL1idx(pcSlice->getRPL1idx());
picHeader->setRPL0(pcSlice->getRPL0());
picHeader->setRPL1(pcSlice->getRPL1());
*picHeader->getLocalRPL0() = *pcSlice->getLocalRPL0();
*picHeader->getLocalRPL1() = *pcSlice->getLocalRPL1();
}
// code DBLK in picture header or slice headers
if( !m_pcCfg->getSliceLevelDblk() )
{
picHeader->setDeblockingFilterOverrideFlag ( pcSlice->getDeblockingFilterOverrideFlag() );
picHeader->setDeblockingFilterDisable ( pcSlice->getDeblockingFilterDisable() );
picHeader->setDeblockingFilterBetaOffsetDiv2 ( pcSlice->getDeblockingFilterBetaOffsetDiv2() );
picHeader->setDeblockingFilterTcOffsetDiv2 ( pcSlice->getDeblockingFilterTcOffsetDiv2() );
picHeader->setDeblockingFilterCbBetaOffsetDiv2( pcSlice->getDeblockingFilterCbBetaOffsetDiv2() );
picHeader->setDeblockingFilterCbTcOffsetDiv2 ( pcSlice->getDeblockingFilterCbTcOffsetDiv2() );
picHeader->setDeblockingFilterCrBetaOffsetDiv2( pcSlice->getDeblockingFilterCrBetaOffsetDiv2() );
picHeader->setDeblockingFilterCrTcOffsetDiv2 ( pcSlice->getDeblockingFilterCrTcOffsetDiv2() );
if (!m_pcCfg->getSliceLevelDeltaQp())
{
picHeader->setQpDelta(pcSlice->getSliceQp() - (pcSlice->getPPS()->getPicInitQPMinus26() + 26));
}
// code SAO parameters in picture header or slice headers
if( !m_pcCfg->getSliceLevelSao() )
{
picHeader->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_LUMA ));
picHeader->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA));
#if JVET_W0066_CCSAO
picHeader->setCcSaoEnabledFlag(COMPONENT_Y, pcSlice->getCcSaoEnabledFlag(COMPONENT_Y));
picHeader->setCcSaoEnabledFlag(COMPONENT_Cb, pcSlice->getCcSaoEnabledFlag(COMPONENT_Cb));
picHeader->setCcSaoEnabledFlag(COMPONENT_Cr, pcSlice->getCcSaoEnabledFlag(COMPONENT_Cr));
#endif
// code ALF parameters in picture header or slice headers
if( !m_pcCfg->getSliceLevelAlf() )
{
picHeader->setAlfEnabledFlag(COMPONENT_Y, pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y ) );
picHeader->setAlfEnabledFlag(COMPONENT_Cb, pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cb) );
picHeader->setAlfEnabledFlag(COMPONENT_Cr, pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cr) );
#if ALF_IMPROVEMENT
picHeader->setAlfFixedFilterSetIdx(pcSlice->getTileGroupAlfFixedFilterSetIdx());
#endif
picHeader->setNumAlfAps(pcSlice->getTileGroupNumAps());
picHeader->setAlfAPSs(pcSlice->getTileGroupApsIdLuma());
picHeader->setAlfApsIdChroma(pcSlice->getTileGroupApsIdChroma());
picHeader->setCcAlfEnabledFlag(COMPONENT_Cb, pcSlice->getTileGroupCcAlfCbEnabledFlag());
picHeader->setCcAlfEnabledFlag(COMPONENT_Cr, pcSlice->getTileGroupCcAlfCrEnabledFlag());
picHeader->setCcAlfCbApsId(pcSlice->getTileGroupCcAlfCbApsId());
picHeader->setCcAlfCrApsId(pcSlice->getTileGroupCcAlfCrApsId());
// code WP parameters in picture header or slice headers
if (!m_pcCfg->getSliceLevelWp())
{
picHeader->setWpScaling(pcSlice->getWpScalingAll());
picHeader->setNumL0Weights(pcSlice->getNumRefIdx(REF_PIC_LIST_0));
picHeader->setNumL0Weights(pcSlice->getNumRefIdx(REF_PIC_LIST_1));
}
pcPic->cs->picHeader->setPic(pcPic);
pcPic->cs->picHeader->setValid();
if (pcPic->cs->pps->getNumSlicesInPic() > 1 || !m_pcCfg->getEnablePictureHeaderInSliceHeader())
pcSlice->setPictureHeaderInSliceHeader(false);
actualTotalBits += xWritePicHeader(accessUnit, pcPic->cs->picHeader);
}
Jonatan Samuelsson-Allendes
committed
{
pcSlice->setPictureHeaderInSliceHeader(true);
}
if (pcSlice->getSPS()->getProfileTierLevel()->getConstraintInfo()->getPicHeaderInSliceHeaderConstraintFlag())
{
CHECK(pcSlice->getPictureHeaderInSliceHeader() == false, "PH shall be present in SH, when pic_header_in_slice_header_constraint_flag is equal to 1");
}
}
pcSlice->setPicHeader( pcPic->cs->picHeader );
pcSlice->setNalUnitLayerId( m_pcEncLib->getLayerId() );

Karsten Suehring
committed
for ( uint32_t ui = 0 ; ui < numSubstreams; ui++ )
{
substreamsOut[ui].clear();
}
/* start slice NALunit */
OutputNALUnit nalu( pcSlice->getNalUnitType(), m_pcEncLib->getLayerId(), pcSlice->getTLayer() );

Karsten Suehring
committed
m_HLSWriter->setBitstream( &nalu.m_Bitstream );
tmpBitsBeforeWriting = m_HLSWriter->getNumberOfWrittenBits();
pcSlice->m_ccAlfFilterParam = m_pcALF->getCcAlfFilterParam();
pcSlice->m_ccAlfFilterControl[0] = m_pcALF->getCcAlfControlIdc(COMPONENT_Cb);
pcSlice->m_ccAlfFilterControl[1] = m_pcALF->getCcAlfControlIdc(COMPONENT_Cr);
#if EMBEDDED_APS
m_HLSWriter->codeSliceHeader( m_aps, pcSlice );
#else

Karsten Suehring
committed
m_HLSWriter->codeSliceHeader( pcSlice );

Karsten Suehring
committed
actualHeadBits += ( m_HLSWriter->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
pcSlice->setFinalized(true);
pcSlice->resetNumberOfSubstream( );
pcSlice->setNumSubstream( pcSlice->getSPS(), pcSlice->getPPS() );

Karsten Suehring
committed
pcSlice->clearSubstreamSizes( );
#if JVET_Q0406_CABAC_ZERO
const int subpicIdx = pcPic->cs->pps->getSubPicIdxFromSubPicId(pcSlice->getSliceSubPicId());
#endif

Karsten Suehring
committed
{
uint32_t numBinsCoded = 0;
m_pcSliceEncoder->encodeSlice(pcPic, &(substreamsOut[0]), numBinsCoded);
binCountsInNalUnits+=numBinsCoded;
#if JVET_Q0406_CABAC_ZERO
subPicStats[subpicIdx].numBinsWritten += numBinsCoded;
#endif

Karsten Suehring
committed
}
{
// Construct the final bitstream by concatenating substreams.
// The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
// Complete the slice header info.
m_HLSWriter->setBitstream( &nalu.m_Bitstream );
m_HLSWriter->codeTilesWPPEntryPoint( pcSlice );
// Append substreams...
OutputBitstream *pcOut = pcBitstreamRedirect;
const int numSubstreamsToCode = pcSlice->getNumberOfSubstream() + 1;

Karsten Suehring
committed
for ( uint32_t ui = 0 ; ui < numSubstreamsToCode; ui++ )
{
pcOut->addSubstream(&(substreamsOut[ui]));

Karsten Suehring
committed
}
}
// If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
// If current NALU is the last NALU of slice and a NALU was buffered, then (a) Write current NALU (b) Update an write buffered NALU at approproate location in NALU list.
bool bNALUAlignedWrittenToList = false; // used to ensure current NALU is not written more than once to the NALU list.
xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
accessUnit.push_back(new NALUnitEBSP(nalu));
actualTotalBits += uint32_t(accessUnit.back()->m_nalUnitData.str().size()) * 8;
numBytesInVclNalUnits += (std::size_t)(accessUnit.back()->m_nalUnitData.str().size());
#if JVET_Q0406_CABAC_ZERO
subPicStats[subpicIdx].numBytesInVclNalUnits += (std::size_t)(accessUnit.back()->m_nalUnitData.str().size());
#endif

Karsten Suehring
committed
bNALUAlignedWrittenToList = true;
if (!bNALUAlignedWrittenToList)
{
nalu.m_Bitstream.writeAlignZero();
accessUnit.push_back(new NALUnitEBSP(nalu));
}
if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
((pcSlice->getSPS()->getGeneralHrdParameters()->getGeneralNalHrdParametersPresentFlag())
|| (pcSlice->getSPS()->getGeneralHrdParameters()->getGeneralVclHrdParametersPresentFlag())) &&
(pcSlice->getSPS()->getGeneralHrdParameters()->getGeneralDecodingUnitHrdParamsPresentFlag()))

Karsten Suehring
committed
{
uint32_t numNalus = 0;

Karsten Suehring
committed
uint32_t numRBSPBytes = 0;
for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
{
numRBSPBytes += uint32_t((*it)->m_nalUnitData.str().size());
numNalus ++;
}
duData.push_back(DUData());
duData.back().accumBitsDU = ( numRBSPBytes << 3 );
duData.back().accumNalsDU = numNalus;
}
#if JVET_Q0406_CABAC_ZERO
if (pcSlice->isLastSliceInSubpic())
{
// Check picture level encoding constraints/requirements
ProfileLevelTierFeatures profileLevelTierFeatures;
profileLevelTierFeatures.extractPTLInformation(*(pcSlice->getSPS()));
sumZeroWords += cabac_zero_word_padding(pcSlice, pcPic, subPicStats[subpicIdx].numBinsWritten, subPicStats[subpicIdx].numBytesInVclNalUnits, 0,
accessUnit.back()->m_nalUnitData, m_pcCfg->getCabacZeroWordPaddingEnabled(), profileLevelTierFeatures);
}
#endif

Karsten Suehring
committed
} // end iteration over slices
{
// Check picture level encoding constraints/requirements
ProfileLevelTierFeatures profileLevelTierFeatures;
profileLevelTierFeatures.extractPTLInformation(*(pcSlice->getSPS()));
validateMinCrRequirements(profileLevelTierFeatures, numBytesInVclNalUnits, pcPic, m_pcCfg);
// cabac_zero_words processing
#if JVET_Q0406_CABAC_ZERO
cabac_zero_word_padding(pcSlice, pcPic, binCountsInNalUnits, numBytesInVclNalUnits, sumZeroWords, accessUnit.back()->m_nalUnitData, m_pcCfg->getCabacZeroWordPaddingEnabled(), profileLevelTierFeatures);
#else
cabac_zero_word_padding(pcSlice, pcPic, binCountsInNalUnits, numBytesInVclNalUnits, accessUnit.back()->m_nalUnitData, m_pcCfg->getCabacZeroWordPaddingEnabled(), profileLevelTierFeatures);
}

Karsten Suehring
committed
//-- For time output for each slice
auto elapsed = std::chrono::steady_clock::now() - beforeTime;
auto encTime = std::chrono::duration_cast<std::chrono::seconds>( elapsed ).count();
std::string digestStr;
if (m_pcCfg->getDecodedPictureHashSEIType()!=HASHTYPE_NONE)
{
SEIDecodedPictureHash *decodedPictureHashSei = new SEIDecodedPictureHash();
PelUnitBuf recoBuf = pcPic->cs->getRecoBuf();
m_seiEncoder.initDecodedPictureHashSEI(decodedPictureHashSei, recoBuf, digestStr, pcSlice->getSPS()->getBitDepths());
trailingSeiMessages.push_back(decodedPictureHashSei);
}

Karsten Suehring
committed
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
#if JVET_R0294_SUBPIC_HASH
// create per-subpicture decoded picture hash SEI messages, if more than one subpicture is enabled
const PPS* pps = pcPic->cs->pps;
const int numSubpics = pps->getNumSubPics();
std::string subPicDigest;
if (numSubpics > 1 && m_pcCfg->getSubpicDecodedPictureHashType() != HASHTYPE_NONE )
{
for (int subPicIdx = 0; subPicIdx < numSubpics; subPicIdx++)
{
const SubPic& subpic = pps->getSubPic(subPicIdx);
const UnitArea area = UnitArea(pcSlice->getSPS()->getChromaFormatIdc(), Area(subpic.getSubPicLeft(), subpic.getSubPicTop(), subpic.getSubPicWidthInLumaSample(), subpic.getSubPicHeightInLumaSample()));
PelUnitBuf recoBuf = pcPic->cs->getRecoBuf(area);
SEIDecodedPictureHash *decodedPictureHashSEI = new SEIDecodedPictureHash();
m_seiEncoder.initDecodedPictureHashSEI(decodedPictureHashSEI, recoBuf, subPicDigest, pcSlice->getSPS()->getBitDepths());
SEIMessages nestedSEI;
nestedSEI.push_back(decodedPictureHashSEI);
const std::vector<uint16_t> subPicIds = { (uint16_t)subpic.getSubPicID() };
std::vector<int> targetOLS;
std::vector<int> targetLayers = {pcPic->layerId};
xCreateScalableNestingSEI(trailingSeiMessages, nestedSEI, targetOLS, targetLayers, subPicIds);
}
}
#endif

Karsten Suehring
committed
m_pcCfg->setEncodedFlag(iGOPid, true);
double PSNR_Y;
xCalculateAddPSNRs(isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, encTime, snr_conversion, printFrameMSE, &PSNR_Y, isEncodeLtRef );

Karsten Suehring
committed
xWriteTrailingSEIMessages(trailingSeiMessages, accessUnit, pcSlice->getTLayer());

Karsten Suehring
committed
printHash(m_pcCfg->getDecodedPictureHashSEIType(), digestStr);
if ( m_pcCfg->getUseRateCtrl() )
{
double avgQP = m_pcRateCtrl->getRCPic()->calAverageQP();
double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
if ( avgLambda < 0.0 )
{
avgLambda = lambda;
}
m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->isIRAP());

Karsten Suehring
committed
m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );

Karsten Suehring
committed
{
m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
}
else // for intra picture, the estimated bits are used to update the current status in the GOP
{
m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
}
#if U0132_TARGET_BITS_SATURATION
if (m_pcRateCtrl->getCpbSaturationEnabled())
{
m_pcRateCtrl->updateCpbState(actualTotalBits);
msg( NOTICE, " [CPB %6d bits]", m_pcRateCtrl->getCpbState() );
}
#endif
}
xCreateFrameFieldInfoSEI( leadingSeiMessages, pcSlice, isField );

Karsten Suehring
committed
xCreatePictureTimingSEI( m_pcCfg->getEfficientFieldIRAPEnabled() ? effFieldIRAPMap.GetIRAPGOPid() : 0, leadingSeiMessages, nestedSeiMessages, duInfoSeiMessages, pcSlice, isField, duData );
if (m_pcCfg->getScalableNestingSEIEnabled())

Karsten Suehring
committed
{
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
const SPS* sps = pcSlice->getSPS();
const PPS* pps = pcSlice->getPPS();
std::vector<uint16_t> subpicIDs;
if (sps->getSubPicInfoPresentFlag())
{
if(sps->getSubPicIdMappingExplicitlySignalledFlag())
{
if(sps->getSubPicIdMappingInSpsFlag())
{
subpicIDs = sps->getSubPicIds();
}
else
{
subpicIDs = pps->getSubPicIds();
}
}
else
{
const int numSubPics = sps->getNumSubPics();
subpicIDs.resize(numSubPics);
for (int i = 0 ; i < numSubPics; i++)
{
subpicIDs[i] = (uint16_t) i;
}
}
}

Karsten Suehring
committed
#if JVET_R0294_SUBPIC_HASH
// Note (KJS): Using targetOLS = 0, 1 is as random as encapsulating the same SEIs in scalable nesting.
// This can just be seen as example regarding how to write scalable nesting, not what to write.
std::vector<int> targetOLS = {0, 1};
std::vector<int> targetLayers;
xCreateScalableNestingSEI(leadingSeiMessages, nestedSeiMessages, targetOLS, targetLayers, subpicIDs);
#else
xCreateScalableNestingSEI(leadingSeiMessages, nestedSeiMessages, subpicIDs);

Karsten Suehring
committed
#endif

Karsten Suehring
committed
}

Karsten Suehring
committed
xWriteLeadingSEIMessages( leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData );
xWriteDuSEIMessages( duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), duData );

Karsten Suehring
committed
m_AUWriterIf->outputAU( accessUnit );
msg( NOTICE, "\n" );
fflush( stdout );
}
DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 0 ) ) );
pcPic->reconstructed = true;
m_bFirst = false;
m_iNumPicCoded++;
if (!(m_pcCfg->getUseCompositeRef() && isEncodeLtRef))
{
for( int i = pcSlice->getTLayer() ; i < pcSlice->getSPS()->getMaxTLayers() ; i ++ )
{
m_totalCoded[i]++;
}
}

Karsten Suehring
committed
/* logging: insert a newline at end of picture period */
if (m_pcCfg->getEfficientFieldIRAPEnabled())
{
iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
}
pcPic->destroyTempBuffers();
pcPic->cs->destroyCoeffs();
pcPic->cs->releaseIntermediateData();
} // iGOPid-loop
delete pcBitstreamRedirect;
CHECK( m_iNumPicCoded > 1, "Unspecified error" );

Karsten Suehring
committed
}
void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const bool printMSEBasedSNR, const bool printSequenceMSE, const bool printHexPsnr, const bool printRprPSNR, const BitDepths &bitDepths )

Karsten Suehring
committed
{
#if ENABLE_QPA
const bool useWPSNR = m_pcEncLib->getUseWPSNR();
#endif
#if WCG_WPSNR
const bool useLumaWPSNR = m_pcEncLib->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcCfg->getLmcs() && m_pcCfg->getReshapeSignalType() == RESHAPE_SIGNAL_PQ);

Karsten Suehring
committed
#endif
if( m_pcCfg->getDecodeBitstream(0).empty() && m_pcCfg->getDecodeBitstream(1).empty() && !m_pcCfg->useFastForwardToPOC() )
{
CHECK( !( uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic() ), "Unspecified error" );
}
//--CFG_KDY
const int rateMultiplier=(isField?2:1);
m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier / (double)m_pcCfg->getTemporalSubsampleRatio());
m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier / (double)m_pcCfg->getTemporalSubsampleRatio());
m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier / (double)m_pcCfg->getTemporalSubsampleRatio());
m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier / (double)m_pcCfg->getTemporalSubsampleRatio());
#if WCG_WPSNR
if (useLumaWPSNR)
{
m_gcAnalyzeWPSNR.setFrmRate(m_pcCfg->getFrameRate()*rateMultiplier / (double)m_pcCfg->getTemporalSubsampleRatio());
}
#endif

Karsten Suehring
committed
const ChromaFormat chFmt = m_pcCfg->getChromaFormatIdc();
//-- all
msg( INFO, "\n" );
msg( DETAILS,"\nSUMMARY --------------------------------------------------------\n" );
Dominik Mehlem
committed
#if JVET_O0756_CALCULATE_HDRMETRICS
const bool calculateHdrMetrics = m_pcEncLib->getCalcluateHdrMetrics();
#endif

Karsten Suehring
committed
#if ENABLE_QPA
Vadim Seregin
committed
m_gcAnalyzeAll.printOut( 'a', chFmt, printMSEBasedSNR, printSequenceMSE, printHexPsnr, printRprPSNR, bitDepths, useWPSNR
Dominik Mehlem
committed
#if JVET_O0756_CALCULATE_HDRMETRICS
, calculateHdrMetrics
#endif
);

Karsten Suehring
committed
#else
Dominik Mehlem
committed
m_gcAnalyzeAll.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, printHexPsnr, bitDepths
#if JVET_O0756_CALCULATE_HDRMETRICS
, calculateHdrMetrics
#endif
);

Karsten Suehring
committed
#endif
msg( DETAILS, "\n\nI Slices--------------------------------------------------------\n" );
m_gcAnalyzeI.printOut( 'i', chFmt, printMSEBasedSNR, printSequenceMSE, printHexPsnr, printRprPSNR, bitDepths );
msg( DETAILS, "\n\nP Slices--------------------------------------------------------\n" );
m_gcAnalyzeP.printOut( 'p', chFmt, printMSEBasedSNR, printSequenceMSE, printHexPsnr, printRprPSNR, bitDepths );
msg( DETAILS, "\n\nB Slices--------------------------------------------------------\n" );
m_gcAnalyzeB.printOut( 'b', chFmt, printMSEBasedSNR, printSequenceMSE, printHexPsnr, printRprPSNR, bitDepths );

Karsten Suehring
committed
#if WCG_WPSNR
if (useLumaWPSNR)
{
msg(DETAILS, "\nWPSNR SUMMARY --------------------------------------------------------\n");
m_gcAnalyzeWPSNR.printOut( 'w', chFmt, printMSEBasedSNR, printSequenceMSE, printHexPsnr, printRprPSNR, bitDepths, useLumaWPSNR );

Karsten Suehring
committed
}
#endif
if (!m_pcCfg->getSummaryOutFilename().empty())
{
m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE, printHexPsnr, bitDepths, m_pcCfg->getSummaryOutFilename());

Karsten Suehring
committed
}
if (!m_pcCfg->getSummaryPicFilenameBase().empty())
{
m_gcAnalyzeI.printSummary(chFmt, printSequenceMSE, printHexPsnr, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"I.txt");
m_gcAnalyzeP.printSummary(chFmt, printSequenceMSE, printHexPsnr, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"P.txt");
m_gcAnalyzeB.printSummary(chFmt, printSequenceMSE, printHexPsnr, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"B.txt");

Karsten Suehring
committed
}
#if WCG_WPSNR
if (!m_pcCfg->getSummaryOutFilename().empty() && useLumaWPSNR)
{
m_gcAnalyzeWPSNR.printSummary(chFmt, printSequenceMSE, printHexPsnr, bitDepths, m_pcCfg->getSummaryOutFilename());

Karsten Suehring
committed
}
#endif
if(isField)
{
//-- interlaced summary
m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate() / (double)m_pcCfg->getTemporalSubsampleRatio());
m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits());
// prior to the above statement, the interlace analyser does not contain the correct total number of bits.