Newer
Older
Vadim Seregin
committed
CHECK( subPicIdx == NOT_VALID, "Sub-picture was not found" );
pcSlice->setSliceSubPicId( pcPic->cs->pps->getSubPic( subPicIdx ).getSubPicID() );
}
if (pcPic->cs->sps->getUseLmcs())
{
pcSlice->setLmcsEnabledFlag(picHeader->getLmcsEnabledFlag());
if (pcSlice->getSliceType() == I_SLICE)
{
//reshape original signal
if( m_pcCfg->getGopBasedTemporalFilterEnabled() )
{
pcPic->getOrigBuf().copyFrom( pcPic->getFilteredOrigBuf() );
}
else
{
pcPic->getOrigBuf().copyFrom( pcPic->getTrueOrigBuf() );
}
if (pcSlice->getLmcsEnabledFlag())
{
pcPic->getOrigBuf(COMPONENT_Y).rspSignal(m_pcReshaper->getFwdLUT());
m_pcReshaper->setSrcReshaped(true);
m_pcReshaper->setRecReshaped(true);
}
else
{
m_pcReshaper->setSrcReshaped(false);
m_pcReshaper->setRecReshaped(false);
}
}
}
bool isLossless = false;
if (m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
{
isLossless = pcPic->losslessSlice(sliceIdx);
}
m_pcSliceEncoder->setLosslessSlice(pcPic, isLossless);
#if JVET_S0258_SUBPIC_CONSTRAINTS
if( pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic( REF_PIC_LIST_0, 0 )->subPictures.size() > 1 )
#else
if (pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic(REF_PIC_LIST_0, 0)->numSubpics > 1)
{
clipMv = clipMvInSubpic;
m_pcEncLib->getInterSearch()->setClipMvInSubPic(true);
}
else
{
clipMv = clipMvInPic;
m_pcEncLib->getInterSearch()->setClipMvInSubPic(false);

Karsten Suehring
committed
m_pcSliceEncoder->precompressSlice( pcPic );
m_pcSliceEncoder->compressSlice ( pcPic, false, false );
if(sliceIdx < pcPic->cs->pps->getNumSlicesInPic() - 1)

Karsten Suehring
committed
{
uint32_t independentSliceIdx = pcSlice->getIndependentSliceIdx();
pcPic->allocateNewSlice();
m_pcSliceEncoder->setSliceSegmentIdx (uiNumSliceSegments);
// prepare for next slice
pcSlice = pcPic->slices[uiNumSliceSegments];
CHECK(!(pcSlice->getPPS() != 0), "Unspecified error");
pcSlice->copySliceInfo(pcPic->slices[uiNumSliceSegments - 1]);
pcSlice->setSliceBits(0);
independentSliceIdx++;
pcSlice->setIndependentSliceIdx(independentSliceIdx);
uiNumSliceSegments++;
}
}
duData.clear();
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
#if DUMP_BEFORE_INLOOP
if( m_pcEncLib->getDumpBeforeInloop() )
{
static VideoIOYuv ioBeforeInLoop;
if( pcPic )
{
if( !ioBeforeInLoop.isOpen() )
{
std::string reconFileName = m_pcEncLib->m_reconFileName;
size_t pos = reconFileName.find_last_of( '.' );
if( pos != string::npos )
{
reconFileName.insert( pos, "beforeInloop" );
}
else
{
reconFileName.append( "beforeInloop" );
}
const BitDepths &bitDepths = pcPic->cs->sps->getBitDepths();
ioBeforeInLoop.open( reconFileName, true, bitDepths.recon, bitDepths.recon, bitDepths.recon );
}
const Window &conf = pcPic->getConformanceWindow();
const SPS* sps = pcPic->cs->sps;
ChromaFormat chromaFormatIDC = sps->getChromaFormatIdc();
InputColourSpaceConversion outputColourSpaceConvert = IPCOLOURSPACE_UNCHANGED;
bool packedYUVMode = false;
bool clipOutputVideoToRec709Range = false;
if( m_pcCfg->getUpscaledOutput() )
{
ioBeforeInLoop.writeUpscaledPicture( *sps, *pcPic->cs->pps, pcPic->getRecoBuf(), outputColourSpaceConvert, packedYUVMode, m_pcCfg->getUpscaledOutput(), NUM_CHROMA_FORMAT, clipOutputVideoToRec709Range );
}
else
{
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];
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
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()
#if JVET_V0094_BILATERAL_FILTER
|| pcSlice->getPPS()->getUseBIF()
#endif
#if JVET_X0071_CHROMA_BILATERAL_FILTER
|| pcSlice->getPPS()->getUseChromaBIF()
{
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
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() || pcSlice->getPPS()->getUseChromaBIF())
// We need to do this step if at least one of BIF or SAO are enabled.
if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF())
#endif
#else
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseChromaBIF())
if( pcSlice->getSPS()->getSAOEnabledFlag() )
#endif

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
#if JVET_X0071_CHROMA_BILATERAL_FILTER
ChromaBIFCabacEstImp chromaBifEst(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()
#endif
#if JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
//assign SAO slice header
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
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
}
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

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());
}
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
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
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
#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
{
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
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};