Newer
Older

Karsten Suehring
committed
m_cInterPred.init( &m_cRdCost, sps->getChromaFormatIdc() );
m_cReshaper.createDec(sps->getBitDepth(CHANNEL_TYPE_LUMA));

Karsten Suehring
committed
bool isField = false;
bool isTopField = false;
if(!m_SEIs.empty())
{
#if !JVET_O0041_FRAME_FIELD_SEI

Karsten Suehring
committed
// Check if any new Picture Timing SEI has arrived
SEIMessages pictureTimingSEIs = getSeisByType(m_SEIs, SEI::PICTURE_TIMING);
if (pictureTimingSEIs.size()>0)
{
SEIPictureTiming* pictureTiming = (SEIPictureTiming*) *(pictureTimingSEIs.begin());
isField = (pictureTiming->m_picStruct == 1) || (pictureTiming->m_picStruct == 2) || (pictureTiming->m_picStruct == 9) || (pictureTiming->m_picStruct == 10) || (pictureTiming->m_picStruct == 11) || (pictureTiming->m_picStruct == 12);
isTopField = (pictureTiming->m_picStruct == 1) || (pictureTiming->m_picStruct == 9) || (pictureTiming->m_picStruct == 11);
}
#else
// Check if any new Frame Field Info SEI has arrived
SEIMessages frameFieldSEIs = getSeisByType(m_SEIs, SEI::FRAME_FIELD_INFO);
if (frameFieldSEIs.size()>0)
{
SEIFrameFieldInfo* ff = (SEIFrameFieldInfo*) *(frameFieldSEIs.begin());
isField = ff->m_fieldPicFlag;
isTopField = isField && (!ff->m_bottomFieldFlag);
}
#endif

Karsten Suehring
committed
}
//Set Field/Frame coding mode
m_pcPic->fieldPic = isField;
m_pcPic->topField = isTopField;
// transfer any SEI messages that have been received to the picture
m_pcPic->SEIs = m_SEIs;
m_SEIs.clear();
// Recursive structure
m_cCuDecoder.init( &m_cTrQuant, &m_cIntraPred, &m_cInterPred );
if (sps->getUseReshaper())
{
m_cCuDecoder.initDecCuReshaper(&m_cReshaper, sps->getChromaFormatIdc());
}
#if MAX_TB_SIZE_SIGNALLING
m_cTrQuant.init( nullptr, sps->getMaxTbSize(), false, false, false, false );
m_cTrQuant.init( nullptr, MAX_TB_SIZEY, false, false, false, false );

Karsten Suehring
committed
// RdCost
m_cRdCost.setCostMode ( COST_STANDARD_LOSSY ); // not used in decoder side RdCost stuff -> set to default
m_cSliceDecoder.create();

Karsten Suehring
committed
{
#if JVET_O1164_PS
m_cALF.create( pps->getPicWidthInLumaSamples(), pps->getPicHeightInLumaSamples(), sps->getChromaFormatIdc(), sps->getMaxCUWidth(), sps->getMaxCUHeight(), sps->getMaxCodingDepth(), sps->getBitDepths().recon );
#else

Karsten Suehring
committed
m_cALF.create( sps->getPicWidthInLumaSamples(), sps->getPicHeightInLumaSamples(), sps->getChromaFormatIdc(), sps->getMaxCUWidth(), sps->getMaxCUHeight(), sps->getMaxCodingDepth(), sps->getBitDepths().recon );
#endif

Karsten Suehring
committed
}
}
else
{
// make the slice-pilot a real slice, and set up the slice-pilot for the next slice
m_pcPic->allocateNewSlice();
CHECK(m_pcPic->slices.size() != (size_t)(m_uiSliceSegmentIdx + 1), "Invalid number of slices");
m_apcSlicePilot = m_pcPic->swapSliceObject(m_apcSlicePilot, m_uiSliceSegmentIdx);
Slice *pSlice = m_pcPic->slices[m_uiSliceSegmentIdx]; // we now have a real slice.
const SPS *sps = pSlice->getSPS();
const PPS *pps = pSlice->getPPS();
APS** apss = pSlice->getAlfAPSs();
APS *lmcsAPS = pSlice->getLmcsAPS();
#if JVET_O0299_APS_SCALINGLIST
APS *scalinglistAPS = pSlice->getscalingListAPS();
#endif

Karsten Suehring
committed
// fix Parameter Sets, now that we have the real slice
m_pcPic->cs->slice = pSlice;
m_pcPic->cs->sps = sps;
m_pcPic->cs->pps = pps;
memcpy(m_pcPic->cs->alfApss, apss, sizeof(m_pcPic->cs->alfApss));
m_pcPic->cs->lmcsAps = lmcsAPS;
#if JVET_O0299_APS_SCALINGLIST
m_pcPic->cs->scalinglistAps = scalinglistAPS;
#endif

Karsten Suehring
committed
m_pcPic->cs->pcv = pps->pcv;
// check that the current active PPS has not changed...
if (m_parameterSetManager.getSPSChangedFlag(sps->getSPSId()) )
{
EXIT("Error - a new SPS has been decoded while processing a picture");
}
if (m_parameterSetManager.getPPSChangedFlag(pps->getPPSId()) )
{
EXIT("Error - a new PPS has been decoded while processing a picture");
}
#if JVET_O_MAX_NUM_ALF_APS_8
for (int i = 0; i < ALF_CTB_MAX_NUM_APS; i++)
#else
for (int i = 0; i < MAX_NUM_APS; i++)
APS* aps = m_parameterSetManager.getAPS(i, ALF_APS);
if (aps && m_parameterSetManager.getAPSChangedFlag(i, ALF_APS))
{
EXIT("Error - a new APS has been decoded while processing a picture");
}
}

Karsten Suehring
committed
if (lmcsAPS && m_parameterSetManager.getAPSChangedFlag(lmcsAPS->getAPSId(), LMCS_APS) )
{
EXIT("Error - a new LMCS APS has been decoded while processing a picture");
}
#if JVET_O0299_APS_SCALINGLIST
if( scalinglistAPS && m_parameterSetManager.getAPSChangedFlag( scalinglistAPS->getAPSId(), SCALING_LIST_APS ) )
{
EXIT( "Error - a new SCALING LIST APS has been decoded while processing a picture" );
}
#endif
#if JVET_O0299_APS_SCALINGLIST
activateAPS(pSlice, m_parameterSetManager, apss, lmcsAPS, scalinglistAPS);
#else
activateAPS(pSlice, m_parameterSetManager, apss, lmcsAPS);
#endif
m_pcPic->cs->lmcsAps = lmcsAPS;
#if JVET_O0299_APS_SCALINGLIST
m_pcPic->cs->scalinglistAps = scalinglistAPS;
#endif

Karsten Suehring
committed
xParsePrefixSEImessages();
// Check if any new SEI has arrived
if(!m_SEIs.empty())
{
// Currently only decoding Unit SEI message occurring between VCL NALUs copied
SEIMessages& picSEI = m_pcPic->SEIs;
SEIMessages decodingUnitInfos = extractSeisByType( picSEI, SEI::DECODING_UNIT_INFO);
picSEI.insert(picSEI.end(), decodingUnitInfos.begin(), decodingUnitInfos.end());
deleteSEIs(m_SEIs);
}
}
// Conformance checks
#if JVET_O0244_DELTA_POC
Slice *pSlice = m_pcPic->slices[m_uiSliceSegmentIdx];
const SPS *sps = pSlice->getSPS();
const PPS *pps = pSlice->getPPS();
if( !sps->getUseWP() )
{
CHECK( pps->getUseWP(), "When sps_weighted_pred_flag is equal to 0, the value of pps_weighted_pred_flag shall be equal to 0." );
}
if( !sps->getUseWPBiPred() )
{
CHECK( pps->getWPBiPred(), "When sps_weighted_bipred_flag is equal to 0, the value of pps_weighted_bipred_flag shall be equal to 0." );
}
#endif
#if JVET_O1164_PS
#if JVET_O0640_PICTURE_SIZE_CONSTRAINT
CHECK( ( pps->getPicWidthInLumaSamples() % ( std::max( 8, int( sps->getMaxCUWidth() >> ( sps->getMaxCodingDepth() - 1 ) ) ) ) ) != 0, "Coded frame width must be a multiple of Max(8, the minimum unit size)" );
CHECK( ( pps->getPicHeightInLumaSamples() % ( std::max( 8, int( sps->getMaxCUHeight() >> ( sps->getMaxCodingDepth() - 1 ) ) ) ) ) != 0, "Coded frame height must be a multiple of Max(8, the minimum unit size)" );
#endif
if( sps->getCTUSize() + 2 * ( 1 << sps->getLog2MinCodingBlockSize() ) > pps->getPicWidthInLumaSamples() )
{
CHECK( sps->getWrapAroundEnabledFlag(), "Wraparound shall be disabled when the value of ( CtbSizeY / MinCbSizeY + 1) is less than or equal to ( pic_width_in_luma_samples / MinCbSizeY - 1 )" );
}
#endif

Karsten Suehring
committed
}
void DecLib::xParsePrefixSEIsForUnknownVCLNal()
{
while (!m_prefixSEINALUs.empty())
{
// do nothing?
msg( NOTICE, "Discarding Prefix SEI associated with unknown VCL NAL unit.\n");
delete m_prefixSEINALUs.front();
}
// TODO: discard following suffix SEIs as well?
}
void DecLib::xParsePrefixSEImessages()
{
while (!m_prefixSEINALUs.empty())
{
InputNALUnit &nalu=*m_prefixSEINALUs.front();
#if !JVET_N0867_TEMP_SCAL_HRD

Karsten Suehring
committed
m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_SEIs, nalu.m_nalUnitType, m_parameterSetManager.getActiveSPS(), m_HRD, m_pDecodedSEIOutputStream );
#else
m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_SEIs, nalu.m_nalUnitType, nalu.m_temporalId, m_parameterSetManager.getActiveSPS(), m_HRD, m_pDecodedSEIOutputStream );
#endif

Karsten Suehring
committed
delete m_prefixSEINALUs.front();
m_prefixSEINALUs.pop_front();
}
}
bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay )
{
m_apcSlicePilot->initSlice(); // the slice pilot is an object to prepare for a new slice
// it is not associated with picture, sps or pps structures.
#if JVET_O1164_RPR
#endif

Karsten Suehring
committed
if (m_bFirstSliceInPicture)
{
m_uiSliceSegmentIdx = 0;
}
else
{
m_apcSlicePilot->copySliceInfo( m_pcPic->slices[m_uiSliceSegmentIdx-1] );
}
m_apcSlicePilot->setSliceCurStartCtuTsAddr(0);
m_apcSlicePilot->setSliceCurEndCtuTsAddr(0);
m_apcSlicePilot->setSliceCurStartBrickIdx(0);
m_apcSlicePilot->setSliceCurEndBrickIdx(0);

Karsten Suehring
committed
m_apcSlicePilot->setNalUnitType(nalu.m_nalUnitType);
m_apcSlicePilot->setTLayer(nalu.m_temporalId);
Vadim Seregin
committed
#if JVET_O0245_VPS_DPS_APS
for( auto& naluTemporalId : m_accessUnitNals )
{
if( naluTemporalId.first != NAL_UNIT_DPS
&& naluTemporalId.first != NAL_UNIT_VPS
&& naluTemporalId.first != NAL_UNIT_SPS
&& naluTemporalId.first != NAL_UNIT_EOS
&& naluTemporalId.first != NAL_UNIT_EOB )
{
CHECK( naluTemporalId.second < nalu.m_temporalId, "TemporalId shall be greater than or equal to the TemporalId of the layer access unit containing the NAL unit" );
}
}
#endif
#if JVET_N0865_NONSYNTAX
if (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR)
CHECK(nalu.m_temporalId != 0, "Current GDR picture has TemporalId not equal to 0");
#endif

Karsten Suehring
committed
m_HLSReader.setBitstream( &nalu.getBitstream() );
m_HLSReader.parseSliceHeader( m_apcSlicePilot, &m_parameterSetManager, m_prevTid0POC );
// update independent slice index
uint32_t uiIndependentSliceIdx = 0;
if (!m_bFirstSliceInPicture)
{
uiIndependentSliceIdx = m_pcPic->slices[m_uiSliceSegmentIdx-1]->getIndependentSliceIdx();
uiIndependentSliceIdx++;
}
m_apcSlicePilot->setIndependentSliceIdx(uiIndependentSliceIdx);
#if K0149_BLOCK_STATISTICS
PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId());
CHECK(pps == 0, "No PPS present");
SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
CHECK(sps == 0, "No SPS present");
writeBlockStatisticsHeader(sps);
#endif

Karsten Suehring
committed
DTRACE_UPDATE( g_trace_ctx, std::make_pair( "poc", m_apcSlicePilot->getPOC() ) );
#if JVET_O0610_DETECT_AUD
#if JVET_N0865_NONSYNTAX
if ((m_bFirstSliceInPicture ||
m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ||
m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) &&
getNoOutputPriorPicsFlag())
#else
if ((m_bFirstSliceInPicture ||
m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
&& getNoOutputPriorPicsFlag() )
#endif
{
checkNoOutputPriorPics(&m_cListPic);
setNoOutputPriorPicsFlag (false);
}
#endif

Karsten Suehring
committed
xUpdatePreviousTid0POC(m_apcSlicePilot);
m_apcSlicePilot->setAssociatedIRAPPOC(m_pocCRA);
m_apcSlicePilot->setAssociatedIRAPType(m_associatedIRAPType);
//For inference of NoOutputOfPriorPicsFlag
#if JVET_N0865_NONSYNTAX
if (m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
#else

Karsten Suehring
committed
if (m_apcSlicePilot->getRapPicFlag())
#endif

Karsten Suehring
committed
{
#if JVET_N0865_NONSYNTAX
if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_bFirstSliceInSequence) ||
(m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_apcSlicePilot->getHandleCraAsCvsStartFlag()) ||
(m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR && m_bFirstSliceInSequence))
{
m_apcSlicePilot->setNoIncorrectPicOutputFlag(true);
}
#else
if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_bFirstSliceInSequence) ||
(m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_apcSlicePilot->getHandleCraAsCvsStartFlag()))

Karsten Suehring
committed
{
m_apcSlicePilot->setNoRaslOutputFlag(true);
}
#endif

Karsten Suehring
committed
//the inference for NoOutputPriorPicsFlag
#if JVET_N0865_NONSYNTAX
if (!m_bFirstSliceInBitstream &&
(m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) &&
m_apcSlicePilot->getNoIncorrectPicOutputFlag())
{
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
{
m_apcSlicePilot->setNoOutputPriorPicsFlag(true);
}
}
#else

Karsten Suehring
committed
if (!m_bFirstSliceInBitstream && m_apcSlicePilot->getRapPicFlag() && m_apcSlicePilot->getNoRaslOutputFlag())
{
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
{
m_apcSlicePilot->setNoOutputPriorPicsFlag(true);
}
}
#endif

Karsten Suehring
committed
else
{
m_apcSlicePilot->setNoOutputPriorPicsFlag(false);
}
#if JVET_N0865_NONSYNTAX
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
{
m_lastNoIncorrectPicOutputFlag = m_apcSlicePilot->getNoIncorrectPicOutputFlag();
}
#else

Karsten Suehring
committed
if(m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
{
m_craNoRaslOutputFlag = m_apcSlicePilot->getNoRaslOutputFlag();
}
#endif

Karsten Suehring
committed
}
#if JVET_N0865_NONSYNTAX
if ((m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) && m_apcSlicePilot->getNoOutputPriorPicsFlag())
#else

Karsten Suehring
committed
if (m_apcSlicePilot->getRapPicFlag() && m_apcSlicePilot->getNoOutputPriorPicsFlag())
#endif

Karsten Suehring
committed
{
m_lastPOCNoOutputPriorPics = m_apcSlicePilot->getPOC();
m_isNoOutputPriorPics = true;
}
else
{
m_isNoOutputPriorPics = false;
}
//For inference of PicOutputFlag
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL)

Karsten Suehring
committed
{
#if JVET_N0865_NONSYNTAX
if (m_lastNoIncorrectPicOutputFlag)
#else

Karsten Suehring
committed
if ( m_craNoRaslOutputFlag )
#endif

Karsten Suehring
committed
{
m_apcSlicePilot->setPicOutputFlag(false);
}
}
#if JVET_N0865_NONSYNTAX
if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) &&
m_lastNoIncorrectPicOutputFlag) //Reset POC MSB when CRA or GDR has NoIncorrectPicOutputFlag equal to 1
#else

Karsten Suehring
committed
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_craNoRaslOutputFlag) //Reset POC MSB when CRA has NoRaslOutputFlag equal to 1
#endif

Karsten Suehring
committed
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
{
PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId());
CHECK(pps == 0, "No PPS present");
SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
CHECK(sps == 0, "No SPS present");
int iMaxPOClsb = 1 << sps->getBitsForPOC();
m_apcSlicePilot->setPOC( m_apcSlicePilot->getPOC() & (iMaxPOClsb - 1) );
xUpdatePreviousTid0POC(m_apcSlicePilot);
}
// Skip pictures due to random access
if (isRandomAccessSkipPicture(iSkipFrame, iPOCLastDisplay))
{
m_prevSliceSkipped = true;
m_skippedPOC = m_apcSlicePilot->getPOC();
return false;
}
// Skip TFD pictures associated with BLA/BLANT pictures
// clear previous slice skipped flag
m_prevSliceSkipped = false;
//we should only get a different poc for a new picture (with CTU address==0)
if(m_apcSlicePilot->getPOC() != m_prevPOC && !m_bFirstSliceInSequence && (m_apcSlicePilot->getSliceCurStartCtuTsAddr() != 0))
{
msg( WARNING, "Warning, the first slice of a picture might have been lost!\n");
}
// leave when a new picture is found
if(m_apcSlicePilot->getSliceCurStartCtuTsAddr() == 0 && !m_bFirstSliceInPicture)
{
if (m_prevPOC >= m_pocRandomAccess)
{
DTRACE_UPDATE( g_trace_ctx, std::make_pair( "final", 0 ) );
m_prevPOC = m_apcSlicePilot->getPOC();
return true;
}
m_prevPOC = m_apcSlicePilot->getPOC();
}
else
{
DTRACE_UPDATE( g_trace_ctx, std::make_pair( "final", 1 ) );
}
//detect lost reference picture and insert copy of earlier frame.
{
int lostPoc;
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
#if JVET_O0241
int refPicIndex;
while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL0(), 0, true, &refPicIndex)) > 0)
{
#if JVET_N0865_GRA2GDR
if ( ( (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) || (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) ) && m_apcSlicePilot->getNoIncorrectPicOutputFlag() )
#else
if (((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GRA) || (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)) && m_apcSlicePilot->getNoIncorrectPicOutputFlag())
#endif
{
xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm(refPicIndex));
}
else
{
xCreateLostPicture(lostPoc - 1);
}
}
while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL0(), 0, true, &refPicIndex)) > 0)
{
#if JVET_N0865_GRA2GDR
if (((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) || (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)) && m_apcSlicePilot->getNoIncorrectPicOutputFlag())
#else
if (((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GRA) || (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)) && m_apcSlicePilot->getNoIncorrectPicOutputFlag())
#endif
{
xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm(refPicIndex));
}
else
{
xCreateLostPicture(lostPoc - 1);
}
}
#else
while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL0(), 0, true)) > 0)
xCreateLostPicture(lostPoc - 1);
while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL1(), 1, true)) > 0)
xCreateLostPicture(lostPoc - 1);

Karsten Suehring
committed
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
}
m_prevPOC = m_apcSlicePilot->getPOC();
if (m_bFirstSliceInPicture)
{
xUpdateRasInit(m_apcSlicePilot);
}
// actual decoding starts here
xActivateParameterSets();
m_bFirstSliceInSequence = false;
m_bFirstSliceInBitstream = false;
Slice* pcSlice = m_pcPic->slices[m_uiSliceSegmentIdx];
pcSlice->setPic( m_pcPic );
m_pcPic->poc = pcSlice->getPOC();
m_pcPic->layer = pcSlice->getTLayer();
m_pcPic->referenced = true;
m_pcPic->layer = nalu.m_temporalId;
#if JVET_O0143_BOTTOM_RIGHT_BRICK_IDX_DELTA
if (pcSlice->getPPS()->getRectSliceFlag())
{
int sliceIdx = pcSlice->getSliceIndex();
int topLeft = pcSlice->getPic()->brickMap->getTopLeftBrickIdx(sliceIdx);
int bottomRight = pcSlice->getPic()->brickMap->getBottomRightBrickIdx(sliceIdx);
pcSlice->setSliceCurStartBrickIdx(topLeft);
pcSlice->setSliceCurEndBrickIdx(bottomRight);
pcSlice->setSliceCurStartCtuTsAddr(pcSlice->getSliceCurStartBrickIdx());
}
#endif

Karsten Suehring
committed
// When decoding the slice header, the stored start and end addresses were actually RS addresses, not TS addresses.
// Now, having set up the maps, convert them to the correct form.
const uint32_t numberOfCtusInFrame = m_pcPic->cs->pcv->sizeInCtus;

Karsten Suehring
committed
uint32_t startCtuIdx = 0;
while (pcSlice->getSliceCurStartBrickIdx() != tileMap.getBrickIdxBsMap(startCtuIdx) && startCtuIdx < numberOfCtusInFrame)
{
startCtuIdx++;
}
uint32_t endCtuIdx = startCtuIdx;
while (pcSlice->getSliceCurEndBrickIdx() != tileMap.getBrickIdxBsMap(endCtuIdx) && endCtuIdx < numberOfCtusInFrame)
{
endCtuIdx++;
}
if (endCtuIdx == numberOfCtusInFrame)
EXIT("Cannot find the last CTU index of the current slice");
while ( (endCtuIdx < numberOfCtusInFrame) && (pcSlice->getSliceCurEndBrickIdx() == tileMap.getBrickIdxBsMap(endCtuIdx)) )
{
endCtuIdx++;
}
if (pcSlice->getSliceCurEndBrickIdx() != tileMap.getBrickIdxBsMap(endCtuIdx - 1))
EXIT("Cannot find the last CTU index of the current slice");
pcSlice->setSliceCurStartCtuTsAddr(startCtuIdx);
pcSlice->setSliceCurEndCtuTsAddr(endCtuIdx);

Karsten Suehring
committed
pcSlice->checkCRA(pcSlice->getRPL0(), pcSlice->getRPL1(), m_pocCRA, m_associatedIRAPType, m_cListPic);
pcSlice->constructRefPicList(m_cListPic);
#if JVET_O1164_RPR
#if JVET_O0299_APS_SCALINGLIST
pcSlice->scaleRefPicList( scaledRefPic, m_parameterSetManager.getAPSs(), pcSlice->getLmcsAPS(), pcSlice->getscalingListAPS(), true );
#else
pcSlice->scaleRefPicList( scaledRefPic, m_parameterSetManager.getAPSs(), pcSlice->getLmcsAPS(), true );
#endif
#endif

Karsten Suehring
committed
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
if (!pcSlice->isIntra())
{
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;
}
}
if (pcSlice->isInterB())
{
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);
}
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;
int refIdx0 = -1;
int 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
//---------------
pcSlice->setRefPOCList();
#if JVET_N0494_DRAP
SEIMessages drapSEIs = getSeisByType(m_pcPic->SEIs, SEI::DEPENDENT_RAP_INDICATION );
if (!drapSEIs.empty())
{
msg( NOTICE, "Dependent RAP indication SEI decoded\n");
pcSlice->setDRAP(true);
pcSlice->setLatestDRAPPOC(pcSlice->getPOC());
}
pcSlice->checkConformanceForDRAP(nalu.m_temporalId);
#endif

Karsten Suehring
committed
Quant *quant = m_cTrQuant.getQuant();
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
#if JVET_O0299_APS_SCALINGLIST
if( pcSlice->getSPS()->getScalingListFlag() )
{
ScalingList scalingList;
if( pcSlice->getscalingListPresentFlag() )
{
APS* scalingListAPS = pcSlice->getscalingListAPS();
scalingList = scalingListAPS->getScalingList();
}
else
{
scalingList.setDefaultScalingList();
}
quant->setScalingListDec( scalingList );
quant->setUseScalingList( true );
}
else
{
quant->setUseScalingList( false );
}
#else

Karsten Suehring
committed
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
if(pcSlice->getSPS()->getScalingListFlag())
{
ScalingList scalingList;
if(pcSlice->getPPS()->getScalingListPresentFlag())
{
scalingList = pcSlice->getPPS()->getScalingList();
}
else if (pcSlice->getSPS()->getScalingListPresentFlag())
{
scalingList = pcSlice->getSPS()->getScalingList();
}
else
{
scalingList.setDefaultScalingList();
}
quant->setScalingListDec(scalingList);
quant->setUseScalingList(true);
}
else
{
quant->setUseScalingList(false);
}
#endif

Karsten Suehring
committed
if (pcSlice->getSPS()->getUseReshaper())
{
#if JVET_O0428_LMCS_CLEANUP
if (m_bFirstSliceInPicture)
m_sliceLmcsApsId = -1;
#endif
if (pcSlice->getLmcsEnabledFlag())
{
APS* lmcsAPS = pcSlice->getLmcsAPS();
#if JVET_O0428_LMCS_CLEANUP
{
m_sliceLmcsApsId = lmcsAPS->getAPSId();
}
else
{
CHECK(lmcsAPS->getAPSId() != m_sliceLmcsApsId, "same APS ID shall be used for all slices in one picture");
}
#endif
SliceReshapeInfo& sInfo = lmcsAPS->getReshaperAPSInfo();
SliceReshapeInfo& tInfo = m_cReshaper.getSliceReshaperInfo();
tInfo.reshaperModelMaxBinIdx = sInfo.reshaperModelMaxBinIdx;
tInfo.reshaperModelMinBinIdx = sInfo.reshaperModelMinBinIdx;
memcpy(tInfo.reshaperModelBinCWDelta, sInfo.reshaperModelBinCWDelta, sizeof(int)*(PIC_CODE_CW_BINS));
tInfo.maxNbitsNeededDeltaCW = sInfo.maxNbitsNeededDeltaCW;
tInfo.setUseSliceReshaper(pcSlice->getLmcsEnabledFlag());
tInfo.setSliceReshapeChromaAdj(pcSlice->getLmcsChromaResidualScaleFlag());
tInfo.setSliceReshapeModelPresentFlag(true);
}
else
{
SliceReshapeInfo& tInfo = m_cReshaper.getSliceReshaperInfo();
tInfo.setUseSliceReshaper(false);
tInfo.setSliceReshapeChromaAdj(false);
tInfo.setSliceReshapeModelPresentFlag(false);
}
if (pcSlice->getLmcsEnabledFlag())
{
m_cReshaper.constructReshaper();
}
else
{
m_cReshaper.setReshapeFlag(false);
}
if ((pcSlice->getSliceType() == I_SLICE) && m_cReshaper.getSliceReshaperInfo().getUseSliceReshaper())
{
m_cReshaper.setCTUFlag(false);
m_cReshaper.setRecReshaped(true);
}
else
{
if (m_cReshaper.getSliceReshaperInfo().getUseSliceReshaper())
{
m_cReshaper.setCTUFlag(true);
m_cReshaper.setRecReshaped(true);
}
else
{
m_cReshaper.setCTUFlag(false);
m_cReshaper.setRecReshaped(false);
}
}
#if JVET_O1109_UNFIY_CRS
m_cReshaper.setVPDULoc(-1, -1);
#endif
}
else
{
m_cReshaper.setCTUFlag(false);
m_cReshaper.setRecReshaped(false);
}

Karsten Suehring
committed
// Decode a picture
m_cSliceDecoder.decompressSlice( pcSlice, &( nalu.getBitstream() ), ( m_pcPic->poc == getDebugPOC() ? getDebugCTU() : -1 ) );

Karsten Suehring
committed
m_bFirstSliceInPicture = false;
m_uiSliceSegmentIdx++;
#if JVET_O1164_RPR
pcSlice->freeScaledRefPicList( scaledRefPic );
#endif

Karsten Suehring
committed
return false;
}
void DecLib::xDecodeVPS( InputNALUnit& nalu )
{
VPS* vps = new VPS();
m_HLSReader.setBitstream( &nalu.getBitstream() );
Vadim Seregin
committed
#if JVET_O0245_VPS_DPS_APS
CHECK( nalu.m_temporalId, "The value of TemporalId of VPS NAL units shall be equal to 0" );
#endif

Karsten Suehring
committed
m_HLSReader.parseVPS( vps );

Karsten Suehring
committed
}
void DecLib::xDecodeDPS( InputNALUnit& nalu )
{
DPS* dps = new DPS();
m_HLSReader.setBitstream( &nalu.getBitstream() );
Vadim Seregin
committed
#if JVET_O0245_VPS_DPS_APS
CHECK( nalu.m_temporalId, "The value of TemporalId of DPS NAL units shall be equal to 0" );
#endif
m_HLSReader.parseDPS( dps );
m_parameterSetManager.storeDPS( dps, nalu.getBitstream().getFifo() );
}

Karsten Suehring
committed
void DecLib::xDecodeSPS( InputNALUnit& nalu )
{
SPS* sps = new SPS();
m_HLSReader.setBitstream( &nalu.getBitstream() );
Vadim Seregin
committed
#if JVET_O0245_VPS_DPS_APS
CHECK( nalu.m_temporalId, "The value of TemporalId of SPS NAL units shall be equal to 0" );
#endif

Karsten Suehring
committed
m_HLSReader.parseSPS( sps );
DTRACE( g_trace_ctx, D_QP_PER_CTU, "CTU Size: %dx%d", sps->getMaxCUWidth(), sps->getMaxCUHeight() );
m_parameterSetManager.storeSPS( sps, nalu.getBitstream().getFifo() );

Karsten Suehring
committed
}
void DecLib::xDecodePPS( InputNALUnit& nalu )
{
PPS* pps = new PPS();
m_HLSReader.setBitstream( &nalu.getBitstream() );
Sheng-Yen Lin
committed
m_HLSReader.parsePPS( pps, &m_parameterSetManager );
Vadim Seregin
committed
#if JVET_O0245_VPS_DPS_APS
pps->setLayerId( nalu.m_nuhLayerId );
pps->setTemporalId( nalu.m_temporalId );
#endif

Karsten Suehring
committed
m_parameterSetManager.storePPS( pps, nalu.getBitstream().getFifo() );
}
void DecLib::xDecodeAPS(InputNALUnit& nalu)
{
APS* aps = new APS();
m_HLSReader.setBitstream(&nalu.getBitstream());
m_HLSReader.parseAPS(aps);
aps->setTemporalId(nalu.m_temporalId);
Vadim Seregin
committed
#if JVET_O0245_VPS_DPS_APS
aps->setLayerId( nalu.m_nuhLayerId );
m_parameterSetManager.checkAuApsContent( aps, m_accessUnitApsNals );
#endif
m_parameterSetManager.storeAPS(aps, nalu.getBitstream().getFifo());
}

Karsten Suehring
committed
bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
{
bool ret;
// ignore all NAL units of layers > 0
if (getTargetDecLayer() >= 0 && nalu.m_nuhLayerId != getTargetDecLayer()) //TBC: ignore bitstreams whose nuh_layer_id is not the target layer id

Karsten Suehring
committed
{
msg( WARNING, "Warning: found NAL unit with nuh_layer_id equal to %d. Ignoring.\n", nalu.m_nuhLayerId);
return false;
}
Vadim Seregin
committed
#if JVET_O0245_VPS_DPS_APS
m_accessUnitNals.push_back( std::pair<NalUnitType, int>( nalu.m_nalUnitType, nalu.m_temporalId ) );
#endif

Karsten Suehring
committed
switch (nalu.m_nalUnitType)
{
case NAL_UNIT_VPS:
xDecodeVPS( nalu );
return false;
case NAL_UNIT_DPS:
xDecodeDPS( nalu );
return false;

Karsten Suehring
committed
case NAL_UNIT_SPS:
xDecodeSPS( nalu );
return false;
case NAL_UNIT_PPS:
xDecodePPS( nalu );
return false;
case NAL_UNIT_APS:
xDecodeAPS(nalu);
return false;

Karsten Suehring
committed
case NAL_UNIT_PREFIX_SEI:
// Buffer up prefix SEI messages until SPS of associated VCL is known.
m_prefixSEINALUs.push_back(new InputNALUnit(nalu));
return false;
case NAL_UNIT_SUFFIX_SEI:
if (m_pcPic)
{
#if !JVET_N0867_TEMP_SCAL_HRD

Karsten Suehring
committed
m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_pcPic->SEIs, nalu.m_nalUnitType, m_parameterSetManager.getActiveSPS(), m_HRD, m_pDecodedSEIOutputStream );
#else
m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_pcPic->SEIs, nalu.m_nalUnitType, nalu.m_temporalId, m_parameterSetManager.getActiveSPS(), m_HRD, m_pDecodedSEIOutputStream );
#endif

Karsten Suehring
committed
}
else
{
msg( NOTICE, "Note: received suffix SEI but no picture currently active.\n");
}
return false;
case NAL_UNIT_CODED_SLICE_TRAIL:
case NAL_UNIT_CODED_SLICE_STSA:
case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
case NAL_UNIT_CODED_SLICE_IDR_N_LP:
case NAL_UNIT_CODED_SLICE_CRA:
#if JVET_N0865_NONSYNTAX
case NAL_UNIT_CODED_SLICE_GDR:
#endif
case NAL_UNIT_CODED_SLICE_RADL:
case NAL_UNIT_CODED_SLICE_RASL:

Karsten Suehring
committed
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
ret = xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay);
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
if ( ret )
{
m_cacheModel.reportFrame( );
m_cacheModel.accumulateFrame( );
m_cacheModel.clear( );
}
#endif
return ret;
case NAL_UNIT_EOS:
m_associatedIRAPType = NAL_UNIT_INVALID;
m_pocCRA = 0;
m_pocRandomAccess = MAX_INT;
m_prevPOC = MAX_INT;
m_prevSliceSkipped = false;
m_skippedPOC = 0;
return false;
case NAL_UNIT_ACCESS_UNIT_DELIMITER:
{
AUDReader audReader;
uint32_t picType;
audReader.parseAccessUnitDelimiter(&(nalu.getBitstream()),picType);
Vadim Seregin
committed
#if JVET_O0245_VPS_DPS_APS
// vectors clearing shall be moved to the right place if mandatory AUD starting an AU is removed
m_accessUnitNals.clear();
m_accessUnitApsNals.clear();
m_accessUnitNals.push_back( std::pair<NalUnitType, int>( NAL_UNIT_ACCESS_UNIT_DELIMITER, nalu.m_temporalId ) );
#endif
#if JVET_O0610_DETECT_AUD
return !m_bFirstSliceInPicture;
#else
msg( NOTICE, "Note: found NAL_UNIT_ACCESS_UNIT_DELIMITER\n");
return false;
#endif

Karsten Suehring
committed
}
case NAL_UNIT_EOB:
return false;