Newer
Older
Vadim Seregin
committed
{
Position firstCtu;
firstCtu.x = pcSlice->getFirstCtuRsAddrInSlice() % pcPic->cs->pps->getPicWidthInCtu();
firstCtu.y = pcSlice->getFirstCtuRsAddrInSlice() / pcPic->cs->pps->getPicWidthInCtu();
Vadim Seregin
committed
int subPicIdx = NOT_VALID;
for( int sp = 0; sp < pcPic->cs->pps->getNumSubPics(); sp++ )
Vadim Seregin
committed
if( pcPic->cs->pps->getSubPic( sp ).containsCtu( firstCtu ) )
Vadim Seregin
committed
break;
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();
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
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
#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];
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
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());
}
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
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
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
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
#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;
#if MSSIM_UNIFORM_METRICS_LOG
xCalculateAddPSNRs(isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, encTime, snr_conversion, printFrameMSE, printMSSSIM,&PSNR_Y, isEncodeLtRef );
#else
xCalculateAddPSNRs(isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, encTime, snr_conversion, printFrameMSE, &PSNR_Y, isEncodeLtRef );
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
{
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();