Commit 2ad2609d authored by Jack Enhorn's avatar Jack Enhorn
Browse files

GDR related decoder fixes

parent 51613562
......@@ -165,6 +165,9 @@ uint32_t DecApp::decode()
m_cDecLib.setHTidExternalSetFlag(m_mTidExternalSet);
m_cDecLib.setTOlsIdxExternalFlag(m_tOlsIdxTidExternalSet);
bool gdrRecoveryPeriod[MAX_NUM_LAYER_IDS] = { false };
bool prevPicSkipped = true;
while (!!bitstreamFile)
{
InputNALUnit nalu;
......@@ -249,7 +252,40 @@ uint32_t DecApp::decode()
bPicSkipped = false;
}
}
int skipFrameCounter = m_iSkipFrame;
m_cDecLib.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay, m_targetOlsIdx);
if ( prevPicSkipped && nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR )
{
gdrRecoveryPeriod[nalu.m_nuhLayerId] = true;
}
if ( skipFrameCounter == 1 && ( nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA ))
{
skipFrameCounter--;
}
if ( m_iSkipFrame < skipFrameCounter &&
((nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_TRAIL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_STSA) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_RADL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) || (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR)))
{
if (m_cDecLib.isSliceNaluFirstInAU(true, nalu))
{
m_cDecLib.checkSeiInPictureUnit();
m_cDecLib.resetPictureSeiNalus();
m_cDecLib.checkAPSInPictureUnit();
m_cDecLib.resetPictureUnitNals();
m_cDecLib.resetAccessUnitSeiTids();
m_cDecLib.checkSEIInAccessUnit();
m_cDecLib.resetAccessUnitSeiPayLoadTypes();
m_cDecLib.resetAccessUnitNals();
m_cDecLib.resetAccessUnitApsNals();
m_cDecLib.resetAccessUnitPicInfo();
}
bPicSkipped = true;
m_iSkipFrame++; // skipFrame count restore, the real decrement occur at the begin of next frame
}
if (nalu.m_nalUnitType == NAL_UNIT_OPI)
{
if (!m_cDecLib.getHTidExternalSetFlag() && m_cDecLib.getOPI()->getHtidInfoPresentFlag())
......@@ -270,6 +306,12 @@ uint32_t DecApp::decode()
bPicSkipped = true;
}
}
if( nalu.isSlice() )
{
prevPicSkipped = bPicSkipped;
}
// once an EOS NAL unit appears in the current PU, mark the variable isEosPresentInPu as true
if (nalu.m_nalUnitType == NAL_UNIT_EOS)
{
......@@ -299,6 +341,14 @@ uint32_t DecApp::decode()
m_cDecLib.updateAssociatedIRAP();
m_cDecLib.updatePrevGDRInSameLayer();
m_cDecLib.updatePrevIRAPAndGDRSubpic();
if ( gdrRecoveryPeriod[nalu.m_nuhLayerId] )
{
if ( m_cDecLib.getGDRRecoveryPocReached() )
{
gdrRecoveryPeriod[nalu.m_nuhLayerId] = false;
}
}
}
else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) &&
m_cDecLib.getFirstSliceInSequence(nalu.m_nuhLayerId))
......@@ -308,6 +358,19 @@ uint32_t DecApp::decode()
if( pcListPic )
{
if ( gdrRecoveryPeriod[nalu.m_nuhLayerId] ) // Suppress YUV and OPL output during GDR recovery
{
PicList::iterator iterPic = pcListPic->begin();
while (iterPic != pcListPic->end())
{
Picture *pcPic = *(iterPic++);
if (pcPic->layerId == nalu.m_nuhLayerId)
{
pcPic->neededForOutput = false;
}
}
}
if( !m_reconFileName.empty() && !m_cVideoIOYuvReconFile[nalu.m_nuhLayerId].isOpen() )
{
const BitDepths &bitDepths=pcListPic->front()->cs->sps->getBitDepths(); // use bit depths of first reconstructed picture.
......
......@@ -614,12 +614,19 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
int irapPOC = getAssociatedIRAPPOC();
const int numEntries[] = { pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(), pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures() };
int numEntries[] = { pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(), pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures() };
const int numActiveEntries[] = { getNumRefIdx( REF_PIC_LIST_0 ), getNumRefIdx( REF_PIC_LIST_1 ) };
const ReferencePictureList* rpl[] = { pRPL0, pRPL1 };
const bool fieldSeqFlag = getSPS()->getFieldSeqFlag();
const int layerIdx = m_pcPic->cs->vps == nullptr ? 0 : m_pcPic->cs->vps->getGeneralLayerIdx( m_pcPic->layerId );
if ( rcListPic.size() < numEntries[0] || rcListPic.size() < numEntries[1] )
{
numEntries[0] = 0;
numEntries[1] = 0;
msg( NOTICE, "Reset numEntriesL0 and numEntriesL1. E.g. receive a CRA after some skipped slices\n");
}
for( int refPicList = 0; refPicList < 2; refPicList++ )
{
for( int i = 0; i < numEntries[refPicList]; i++ )
......@@ -668,7 +675,7 @@ void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureLi
// Generated reference picture does not have picture header
const bool isGeneratedRefPic = pcRefPic->slices[0]->getPicHeader() ? false : true;
const bool nonReferencePictureFlag = isGeneratedRefPic ? pcRefPic->slices[0]->getPicHeader()->getNonReferencePictureFlag() : pcRefPic->nonReferencePictureFlag;
const bool nonReferencePictureFlag = isGeneratedRefPic ? pcRefPic->nonReferencePictureFlag : pcRefPic->slices[0]->getPicHeader()->getNonReferencePictureFlag();
CHECK( pcRefPic == m_pcPic || nonReferencePictureFlag, "The picture referred to by each entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall not be the current picture and shall have ph_non_ref_pic_flag equal to 0" );
if( i < numActiveEntries[refPicList] )
......@@ -1110,37 +1117,40 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic, const PPS& pps)
}
const Slice* pcSlice = pcPic->slices[0];
if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getNoOutputOfPriorPicsFlag() && pcPic->layerId == this->m_nuhLayerId)
if(pcSlice->getPicHeader()) // Generated reference picture does not have picture header
{
if ((nalUnitType == NAL_UNIT_CODED_SLICE_CRA || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL) && !pps.getMixedNaluTypesInPicFlag())
if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getNoOutputOfPriorPicsFlag() && pcPic->layerId == this->m_nuhLayerId)
{
CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
"equal to layerId in decoding order shall precede the IRAP picture in output order.");
if ((nalUnitType == NAL_UNIT_CODED_SLICE_CRA || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL) && !pps.getMixedNaluTypesInPicFlag())
{
CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
"equal to layerId in decoding order shall precede the IRAP picture in output order.");
}
}
}
if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && pcPic->layerId == this->m_nuhLayerId)
{
if (nalUnitType == NAL_UNIT_CODED_SLICE_RADL)
if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && pcPic->layerId == this->m_nuhLayerId)
{
if (this->getAssociatedIRAPPOC() > pcSlice->getAssociatedIRAPPOC() && !pps.getMixedNaluTypesInPicFlag())
if (nalUnitType == NAL_UNIT_CODED_SLICE_RADL)
{
if (this->getAssociatedIRAPPOC() != pcPic->poc)
if (this->getAssociatedIRAPPOC() > pcSlice->getAssociatedIRAPPOC() && !pps.getMixedNaluTypesInPicFlag())
{
CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
"equal to layerId in decoding order shall precede any RADL picture associated with the IRAP picture in output order.");
if (this->getAssociatedIRAPPOC() != pcPic->poc)
{
CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
"equal to layerId in decoding order shall precede any RADL picture associated with the IRAP picture in output order.");
}
}
}
}
}
if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getPicHeader()->getNoOutputBeforeRecoveryFlag() && pcPic->layerId == this->m_nuhLayerId
&& nalUnitType != NAL_UNIT_CODED_SLICE_GDR && this->getPicHeader()->getRecoveryPocCnt() != -1)
{
if (this->getPOC() == this->getPicHeader()->getRecoveryPocCnt() + this->getPrevGDRInSameLayerPOC())
if (pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getPicHeader()->getNoOutputBeforeRecoveryFlag() && pcPic->layerId == this->m_nuhLayerId
&& nalUnitType != NAL_UNIT_CODED_SLICE_GDR && this->getPicHeader()->getRecoveryPocCnt() != -1)
{
CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes a recovery point picture with "
"nuh_layer_id equal to layerId in decoding order shall precede the recovery point picture in output order.");
if (this->getPOC() == this->getPicHeader()->getRecoveryPocCnt() + this->getPrevGDRInSameLayerPOC())
{
CHECK(pcPic->poc >= this->getPOC(), "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes a recovery point picture with "
"nuh_layer_id equal to layerId in decoding order shall precede the recovery point picture in output order.");
}
}
}
......@@ -1251,14 +1261,18 @@ void Slice::checkSubpicTypeConstraints(PicList& rcListPic, const ReferencePictur
bool isBufPicOutput = false;
int bufSubpicType = NAL_UNIT_INVALID;
int bufSubpicPrevIRAPSubpicPOC = 0;
for (int i = 0; i < bufPic->numSlices; i++)
if (bufPic->slices[0]->getPicHeader() != NULL) // Generated reference picture does not have picture header
{
if (bufPic->sliceSubpicIdx[i] == curSubpicIdx)
for (int i = 0; i < bufPic->numSlices; i++)
{
isBufPicOutput = bufPic->slices[i]->getPicHeader()->getPicOutputFlag();
bufSubpicType = bufPic->slices[i]->getNalUnitType();
bufSubpicPrevIRAPSubpicPOC = bufPic->slices[i]->getPrevIRAPSubpicPOC();
break;
if (bufPic->sliceSubpicIdx[i] == curSubpicIdx)
{
isBufPicOutput = bufPic->slices[i]->getPicHeader()->getPicOutputFlag();
bufSubpicType = bufPic->slices[i]->getNalUnitType();
bufSubpicPrevIRAPSubpicPOC = bufPic->slices[i]->getPrevIRAPSubpicPOC();
break;
}
}
}
......@@ -1813,7 +1827,7 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
{
if (printErrors)
{
msg(ERROR, "\nCurrent picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc);
msg(ERROR, "Error: Current picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), notPresentPoc);
}
return notPresentPoc;
}
......@@ -1844,7 +1858,7 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
{
if (printErrors)
{
msg(ERROR, "\nCurrent picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc);
msg(ERROR, "Error: Current picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), notPresentPoc);
}
return notPresentPoc;
}
......@@ -1923,7 +1937,7 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
{
if (printErrors)
{
msg(ERROR, "\nCurrent picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc);
msg(ERROR, "Error: Current picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), notPresentPoc);
}
*refPicIndex = ii;
return notPresentPoc;
......@@ -1955,7 +1969,7 @@ int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePi
{
if (printErrors)
{
msg(ERROR, "\nCurrent picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc);
msg(ERROR, "Error: Current picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), notPresentPoc);
}
*refPicIndex = ii;
return notPresentPoc;
......
......@@ -424,11 +424,11 @@ DecLib::DecLib()
, m_prevPicPOC(MAX_INT)
, m_prevTid0POC(0)
, m_bFirstSliceInPicture(true)
, m_firstSliceInSequence{ true }
, m_firstSliceInBitstream(true)
, m_isFirstAuInCvs( true )
, m_prevSliceSkipped(false)
, m_skippedPOC(0)
, m_skippedPOC(MAX_INT)
, m_skippedLayerID(MAX_INT)
, m_lastPOCNoOutputPriorPics(-1)
, m_isNoOutputPriorPics(false)
, m_lastNoOutputBeforeRecoveryFlag{ false }
......@@ -463,6 +463,8 @@ DecLib::DecLib()
memset(m_prevEOS, false, sizeof(m_prevEOS));
memset(m_accessUnitEos, false, sizeof(m_accessUnitEos));
std::fill_n(m_prevGDRInSameLayerPOC, MAX_VPS_LAYERS, -MAX_INT);
std::fill_n(m_prevGDRInSameLayerRecoveryPOC, MAX_VPS_LAYERS, -MAX_INT);
std::fill_n(m_firstSliceInSequence, MAX_VPS_LAYERS, true);
std::fill_n(m_pocCRA, MAX_VPS_LAYERS, -MAX_INT);
for (int i = 0; i < MAX_VPS_LAYERS; i++)
{
......@@ -898,13 +900,22 @@ void DecLib::xCreateLostPicture( int iLostPoc, const int layerId )
void DecLib::xCreateUnavailablePicture( const PPS *pps, const int iUnavailablePoc, const bool longTermFlag, const int temporalId, const int layerId, const bool interLayerRefPicFlag )
{
msg(INFO, "\ninserting unavailable poc : %d\n", iUnavailablePoc);
msg(INFO, "Note: Inserting unavailable POC : %d\n", iUnavailablePoc);
Picture* cFillPic = xGetNewPicBuffer( *( m_parameterSetManager.getFirstSPS() ), *( m_parameterSetManager.getFirstPPS() ), 0, layerId );
CHECK(!cFillPic->slices.size(), "No slices in picture");
cFillPic->cs = new CodingStructure( g_globalUnitCache.cuCache, g_globalUnitCache.puCache, g_globalUnitCache.tuCache );
cFillPic->cs->sps = m_parameterSetManager.getFirstSPS();
cFillPic->cs->pps = m_parameterSetManager.getFirstPPS();
cFillPic->cs->vps = m_parameterSetManager.getVPS(0);
cFillPic->cs->create(cFillPic->cs->sps->getChromaFormatIdc(), Area(0, 0, cFillPic->cs->pps->getPicWidthInLumaSamples(), cFillPic->cs->pps->getPicHeightInLumaSamples()), true, (bool)(cFillPic->cs->sps->getPLTMode()));
cFillPic->allocateNewSlice();
cFillPic->slices[0]->initSlice();
cFillPic->setDecodingOrderNumber(0);
cFillPic->subLayerNonReferencePictureDueToSTSA = false;
cFillPic->unscaledPic = cFillPic;
uint32_t yFill = 1 << (m_parameterSetManager.getFirstSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 1);
uint32_t cFill = 1 << (m_parameterSetManager.getFirstSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - 1);
cFillPic->getRecoBuf().Y().fill(yFill);
......@@ -916,7 +927,12 @@ void DecLib::xCreateUnavailablePicture( const PPS *pps, const int iUnavailableP
cFillPic->interLayerRefPicFlag = interLayerRefPicFlag;
cFillPic->longTerm = longTermFlag;
cFillPic->slices[0]->setPOC(iUnavailablePoc);
xUpdatePreviousTid0POC(cFillPic->slices[0]);
cFillPic->poc = iUnavailablePoc;
if( (cFillPic->slices[0]->getTLayer() == 0) && (cFillPic->slices[0]->getNalUnitType() != NAL_UNIT_CODED_SLICE_RASL) && (cFillPic->slices[0]->getNalUnitType() != NAL_UNIT_CODED_SLICE_RADL) )
{
m_prevTid0POC = cFillPic->slices[0]->getPOC();
}
cFillPic->reconstructed = true;
cFillPic->neededForOutput = false;
// picture header is not derived for generated reference picture
......@@ -955,6 +971,11 @@ void DecLib::checkLayerIdIncludedInCvss()
for (auto pic = m_accessUnitPicInfo.begin(); pic != m_accessUnitPicInfo.end(); pic++)
{
bool layerIdFind;
if ( m_firstAccessUnitPicInfo.size() == 0 )
{
msg( NOTICE, "Note: checkIncludedInFirstAu(), m_firstAccessUnitPicInfo.size() is 0.\n");
continue;
}
for (auto picFirst = m_firstAccessUnitPicInfo.begin(); picFirst != m_firstAccessUnitPicInfo.end(); picFirst++)
{
layerIdFind = pic->m_nuhLayerId == picFirst->m_nuhLayerId ? true : false;
......@@ -2086,6 +2107,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
m_accessUnitNoOutputPriorPicFlags.push_back(m_apcSlicePilot->getNoOutputOfPriorPicsFlag());
}
if (m_picHeader.getGdrPicFlag())
{
m_prevGDRInSameLayerRecoveryPOC[nalu.m_nuhLayerId] = m_picHeader.getRecoveryPocCnt();
}
PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId());
CHECK(pps == 0, "No PPS present");
SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
......@@ -2282,10 +2308,12 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
// Skip pictures due to random access
if (isRandomAccessSkipPicture(iSkipFrame, iPOCLastDisplay, pps->getMixedNaluTypesInPicFlag()))
if (isRandomAccessSkipPicture(iSkipFrame, iPOCLastDisplay, pps->getMixedNaluTypesInPicFlag(), nalu.m_nuhLayerId))
{
m_prevSliceSkipped = true;
m_skippedPOC = m_apcSlicePilot->getPOC();
m_skippedLayerID = nalu.m_nuhLayerId;
// reset variables for bitstream conformance tests
resetAccessUnitNals();
resetAccessUnitApsNals();
......@@ -2335,7 +2363,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
{
if (m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex) == 0)
{
xCreateUnavailablePicture( m_apcSlicePilot->getPPS(), lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getPic()->temporalId, m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL0()->isInterLayerRefPic( refPicIndex ) );
xCreateUnavailablePicture( pps, lostPoc, m_apcSlicePilot->getRPL0()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getTLayer(), m_apcSlicePilot->getNalUnitLayerId(), m_apcSlicePilot->getRPL0()->isInterLayerRefPic( refPicIndex ) );
}
}
else
......@@ -2956,6 +2984,11 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
case NAL_UNIT_SUFFIX_SEI:
if (m_pcPic)
{
if ( m_prevSliceSkipped )
{
msg( NOTICE, "Note: received suffix SEI but current picture is skipped.\n");
return false;
}
m_pictureSeiNalus.push_back(new InputNALUnit(nalu));
m_accessUnitSeiTids.push_back(nalu.m_temporalId);
const SPS *sps = m_parameterSetManager.getActiveSPS();
......@@ -2987,6 +3020,7 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
m_associatedIRAPType[nalu.m_nuhLayerId] = NAL_UNIT_INVALID;
m_pocCRA[nalu.m_nuhLayerId] = -MAX_INT;
m_prevGDRInSameLayerPOC[nalu.m_nuhLayerId] = -MAX_INT;
m_prevGDRInSameLayerRecoveryPOC[nalu.m_nuhLayerId] = -MAX_INT;
std::fill_n(m_prevGDRSubpicPOC[nalu.m_nuhLayerId], MAX_NUM_SUB_PICS, -MAX_INT);
std::fill_n(m_prevIRAPSubpicPOC[nalu.m_nuhLayerId], MAX_NUM_SUB_PICS, -MAX_INT);
memset(m_prevIRAPSubpicDecOrderNo[nalu.m_nuhLayerId], 0, sizeof(int)*MAX_NUM_SUB_PICS);
......@@ -3055,11 +3089,22 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
* equal to or greater than the random access point POC is attempted. For non IDR/CRA/BLA random
* access point there is no guarantee that the decoder will not crash.
*/
bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay, bool mixedNaluInPicFlag )
bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay, bool mixedNaluInPicFlag, uint32_t layerId )
{
if( (iSkipFrame > 0) &&
(m_apcSlicePilot->getFirstCtuRsAddrInSlice() == 0 && layerId == 0) &&
(m_skippedPOC != MAX_INT) && (m_skippedLayerID != MAX_INT))
{
// When skipFrame count greater than 0, and current frame is not the first frame of sequence, decrement skipFrame count.
// If skipFrame count is still greater than 0, the current frame will be skipped.
iSkipFrame--;
}
if (iSkipFrame)
{
iSkipFrame--; // decrement the counter
m_maxDecSubPicIdx = 0;
m_maxDecSliceAddrInSubPic = -1;
return true;
}
else if ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP )
......@@ -3068,7 +3113,7 @@ bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay, b
}
else if (m_pocRandomAccess == MAX_INT) // start of random access point, m_pocRandomAccess has not been set yet.
{
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR && m_apcSlicePilot->getPicHeader()->getRecoveryPocCnt() == 0 ) )
if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR )
{
// set the POC random access since we need to skip the reordered pictures in the case of CRA/CRANT/BLA/BLANT.
m_pocRandomAccess = m_apcSlicePilot->getPOC();
......@@ -3077,9 +3122,12 @@ bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay, b
{
if(!m_warningMessageSkipPicture)
{
msg( WARNING, "\nWarning: this is not a valid random access point and the data is discarded until the first CRA picture");
msg( WARNING, "Warning: This is not a valid random access point and the data is discarded until the first CRA or GDR picture\n");
m_warningMessageSkipPicture = true;
}
iSkipFrame--;
m_maxDecSubPicIdx = 0;
m_maxDecSliceAddrInSubPic = -1;
return true;
}
}
......@@ -3089,6 +3137,9 @@ bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay, b
mixedNaluInPicFlag))
{
iPOCLastDisplay++;
iSkipFrame--;
m_maxDecSubPicIdx = 0;
m_maxDecSliceAddrInSubPic = -1;
return true;
}
// if we reach here, then the picture is not skipped.
......
......@@ -73,6 +73,7 @@ private:
GeneralHrdParams m_prevGeneralHrdParams;
int m_prevGDRInSameLayerPOC[MAX_VPS_LAYERS]; ///< POC number of the latest GDR picture
int m_prevGDRInSameLayerRecoveryPOC[MAX_VPS_LAYERS]; ///< Recovery POC number of the latest GDR picture
NalUnitType m_associatedIRAPType[MAX_VPS_LAYERS]; ///< NAL unit type of the previous IRAP picture
int m_pocCRA[MAX_VPS_LAYERS]; ///< POC number of the previous CRA picture
int m_associatedIRAPDecodingOrderNumber[MAX_VPS_LAYERS]; ///< Decoding order number of the previous IRAP picture
......@@ -119,7 +120,7 @@ private:
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
CacheModel m_cacheModel;
#endif
bool isRandomAccessSkipPicture(int& iSkipFrame, int& iPOCLastDisplay, bool mixedNaluInPicFlag);
bool isRandomAccessSkipPicture(int& iSkipFrame, int& iPOCLastDisplay, bool mixedNaluInPicFlag, uint32_t layerId);
Picture* m_pcPic;
uint32_t m_uiSliceSegmentIdx;
uint32_t m_prevLayerID;
......@@ -133,6 +134,7 @@ private:
bool m_accessUnitEos[MAX_VPS_LAYERS];
bool m_prevSliceSkipped;
int m_skippedPOC;
uint32_t m_skippedLayerID;
int m_lastPOCNoOutputPriorPics;
bool m_isNoOutputPriorPics;
bool m_lastNoOutputBeforeRecoveryFlag[MAX_VPS_LAYERS]; //value of variable NoOutputBeforeRecoveryFlag of the assocated CRA/GDR pic
......@@ -228,6 +230,7 @@ public:
void updateAssociatedIRAP();
void updatePrevGDRInSameLayer();
void updatePrevIRAPAndGDRSubpic();
bool getGDRRecoveryPocReached() { return ( m_pcPic->getPOC() >= m_prevGDRInSameLayerPOC[m_pcPic->layerId] + m_prevGDRInSameLayerRecoveryPOC[m_pcPic->layerId] ); }
#if JVET_S0078_NOOUTPUTPRIORPICFLAG
bool getAudIrapOrGdrAuFlag() const { return m_audIrapOrGdrAuFlag; }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment