Newer
Older
for (int colRefPicListIdx = 0; colRefPicListIdx < (pColSlice->isInterB() ? 2 : 1); colRefPicListIdx++)
{
for (int colRefIdx = 0; colRefIdx < pColSlice->getNumRefIdx(RefPicList(colRefPicListIdx)); colRefIdx++)
{
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
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
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
#if JVET_AI0183_MVP_EXTENSION
const bool bIsColRefLongTerm = pColSlice->getIsUsedAsLongTerm(RefPicList(colRefPicListIdx), colRefIdx);
const int colRefPOC = pColSlice->getRefPOC(RefPicList(colRefPicListIdx), colRefIdx);
for (int curRefPicListIdx = 0; curRefPicListIdx < (pcSlice->isInterB() ? 2 : 1); curRefPicListIdx++)
{
double bestDistScale = MAX_DOUBLE;
int targetRefIdx = -1;
for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx)); curRefIdx++)
{
const int currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
const bool bIsCurrRefLongTerm = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
if (bIsCurrRefLongTerm != bIsColRefLongTerm)
{
continue;
}
if (bIsCurrRefLongTerm)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
break;
}
else if (colPOC - colRefPOC == currPOC - currRefPOC)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
break;
}
else
{
if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)) < bestDistScale)
{
bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
targetRefIdx = curRefIdx;
}
}
} // curRefIdx
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx, colFrameIdx);
#else
pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx);
#endif
if (pcSlice->getCheckLDC() == true)
{
continue;
}
int targetRefIdx1st = targetRefIdx;
double bestOverScale = 0;
double scale = 0;
int curPOCMax, curPOCMin;
int colPOCMax, colPOCMin;
int bestTargetRefIdx = -1;
bestDistScale = MAX_DOUBLE;
targetRefIdx = -1;
for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx)); curRefIdx++)
{
if (curRefIdx == targetRefIdx1st)
{
continue;
}
const int currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
const bool bIsCurrRefLongTerm =
pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
if (bIsCurrRefLongTerm != bIsColRefLongTerm)
{
continue;
}
if (bIsCurrRefLongTerm)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
bestTargetRefIdx = -1;
break;
}
else if (colRefPOC == currRefPOC)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
bestTargetRefIdx = -1;
break;
}
else
{
curPOCMax = std::max(currPOC, currRefPOC);
curPOCMin = std::min(currPOC, currRefPOC);
colPOCMax = std::max(colPOC, colRefPOC);
colPOCMin = std::min(colPOC, colRefPOC);
scale = std::max(0, std::min(curPOCMax, colPOCMax) - std::max(curPOCMin, colPOCMin));
scale = scale * scale / (abs(currPOC - currRefPOC) * abs(colPOC - colRefPOC));
if (scale > bestOverScale)
{
bestOverScale = scale;
bestTargetRefIdx = curRefIdx;
}
if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)) < bestDistScale)
{
bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
targetRefIdx = curRefIdx;
}
}
} // curRefIdx
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
if (bestTargetRefIdx != -1)
{
targetRefIdx = bestTargetRefIdx;
}
if (targetRefIdx == -1)
{
targetRefIdx = 0;
}
pcSlice->setImRefIdx2nd(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx,
targetRefIdx, colFrameIdx );
#else
pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx,
targetRefIdx);
#endif
bestOverScale = 0;
scale = 0;
bestTargetRefIdx = -1;
bestDistScale = MAX_DOUBLE;
targetRefIdx = -1;
for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx));
curRefIdx++)
{
const int currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
const bool bIsCurrRefLongTerm =
pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
if (bIsCurrRefLongTerm != bIsColRefLongTerm)
{
continue;
}
if (bIsCurrRefLongTerm)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
bestTargetRefIdx = -1;
break;
}
else if (colRefPOC == currRefPOC)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
bestTargetRefIdx = -1;
break;
}
else
{
curPOCMax = std::max(currPOC, currRefPOC);
curPOCMin = std::min(currPOC, currRefPOC);
colPOCMax = std::max(colPOC, colRefPOC);
colPOCMin = std::min(colPOC, colRefPOC);
scale = std::max(0, std::min(curPOCMax, colPOCMax) - std::max(curPOCMin, colPOCMin));
scale = scale * scale / (abs(currPOC - currRefPOC) * abs(colPOC - colRefPOC));
if (scale > bestOverScale)
{
bestOverScale = scale;
bestTargetRefIdx = curRefIdx;
}
if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0))
< bestDistScale)
{
bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
targetRefIdx = curRefIdx;
}
}
} // curRefIdx
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
if (bestTargetRefIdx != -1)
{
targetRefIdx = bestTargetRefIdx;
}
if (targetRefIdx == -1)
{
targetRefIdx = 0;
}
pcSlice->setImRefIdx3rd(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx),
colRefIdx, targetRefIdx, colFrameIdx);
#else
pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx),
colRefIdx, targetRefIdx);
#endif
} // curRefPicListIdx
#else
const bool bIsColRefLongTerm = pColSlice->getIsUsedAsLongTerm(RefPicList(colRefPicListIdx), colRefIdx);
const int colRefPOC = pColSlice->getRefPOC(RefPicList(colRefPicListIdx), colRefIdx);
for (int curRefPicListIdx = 0; curRefPicListIdx < (pcSlice->isInterB() ? 2 : 1); curRefPicListIdx++)
{
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
int targetRefIdx = -1;
for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx)); curRefIdx++)
{
const int currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
const bool bIsCurrRefLongTerm = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
if (bIsCurrRefLongTerm != bIsColRefLongTerm)
{
continue;
}
if (bIsCurrRefLongTerm)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
break;
}
else if (colPOC - colRefPOC == currPOC - currRefPOC)
{
targetRefIdx = curRefIdx;
bestDistScale = 1;
break;
}
else
{
//printf("colRefPicListIdx:%d, curRefPicListIdx:%d, colRefIdx:%d, targetRefIdx:%d, curRefIdx:%d\n", colRefPicListIdx, curRefPicListIdx, colRefIdx, targetRefIdx, curRefIdx);
//printf("currPOC:%d, currRefPOC:%d, colPOC:%d, colRefPOC:%d\n", currPOC, currRefPOC, colPOC, colRefPOC);
//printf("bestDistScale:%.2f %.2f\n", bestDistScale, abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)));
if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)) < bestDistScale)
{
bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
targetRefIdx = curRefIdx;
}
}
} // curRefIdx
//printf("sliceIdx:%d, colRefPicListIdx:%d, curRefPicListIdx:%d, colRefIdx:%d, targetRefIdx:%d\n", sliceIdx, colRefPicListIdx, curRefPicListIdx, colRefIdx, targetRefIdx);
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx, colFrameIdx);
#else
pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx);
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
}
#endif
}
#if JVET_Y0128_NON_CTC
bool bDisableTMVP;
if (pcPic->cs->isGdrEnabled())
{
PicHeader *picHeader = new PicHeader;
*picHeader = *pcPic->cs->picHeader;
bDisableTMVP = pcSlice->scaleRefPicList(scaledRefPic, picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
}
else
{
bDisableTMVP = pcSlice->scaleRefPicList(scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
}
bool bDisableTMVP = pcSlice->scaleRefPicList( scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
if ( picHeader->getEnableTMVPFlag() && bDisableTMVP )
{
picHeader->setEnableTMVPFlag( 0 );
}
#else
#if JVET_Z0118_GDR
PicHeader *picHeader = new PicHeader;
*picHeader = *pcPic->cs->picHeader;
pcSlice->scaleRefPicList( scaledRefPic, picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
picHeader = pcPic->cs->picHeader;
#else
pcSlice->scaleRefPicList( scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
#endif

Karsten Suehring
committed
// set adaptive search range for non-intra-slices
if (m_pcCfg->getUseASR() && !pcSlice->isIntra())

Karsten Suehring
committed
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
{
m_pcSliceEncoder->setSearchRange(pcSlice);
}
bool bGPBcheck=false;
if ( pcSlice->getSliceType() == B_SLICE)
{
if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
{
bGPBcheck=true;
int i;
for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
{
if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) )
{
bGPBcheck=false;
break;
}
}
}
}
if(bGPBcheck)
{

Karsten Suehring
committed
}
else
{

Karsten Suehring
committed
}
if ( pcSlice->getSPS()->getUseSMVD() && pcSlice->getCheckLDC() == false
{
int currPOC = pcSlice->getPOC();
int forwardPOC = currPOC;
int ref = 0, refIdx0 = -1, refIdx1 = -1;
// search nearest forward POC in List 0
for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); ref++ )
{
int poc = pcSlice->getRefPic( REF_PIC_LIST_0, ref )->getPOC();
const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_0, ref)->longTerm;
if ( poc < currPOC && (poc > forwardPOC || refIdx0 == -1) && !isRefLongTerm )
{
forwardPOC = poc;
refIdx0 = ref;
}
}
// search nearest backward POC in List 1
for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); ref++ )
{
int poc = pcSlice->getRefPic( REF_PIC_LIST_1, ref )->getPOC();
const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_1, ref)->longTerm;
if ( poc > currPOC && (poc < backwardPOC || refIdx1 == -1) && !isRefLongTerm )
refIdx0 = -1;
refIdx1 = -1;
// search nearest backward POC in List 0
for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); ref++ )
{
int poc = pcSlice->getRefPic( REF_PIC_LIST_0, ref )->getPOC();
const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_0, ref)->longTerm;
if ( poc > currPOC && (poc < backwardPOC || refIdx0 == -1) && !isRefLongTerm )
refIdx0 = ref;
}
}
// search nearest forward POC in List 1
for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); ref++ )
{
int poc = pcSlice->getRefPic( REF_PIC_LIST_1, ref )->getPOC();
const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_1, ref)->longTerm;
if ( poc < currPOC && (poc > forwardPOC || refIdx1 == -1) && !isRefLongTerm )
{
forwardPOC = poc;
refIdx1 = ref;
}
}
}
{
pcSlice->setBiDirPred( true, refIdx0, refIdx1 );
}
else
{
pcSlice->setBiDirPred( false, -1, -1 );
}
}
else
{
pcSlice->setBiDirPred( false, -1, -1 );
}
#if JVET_Y0128_NON_CTC
pcSlice->checkBMAvailability(pcSlice);
pcSlice->checkAmvpMergeModeAvailability(pcSlice);
#endif
#if JVET_Z0054_BLK_REF_PIC_REORDER
if (pcSlice->getSPS()->getUseARL())
{
pcSlice->generateCombinedList();
pcSlice->generateRefPicPairList();
}
#endif
#if JVET_AF0159_AFFINE_SUBPU_BDOF_REFINEMENT
pcSlice->generateEqualPocDist();
#endif
#if JVET_AI0183_MVP_EXTENSION
pcSlice->generateIntersectingMv();
#endif

Karsten Suehring
committed
double lambda = 0.0;
int actualHeadBits = 0;
int actualTotalBits = 0;
int estimatedBits = 0;
int tmpBitsBeforeWriting = 0;

Karsten Suehring
committed
xPicInitRateControl(estimatedBits, iGOPid, lambda, pcPic, pcSlice);

Karsten Suehring
committed
uint32_t uiNumSliceSegments = 1;
{
pcSlice->setDefaultClpRng( *pcSlice->getSPS() );
}
// Allocate some coders, now the number of tiles are known.
const uint32_t numberOfCtusInFrame = pcPic->cs->pcv->sizeInCtus;
const int numSubstreamsColumns = pcSlice->getPPS()->getNumTileColumns();
const int numSubstreamRows = pcSlice->getSPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->cs->pcv->heightInCtus : (pcSlice->getPPS()->getNumTileRows());
const int numSubstreams = std::max<int> (numSubstreamRows * numSubstreamsColumns, (int) pcPic->cs->pps->getNumSlicesInPic());

Karsten Suehring
committed
std::vector<OutputBitstream> substreamsOut(numSubstreams);
#if ENABLE_QPA

Christian Helmrich
committed
pcPic->m_uEnerHpCtu.resize (numberOfCtusInFrame);
pcPic->m_iOffsetCtu.resize (numberOfCtusInFrame);
if (pcSlice->getPPS()->getUseDQP() && pcSlice->getCuQpDeltaSubdiv() > 0)

Christian Helmrich
committed
{
const PreCalcValues &pcv = *pcPic->cs->pcv;
const unsigned mtsLog2 = (unsigned)floorLog2(std::min (pcPic->cs->sps->getMaxTbSize(), pcv.maxCUWidth));

Christian Helmrich
committed
pcPic->m_subCtuQP.resize ((pcv.maxCUWidth >> mtsLog2) * (pcv.maxCUHeight >> mtsLog2));
}

Karsten Suehring
committed
#endif
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if (pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() || pcSlice->getPPS()->getUseChromaBIF())
// BIF happens in SAO code so this needs to be done
// even if SAO=0 if BIF=1.
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
{
pcPic->resizeSAO( numberOfCtusInFrame, 0 );
pcPic->resizeSAO( numberOfCtusInFrame, 1 );
}
// it is used for signalling during CTU mode decision, i.e. before ALF processing
if( pcSlice->getSPS()->getALFEnabledFlag() )

Karsten Suehring
committed
{
pcPic->resizeAlfCtuEnableFlag( numberOfCtusInFrame );
pcPic->resizeAlfCtuAlternative( numberOfCtusInFrame );
pcPic->resizeAlfCtbFilterIndex(numberOfCtusInFrame);

Karsten Suehring
committed
}
bool decPic = false;
bool encPic = false;
// test if we can skip the picture entirely or decode instead of encoding
trySkipOrDecodePicture( decPic, encPic, *m_pcCfg, pcPic, m_pcEncLib->getApsMap() );
#if JVET_AI0084_ALF_RESIDUALS_SCALING
if ( decPic && pcPic != nullptr && pcPic->cs->sps->getALFEnabledFlag() )
{
m_pcALF->restoreAlfScalePrev( pcPic->m_alfScalePrev );
}
#endif

Karsten Suehring
committed
pcPic->cs->slice = pcSlice; // please keep this
#if ENABLE_QPA
#if JVET_AI0136_ADAPTIVE_DUAL_TREE
if ( pcSlice->getPPS()->getSliceChromaQpFlag() && pcSlice->getPic()->cs->slice->isIntra() && !pcSlice->getPic()->cs->pcv->ISingleTree && !m_pcCfg->getUsePerceptQPA() && (m_pcCfg->getSliceChromaOffsetQpPeriodicity() == 0))
#else
if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree (*pcSlice->getPic()->cs) && !m_pcCfg->getUsePerceptQPA() && (m_pcCfg->getSliceChromaOffsetQpPeriodicity() == 0))
#endif
#else
if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree (*pcSlice->getPic()->cs))
#endif

Karsten Suehring
committed
{
#if JVET_AC0096
if (!(pcSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR || pcSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR2 || pcSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR3))
#endif
// overwrite chroma qp offset for dual tree
pcSlice->setSliceChromaQpDelta(COMPONENT_Cb, m_pcCfg->getChromaCbQpOffsetDualTree());
pcSlice->setSliceChromaQpDelta(COMPONENT_Cr, m_pcCfg->getChromaCrQpOffsetDualTree());
if (pcSlice->getSPS()->getJointCbCrEnabledFlag())
{
pcSlice->setSliceChromaQpDelta(JOINT_CbCr, m_pcCfg->getChromaCbCrQpOffsetDualTree());
}
m_pcSliceEncoder->setUpLambda(pcSlice, pcSlice->getLambdas()[0], pcSlice->getSliceQp());
#if JVET_AC0096

Karsten Suehring
committed
#if JVET_AG0145_ADAPTIVE_CLIPPING
if (m_pcCfg->getIntraPeriod() == -1)
{
if (pcPic->cs->slice->getSliceType() == I_SLICE)
{
pcSlice->setLumaPelMax((1 << pcPic->cs->sps->getBitDepth(toChannelType(COMPONENT_Y))) - 1);
pcSlice->setLumaPelMin(0);
}
}
#endif
if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
{
picHeader->setExplicitScalingListEnabledFlag( true );
pcSlice->setExplicitScalingListUsed( true );
int apsId = std::min<int>( 7, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) );
ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
APS* scalingListAPS = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
assert( scalingListAPS != NULL );
picHeader->setScalingListAPS( scalingListAPS );
}
pcPic->cs->picHeader->setPic(pcPic);
pcPic->cs->picHeader->setValid();
if(pcPic->cs->sps->getFpelMmvdEnabledFlag())
Jonatan Samuelsson-Allendes
committed
// cannot set ph_fpel_mmvd_enabled_flag at slice level - need new picture-level version of checkDisFracMmvd algorithm?
// m_pcSliceEncoder->checkDisFracMmvd( pcPic, 0, numberOfCtusInFrame );
bool useIntegerMVD = (pcPic->lwidth()*pcPic->lheight() > 1920 * 1080);
pcPic->cs->picHeader->setDisFracMMVD( useIntegerMVD );
}
if (pcSlice->getSPS()->getJointCbCrEnabledFlag())
{
m_pcSliceEncoder->setJointCbCrModes(*pcPic->cs, Position(0, 0), pcPic->cs->area.lumaSize());
}
if( encPic )
// now compress (trial encode) the various slice segments (slices, and dependent slices)
{
DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "poc", pocCurr ) ) );
const std::vector<uint16_t> sliceLosslessArray = *(m_pcCfg->getSliceLosslessArray());
bool mixedLossyLossless = m_pcCfg->getMixedLossyLossless();
if (m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
{
pcPic->fillSliceLossyLosslessArray(sliceLosslessArray, mixedLossyLossless);
}
for(uint32_t sliceIdx = 0; sliceIdx < pcPic->cs->pps->getNumSlicesInPic(); sliceIdx++ )
{
pcSlice->setSliceMap( pcPic->cs->pps->getSliceMap( sliceIdx ) );
Vadim Seregin
committed
if( pcPic->cs->pps->getRectSliceFlag() )
{
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;
#if JVET_AJ0158_SUBBLOCK_INTER_EXTENSION
clipMv2 = clipMvInSubpic2;
#endif
m_pcEncLib->getInterSearch()->setClipMvInSubPic(true);
}
else
{
clipMv = clipMvInPic;
#if JVET_AJ0158_SUBBLOCK_INTER_EXTENSION
clipMv2 = clipMvInPic2;
#endif
m_pcEncLib->getInterSearch()->setClipMvInSubPic(false);

Karsten Suehring
committed
m_pcSliceEncoder->precompressSlice( pcPic );
Thierry Dumas
committed
#if JVET_AJ0249_NEURAL_NETWORK_BASED
pcSlice->setPnnMode(m_pcCfg->getNnipMode());
#endif

Karsten Suehring
committed
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();
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
#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() )
{
Kenneth Andersson
committed
#if JVET_AB0082
ioBeforeInLoop.writeUpscaledPicture(*sps, *pcPic->cs->pps, pcPic->getRecoBuf(), outputColourSpaceConvert, packedYUVMode, m_pcCfg->getUpscaledOutput(), NUM_CHROMA_FORMAT, clipOutputVideoToRec709Range, m_pcCfg->getUpscaleFilerForDisplay());
#else
ioBeforeInLoop.writeUpscaledPicture( *sps, *pcPic->cs->pps, pcPic->getRecoBuf(), outputColourSpaceConvert, packedYUVMode, m_pcCfg->getUpscaledOutput(), NUM_CHROMA_FORMAT, clipOutputVideoToRec709Range );
Kenneth Andersson
committed
#endif
}
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
#if JVET_Z0118_GDR
pcPic->setCleanDirty(false);
#endif

Karsten Suehring
committed
CodingStructure& cs = *pcPic->cs;
pcSlice = pcPic->slices[0];
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
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() );
}
Nan Hu
committed
}
Nan Hu
committed
#if JVET_AA0095_ALF_WITH_SAMPLES_BEFORE_DBF
if (pcSlice->getSPS()->getALFEnabledFlag())
{
// create ALF object based on the picture size
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());
}
Nan Hu
committed
m_pcALF->copyDbData(cs);
Nan Hu
committed
#endif
#if JVET_AC0162_ALF_RESIDUAL_SAMPLES_INPUT
if (pcSlice->getSPS()->getALFEnabledFlag())
{
// create ALF object based on the picture size
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());
}
m_pcALF->copyResiData(cs);
}
#endif
#if JVET_AJ0188_CODING_INFO_CLASSIFICATION
m_pcALF->callCodingInfoBuf( cs ).fill( 0 );
#endif
#if JVET_W0066_CCSAO
|| pcSlice->getSPS()->getCCSAOEnabledFlag()
#endif
#if JVET_V0094_BILATERAL_FILTER
|| pcSlice->getPPS()->getUseBIF()
#endif
#if JVET_X0071_CHROMA_BILATERAL_FILTER
|| pcSlice->getPPS()->getUseChromaBIF()
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);
if ( saoSize.width != picWidth || saoSize.height != picHeight )
{
m_pcSAO->create(picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, log2SaoOffsetScaleLuma, log2SaoOffsetScaleChroma);
m_pcSAO->setReshaper(m_pcReshaper);
}
// create SAO encoder data based on the picture size
m_pcSAO->destroyEncData();
m_pcSAO->createEncData(m_pcCfg->getSaoCtuBoundary(), numCtuInFrame);
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);
}
}
}
#if JVET_AB0171_ASYMMETRIC_DB_FOR_GDR
if (m_pcCfg->getAsymmetricILF() && (pcPic->cs->picHeader->getInGdrInterval() || pcPic->cs->picHeader->getIsGdrRecoveryPocPic()))
{
m_pcLoopFilter->setAsymmetricDB(true);
}
else
{
m_pcLoopFilter->setAsymmetricDB(false);
}
#endif
#if JVET_AJ0188_CODING_INFO_CLASSIFICATION
PelUnitBuf codingInfoBuf = m_pcALF->callCodingInfoBuf( cs );
m_pcLoopFilter->loopFilterPic( cs, codingInfoBuf, true );
#else

Karsten Suehring
committed
m_pcLoopFilter->loopFilterPic( cs );

Karsten Suehring
committed
CS::setRefinedMotionField(cs);

Karsten Suehring
committed
#if JVET_AE0043_CCP_MERGE_TEMPORAL
if ((pcPic->temporalId == 0) || (pcPic->temporalId < pcSlice->getSPS()->getMaxTLayers() - 1))
{
CS::saveTemporalCcpModel(cs);
}
#endif
#if JVET_AG0058_EIP
if ((pcPic->temporalId == 0) || (pcPic->temporalId < pcSlice->getSPS()->getMaxTLayers() - 1))
{
CS::saveTemporalEipModel(cs);
}
#endif
#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()));

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 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( pcSlice->getSPS()->getSAOEnabledFlag()
#if JVET_W0066_CCSAO
|| pcSlice->getSPS()->getCCSAOEnabledFlag()
#endif
)
{
m_pcSAO->destroyEncData();
}
#if RPR_ENABLE && !JVET_AA0095_ALF_WITH_SAMPLES_BEFORE_DBF
// 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() );
}
}