Newer
Older

Karsten Suehring
committed
pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
if (m_pcCfg->getEfficientFieldIRAPEnabled())
{
if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
|| pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) // IRAP picture

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

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

Karsten Suehring
committed
{
m_associatedIRAPType = pcSlice->getNalUnitType();
m_associatedIRAPPOC = pocCurr;
}
pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
}
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
#if JVET_N0494_DRAP
pcSlice->setEnableDRAPSEI(m_pcEncLib->getDependentRAPIndicationSEIEnabled());
if (m_pcEncLib->getDependentRAPIndicationSEIEnabled())
{
// Only mark the picture as DRAP if all of the following applies:
// 1) DRAP indication SEI messages are enabled
// 2) The current picture is not an intra picture
// 3) The current picture is in the DRAP period
// 4) The current picture is a trailing picture
pcSlice->setDRAP(m_pcEncLib->getDependentRAPIndicationSEIEnabled() && m_pcEncLib->getDrapPeriod() > 0 && !pcSlice->isIntra() &&
pocCurr % m_pcEncLib->getDrapPeriod() == 0 && pocCurr > pcSlice->getAssociatedIRAPPOC());
if (pcSlice->isDRAP())
{
int pocCycle = 1 << (pcSlice->getSPS()->getBitsForPOC());
int deltaPOC = pocCurr > pcSlice->getAssociatedIRAPPOC() ? pocCurr - pcSlice->getAssociatedIRAPPOC() : pocCurr - ( pcSlice->getAssociatedIRAPPOC() & (pocCycle -1) );
CHECK(deltaPOC > (pocCycle >> 1), "Use a greater value for POC wraparound to enable a POC distance between IRAP and DRAP of " << deltaPOC << ".");
m_iLatestDRAPPOC = pocCurr;
pcSlice->setTLayer(0); // Force DRAP picture to have temporal layer 0
}
pcSlice->setLatestDRAPPOC(m_iLatestDRAPPOC);
pcSlice->setUseLTforDRAP(false); // When set, sets the associated IRAP as long-term in RPL0 at slice level, unless the associated IRAP is already included in RPL0 or RPL1 defined in SPS
PicList::iterator iterPic = rcListPic.begin();
Picture *rpcPic;
while (iterPic != rcListPic.end())
{
rpcPic = *(iterPic++);
if ( pcSlice->isDRAP() && rpcPic->getPOC() != pocCurr )
{
rpcPic->precedingDRAP = true;
}
else if ( !pcSlice->isDRAP() && rpcPic->getPOC() == pocCurr )
{
rpcPic->precedingDRAP = false;
}
}
}
if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 ||
(m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) ))
#else
if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0)
{
pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1());
}
pcSlice->applyReferencePictureListBasedMarking(rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1());

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

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

Karsten Suehring
committed
{
bool isSTSA=true;
for(int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
{
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
int lTid = m_pcCfg->getRPLEntry(0, ii).m_temporalId;
if (lTid == pcSlice->getTLayer())
{
const ReferencePictureList* rpl0 = pcSlice->getSPS()->getRPLList0()->getReferencePictureList(ii);
for (int jj = 0; jj < pcSlice->getRPL0()->getNumberOfActivePictures(); jj++)
{
int tPoc = m_pcCfg->getRPLEntry(0, ii).m_POC + rpl0->getRefPicIdentifier(jj);
int kk = 0;
for (kk = 0; kk<m_pcCfg->getGOPSize(); kk++)
{
if (m_pcCfg->getRPLEntry(0, kk).m_POC == tPoc)
{
break;
}
}
int tTid = m_pcCfg->getRPLEntry(0, kk).m_temporalId;
if (tTid >= pcSlice->getTLayer())
{
isSTSA = false;
break;
}
}
const ReferencePictureList* rpl1 = pcSlice->getSPS()->getRPLList1()->getReferencePictureList(ii);
for (int jj = 0; jj < pcSlice->getRPL1()->getNumberOfActivePictures(); jj++)
{
int tPoc = m_pcCfg->getRPLEntry(1, ii).m_POC + rpl1->getRefPicIdentifier(jj);
int kk = 0;
for (kk = 0; kk<m_pcCfg->getGOPSize(); kk++)
{
if (m_pcCfg->getRPLEntry(1, kk).m_POC == tPoc)
{
break;
}
}
int tTid = m_pcCfg->getRPLEntry(1, kk).m_temporalId;
if (tTid >= pcSlice->getTLayer())
{
isSTSA = false;
break;
}
}
}

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

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

Karsten Suehring
committed
// Set reference list
#if JVET_O1164_RPR
#if JVET_O0299_APS_SCALINGLIST
pcSlice->scaleRefPicList( scaledRefPic, m_pcEncLib->getApss(), *pcSlice->getLmcsAPS(), *pcSlice->getscalingListAPS(), false );
#else
pcSlice->scaleRefPicList( scaledRefPic, m_pcEncLib->getApss(), *pcSlice->getLmcsAPS(), false );
#endif
#endif

Karsten Suehring
committed
#if JVET_O1164_PS
xPicInitHashME( pcPic, pcSlice->getPPS(), rcListPic );
#else

Karsten Suehring
committed
xPicInitHashME(pcPic, pcSlice->getSPS(), rcListPic);
#endif

Karsten Suehring
committed
if( m_pcCfg->getUseAMaxBT() )
{

Karsten Suehring
committed
{
int refLayer = pcSlice->getDepth();
if( refLayer > 9 ) refLayer = 9; // Max layer is 10
if( m_bInitAMaxBT && pcSlice->getPOC() > m_uiPrevISlicePOC )
{
::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
::memset( m_uiNumBlk, 0, sizeof( m_uiNumBlk ) );
m_bInitAMaxBT = false;
}
if( refLayer >= 0 && m_uiNumBlk[refLayer] != 0 )
{
pcSlice->setSplitConsOverrideFlag(true);

Karsten Suehring
committed
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] );
if( dBlkSize < AMAXBT_TH32 )
{
pcSlice->setMaxBTSize( 32 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 32 );
}
else if( dBlkSize < AMAXBT_TH64 )
{
pcSlice->setMaxBTSize( 64 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 64 );
}
else
{
pcSlice->setMaxBTSize( 128 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 128 );
}
m_uiBlkSize[refLayer] = 0;
m_uiNumBlk [refLayer] = 0;
}
}
else
{
if( m_bInitAMaxBT )
{
::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
::memset( m_uiNumBlk, 0, sizeof( m_uiNumBlk ) );
}
m_uiPrevISlicePOC = pcSlice->getPOC();
m_bInitAMaxBT = true;
}
}
// Slice info. refinement
if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
{
pcSlice->setSliceType ( P_SLICE );
}
xUpdateRasInit( pcSlice );
if ( pcSlice->getPendingRasInit() )
{
// this ensures that independently encoded bitstream chunks can be combined to bit-equal
pcSlice->setEncCABACTableIdx( pcSlice->getSliceType() );
}
else
{
pcSlice->setEncCABACTableIdx( m_pcSliceEncoder->getEncCABACTableIdx() );
}
if (pcSlice->getSliceType() == B_SLICE)
{
#if !JVET_O1164_RPR

Karsten Suehring
committed
#if X0038_LAMBDA_FROM_QP_CAPABILITY
const uint32_t uiColFromL0 = calculateCollocatedFromL0Flag(pcSlice);
pcSlice->setColFromL0Flag(uiColFromL0);
#else
pcSlice->setColFromL0Flag(1-uiColDir);
#endif
#endif

Karsten Suehring
committed
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
bool bLowDelay = true;
int iCurrPOC = pcSlice->getPOC();
int iRefIdx = 0;
for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
{
if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
{
bLowDelay = false;
}
}
for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
{
if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
{
bLowDelay = false;
}
}
pcSlice->setCheckLDC(bLowDelay);
}
else
{
pcSlice->setCheckLDC(true);
}
#if !X0038_LAMBDA_FROM_QP_CAPABILITY && !JVET_O1164_RPR

Karsten Suehring
committed
uiColDir = 1-uiColDir;
#endif
//-------------------------------------------------------------
pcSlice->setRefPOCList();
pcSlice->setList1IdxToList0Idx();
Martin Pettersson
committed

Karsten Suehring
committed
if (m_pcEncLib->getTMVPModeId() == 2)
{
Martin Pettersson
committed
#if JVET_O0238_PPS_OR_SLICE
assert (m_pcEncLib->getPPSTemporalMVPEnabledIdc() == 0);
#endif

Karsten Suehring
committed
if (iGOPid == 0) // first picture in SOP (i.e. forward B)
{
pcSlice->setEnableTMVPFlag(0);
}
else
{
// Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
pcSlice->setEnableTMVPFlag(1);
}
}
#if JVET_O0238_PPS_OR_SLICE
Martin Pettersson
committed
else if (m_pcEncLib->getTMVPModeId() == 1 && m_pcEncLib->getPPSTemporalMVPEnabledIdc() != 1)
#else

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

Karsten Suehring
committed
{
pcSlice->setEnableTMVPFlag(1);
}
else
{
pcSlice->setEnableTMVPFlag(0);
}
// disable TMVP when current picture is the only ref picture
if (pcSlice->isIRAP() && pcSlice->getSPS()->getIBCFlag())
{
pcSlice->setEnableTMVPFlag(0);
}
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
#if JVET_O1164_RPR
if( pcSlice->getSliceType() != I_SLICE && pcSlice->getEnableTMVPFlag() )
{
int colRefIdxL0 = -1, colRefIdxL1 = -1;
for( int refIdx = 0; refIdx < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); refIdx++ )
{
int refPicWidth = pcSlice->getRefPic( REF_PIC_LIST_0, refIdx )->unscaledPic->cs->pps->getPicWidthInLumaSamples();
int refPicHeight = pcSlice->getRefPic( REF_PIC_LIST_0, refIdx )->unscaledPic->cs->pps->getPicHeightInLumaSamples();
int curPicWidth = pcSlice->getPPS()->getPicWidthInLumaSamples();
int curPicHeight = pcSlice->getPPS()->getPicHeightInLumaSamples();
if( refPicWidth == curPicWidth && refPicHeight == curPicHeight )
{
colRefIdxL0 = refIdx;
break;
}
}
if( pcSlice->getSliceType() == B_SLICE )
{
for( int refIdx = 0; refIdx < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); refIdx++ )
{
int refPicWidth = pcSlice->getRefPic( REF_PIC_LIST_1, refIdx )->unscaledPic->cs->pps->getPicWidthInLumaSamples();
int refPicHeight = pcSlice->getRefPic( REF_PIC_LIST_1, refIdx )->unscaledPic->cs->pps->getPicHeightInLumaSamples();
int curPicWidth = pcSlice->getPPS()->getPicWidthInLumaSamples();
int curPicHeight = pcSlice->getPPS()->getPicHeightInLumaSamples();
if( refPicWidth == curPicWidth && refPicHeight == curPicHeight )
{
colRefIdxL1 = refIdx;
break;
}
}
}
if( colRefIdxL0 >= 0 && colRefIdxL1 >= 0 )
{
const Picture *refPicL0 = pcSlice->getRefPic( REF_PIC_LIST_0, colRefIdxL0 );
if( !refPicL0->slices.size() )
{
refPicL0 = refPicL0->unscaledPic;
}
const Picture *refPicL1 = pcSlice->getRefPic( REF_PIC_LIST_1, colRefIdxL1 );
if( !refPicL1->slices.size() )
{
refPicL1 = refPicL1->unscaledPic;
}
const uint32_t uiColFromL0 = refPicL0->slices[0]->getSliceQp() > refPicL1->slices[0]->getSliceQp();
pcSlice->setColFromL0Flag( uiColFromL0 );
pcSlice->setColRefIdx( uiColFromL0 ? colRefIdxL0 : colRefIdxL1 );
}
else if( colRefIdxL0 < 0 && colRefIdxL1 >= 0 )
{
pcSlice->setColFromL0Flag( false );
pcSlice->setColRefIdx( colRefIdxL1 );
}
else if( colRefIdxL0 >= 0 && colRefIdxL1 < 0 )
{
pcSlice->setColFromL0Flag( true );
pcSlice->setColRefIdx( colRefIdxL0 );
}
else
{
pcSlice->setEnableTMVPFlag( 0 );
}
}
#endif

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

Karsten Suehring
committed
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
{
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)
{
pcSlice->setMvdL1ZeroFlag(true);
}
else
{
pcSlice->setMvdL1ZeroFlag(false);
}
if ( pcSlice->getSPS()->getUseSMVD() && pcSlice->getCheckLDC() == false
#if JVET_O0284_CONDITION_SMVD_MVDL1ZEROFLAG
&& pcSlice->getMvdL1ZeroFlag() == false
#endif
{
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();
#if JVET_O0414_SMVD_LTRP
const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_0, ref)->longTerm;
if ( poc < currPOC && (poc > forwardPOC || refIdx0 == -1) && !isRefLongTerm )
if ( poc < currPOC && (poc > forwardPOC || refIdx0 == -1) )
{
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();
#if JVET_O0414_SMVD_LTRP
const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_1, ref)->longTerm;
if ( poc > currPOC && (poc < backwardPOC || refIdx1 == -1) && !isRefLongTerm )
if ( poc > currPOC && (poc < backwardPOC || refIdx1 == -1) )
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();
#if JVET_O0414_SMVD_LTRP
const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_0, ref)->longTerm;
if ( poc > currPOC && (poc < backwardPOC || refIdx0 == -1) && !isRefLongTerm )
if ( poc > currPOC && (poc < backwardPOC || refIdx0 == -1) )
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();
#if JVET_O0414_SMVD_LTRP
const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_1, ref)->longTerm;
if ( poc < currPOC && (poc > forwardPOC || refIdx1 == -1) && !isRefLongTerm )
if ( poc < currPOC && (poc > forwardPOC || refIdx1 == -1) )
{
forwardPOC = poc;
refIdx1 = ref;
}
}
}
{
pcSlice->setBiDirPred( true, refIdx0, refIdx1 );
}
else
{
pcSlice->setBiDirPred( false, -1, -1 );
}
}
else
{
pcSlice->setBiDirPred( false, -1, -1 );
}

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()->getNumTileColumnsMinus1() + 1);
const int numSubstreamRows = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->cs->pcv->heightInCtus : (pcSlice->getPPS()->getNumTileRowsMinus1() + 1);
const int numSubstreams = std::max<int> (numSubstreamRows * numSubstreamsColumns, (int) pcPic->brickMap->bricks.size());

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 ENABLE_QPA_SUB_CTU
if (pcSlice->getPPS()->getUseDQP() && pcSlice->getPPS()->getCuQpDeltaSubdiv() > 0)

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

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

Karsten Suehring
committed
#endif
if (pcSlice->getSPS()->getSAOEnabledFlag())

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 );
#if JVET_O0090_ALF_CHROMA_FILTER_ALTERNATIVES_CTB
pcPic->resizeAlfCtuAlternative( numberOfCtusInFrame );
#endif
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 );
pcPic->cs->slice = pcSlice; // please keep this
#if ENABLE_QPA
if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree (*pcSlice->getPic()->cs) && !m_pcCfg->getUsePerceptQPA() && (m_pcCfg->getSliceChromaOffsetQpPeriodicity() == 0))
#else
if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree (*pcSlice->getPic()->cs))
#endif

Karsten Suehring
committed
{
// overwrite chroma qp offset for dual tree
pcSlice->setSliceChromaQpDelta(COMPONENT_Cb, m_pcCfg->getChromaCbQpOffsetDualTree());
pcSlice->setSliceChromaQpDelta(COMPONENT_Cr, m_pcCfg->getChromaCrQpOffsetDualTree());
#if JVET_O0376_SPS_JOINTCBCR_FLAG
if (pcSlice->getSPS()->getJointCbCrEnabledFlag())
pcSlice->setSliceChromaQpDelta(JOINT_CbCr, m_pcCfg->getChromaCbCrQpOffsetDualTree());
}
#else
pcSlice->setSliceChromaQpDelta(JOINT_CbCr, m_pcCfg->getChromaCbCrQpOffsetDualTree());
#endif

Karsten Suehring
committed
m_pcSliceEncoder->setUpLambda(pcSlice, pcSlice->getLambdas()[0], pcSlice->getSliceQp());

Karsten Suehring
committed
xPicInitLMCS(pcPic, pcSlice);

Karsten Suehring
committed
#if JVET_O0299_APS_SCALINGLIST
if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
{
pcSlice->setscalingListPresentFlag( true );
int apsId = 0;
pcSlice->setscalingListAPSId( apsId );
ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
APS* scalingListAPS = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
assert( scalingListAPS != NULL );
pcSlice->setscalingListAPS( scalingListAPS );
}
#endif
if( encPic )
// now compress (trial encode) the various slice segments (slices, and dependent slices)
{
DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "poc", pocCurr ) ) );

Karsten Suehring
committed
pcSlice->setSliceCurStartCtuTsAddr( 0 );
uint32_t sliceIdx = 0;
const BrickMap& tileMap = *(pcPic->brickMap);

Karsten Suehring
committed
for(uint32_t nextCtuTsAddr = 0; nextCtuTsAddr < numberOfCtusInFrame; )
{
m_pcSliceEncoder->precompressSlice( pcPic );
m_pcSliceEncoder->compressSlice ( pcPic, false, false );
const uint32_t curSliceEnd = pcSlice->getSliceCurEndCtuTsAddr();
pcSlice->setSliceIndex(sliceIdx);

Karsten Suehring
committed
if(curSliceEnd < numberOfCtusInFrame)
{
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]);
sliceIdx++;
if (pcSlice->getPPS()->getRectSliceFlag())
{
uint32_t startTileIdx = pcSlice->getPPS()->getTopLeftBrickIdx(sliceIdx);
uint32_t nextCtu = 0;
uint32_t tmpSliceIdx = 0;
while (tmpSliceIdx != startTileIdx)
{
nextCtu++;
tmpSliceIdx = tileMap.getBrickIdxBsMap(nextCtu);
}
pcSlice->setSliceCurStartCtuTsAddr(nextCtu);
}
else
{
pcSlice->setSliceCurStartCtuTsAddr(curSliceEnd);
}

Karsten Suehring
committed
pcSlice->setSliceBits(0);
independentSliceIdx++;
pcSlice->setIndependentSliceIdx(independentSliceIdx);
uiNumSliceSegments++;
}
nextCtuTsAddr = curSliceEnd;
}
duData.clear();
CodingStructure& cs = *pcPic->cs;
pcSlice = pcPic->slices[0];
if (pcSlice->getSPS()->getUseReshaper() && m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper())
{
pcSlice->setLmcsEnabledFlag(true);
int apsId = 0;
pcSlice->setLmcsAPSId(apsId);
for (int s = 0; s < uiNumSliceSegments; s++)
{
pcPic->slices[s]->setLmcsEnabledFlag(pcSlice->getLmcsEnabledFlag());
pcPic->slices[s]->setLmcsChromaResidualScaleFlag((pcSlice->getLmcsChromaResidualScaleFlag()));
if (pcSlice->getLmcsEnabledFlag())
{
//pcPic->slices[s]->setLmcsAPS(pcSlice->getLmcsAPS());
pcPic->slices[s]->setLmcsAPSId(pcSlice->getLmcsAPSId());
}
}
CHECK((m_pcReshaper->getRecReshaped() == false), "Rec picture is not reshaped!");
pcPic->getRecoBuf(COMPONENT_Y).rspSignal(m_pcReshaper->getInvLUT());
m_pcReshaper->setRecReshaped(false);
pcPic->getOrigBuf().copyFrom(pcPic->getTrueOrigBuf());
}
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
#if JVET_O1164_PS
// create SAO object based on the picture size
if( pcSlice->getSPS()->getSAOEnabledFlag() )
{
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 = pcPic->cs->slice->getPPS()->getPpsRangeExtension().getLog2SaoOffsetScale( CHANNEL_TYPE_LUMA );
const uint32_t log2SaoOffsetScaleChroma = pcPic->cs->slice->getPPS()->getPpsRangeExtension().getLog2SaoOffsetScale( CHANNEL_TYPE_CHROMA );
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 );
}
if( !m_pcEncLib->getLoopFilterDisable() )
{
m_pcEncLib->getLoopFilter()->initEncPicYuvBuffer( chromaFormatIDC, picWidth, picHeight );
}
#endif
#if JVET_O0299_APS_SCALINGLIST
if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
{
pcSlice->setscalingListPresentFlag( true );
int apsId = 0;
pcSlice->setscalingListAPSId( apsId );
}
for( int s = 0; s < uiNumSliceSegments; s++ )
{
pcPic->slices[ s ]->setscalingListPresentFlag( pcSlice->getscalingListPresentFlag() );
if( pcSlice->getscalingListPresentFlag() )
{
pcPic->slices[ s ]->setscalingListAPSId( pcSlice->getscalingListAPSId() );
}
}
#endif

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
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
{
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
}
m_pcLoopFilter->loopFilterPic( cs );
CS::setRefinedMotionField(cs);

Karsten Suehring
committed
DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 1 ) ) );
if( pcSlice->getSPS()->getSAOEnabledFlag() )

Karsten Suehring
committed
{
bool sliceEnabled[MAX_NUM_COMPONENT];
m_pcSAO->initCABACEstimator( m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice );

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
for(int s=0; s< uiNumSliceSegments; s++)
{
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]);
}
}
if( pcSlice->getSPS()->getALFEnabledFlag() )
#if JVET_O1164_PS
m_pcALF->destroy();
m_pcALF->create( m_pcCfg, picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, m_pcCfg->getBitDepth(), m_pcCfg->getInputBitDepth() );
#endif
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
);

Christian Helmrich
committed
//assign ALF slice header
for (int s = 0; s < uiNumSliceSegments; s++)
{
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))
{
pcPic->slices[s]->setTileGroupNumAps(cs.slice->getTileGroupNumAps());
pcPic->slices[s]->setAlfAPSs(cs.slice->getTileGroupApsIdLuma());
}
else
{
pcPic->slices[s]->setTileGroupNumAps(0);
}
pcPic->slices[s]->setAlfAPSs(cs.slice->getAlfAPSs());
pcPic->slices[s]->setTileGroupApsIdChroma(cs.slice->getTileGroupApsIdChroma());

Karsten Suehring
committed
}
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
{
m_pcSAO->disabledRate( *pcPic->cs, pcPic->getSAO(1), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma());
}
}
#if JVET_O1164_RPR
pcSlice->freeScaledRefPicList( scaledRefPic );
#endif

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

Karsten Suehring
committed
{
m_uiBlkSize[pcSlice->getDepth()] += cu->Y().area();
m_uiNumBlk [pcSlice->getDepth()]++;
}
}
}
if( encPic || decPic )
{
pcSlice = pcPic->slices[0];
/////////////////////////////////////////////////////////////////////////////////////////////////// File writing
// write various parameter sets
bool writePS = m_bSeqFirst || (m_pcCfg->getReWriteParamSets() && (pcSlice->isIRAP()));
if (writePS)
{
m_pcEncLib->setParamSetChanged(pcSlice->getSPS()->getSPSId(), pcSlice->getPPS()->getPPSId());
}
actualTotalBits += xWriteParameterSets(accessUnit, pcSlice, writePS);

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;
}
if (m_pcCfg->getAccessUnitDelimiter())
{
xWriteAccessUnitDelimiter(accessUnit, pcSlice);
}
//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()->getUseReshaper())
{
//only 1 LMCS data for 1 picture
int apsId = pcSlice->getLmcsAPSId();
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)
{
actualTotalBits += xWriteAPS(accessUnit, aps);
apsMap->clearChangedFlag((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
CHECK(aps != pcSlice->getLmcsAPS(), "Wrong LMCS APS pointer in compressGOP");
}
}
#if JVET_O0299_APS_SCALINGLIST
// only 1 SCALING LIST data for 1 picture
if( pcSlice->getSPS()->getScalingListFlag() && ( m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ ) )
{
int apsId = pcSlice->getscalingListAPSId();
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 )
{
actualTotalBits += xWriteAPS( accessUnit, aps );
apsMap->clearChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
CHECK( aps != pcSlice->getscalingListAPS(), "Wrong SCALING LIST APS pointer in compressGOP" );
}
}
#endif
if (pcSlice->getSPS()->getALFEnabledFlag() && pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y))
{
#if JVET_O_MAX_NUM_ALF_APS_8
for (int apsId = 0; apsId < ALF_CTB_MAX_NUM_APS; apsId++)
#else
for (int apsId = 0; apsId < MAX_NUM_APS; apsId++) //HD: shouldn't this be looping over slice_alf_aps_id_luma[ i ]? By looping over MAX_NUM_APS, it is possible unused ALF APS is written. Please check!
{
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) = *aps; //allocate and cpy
m_pcALF->setApsIdStart( apsId );
}
{
actualTotalBits += xWriteAPS(accessUnit, aps);
apsMap->clearChangedFlag((apsId << NUM_APS_TYPE_LEN) + ALF_APS);
CHECK(aps != pcSlice->getAlfAPSs()[apsId], "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)
for(uint32_t sliceSegmentStartCtuTsAddr = 0, sliceSegmentIdxCount = 0; sliceSegmentStartCtuTsAddr < numberOfCtusInFrame; sliceSegmentIdxCount++, sliceSegmentStartCtuTsAddr = pcSlice->getSliceCurEndCtuTsAddr())
{
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
for ( uint32_t ui = 0 ; ui < numSubstreams; ui++ )
{
substreamsOut[ui].clear();
}
/* start slice NALunit */
OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
m_HLSWriter->setBitstream( &nalu.m_Bitstream );