Commit 07afae5e authored by Karsten Suehring's avatar Karsten Suehring Committed by Xiang Li

Refactor/Bugfix: VPS handling

- create a "dummy" VPS with ID 0 on first access in ParameterSetManager
- actually use the "dummy" VPS
- improve DecLib::m_vps handling (may still fail if multiple VPSs are in the bitstream)
parent f0dbf4b8
......@@ -49,6 +49,26 @@ ParameterSetManager::~ParameterSetManager()
{
}
VPS* ParameterSetManager::getVPS( int vpsId )
{
if ( vpsId != 0)
{
return m_vpsMap.getPS( vpsId );
}
else
{
// VPS Id zero contains inferred values only. Allocate (with defaults) on first access
VPS *vps = m_vpsMap.getPS (0);
if (vps == nullptr)
{
m_vpsMap.allocatePS(0);
vps = m_vpsMap.getPS( 0 );
vps->deriveOutputLayerSets();
}
return m_vpsMap.getPS( 0 );
}
};
// activate a PPS and depending on isIRAP parameter also SPS
// returns true, if activation is successful
bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
......@@ -63,31 +83,22 @@ bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
if (sps)
{
int vpsId = sps->getVPSId();
if(vpsId != 0)
VPS *vps = m_vpsMap.getPS(vpsId);
if(vps)
{
VPS *vps = m_vpsMap.getPS(vpsId);
if(vps)
{
m_activeVPSId = vpsId;
m_vpsMap.setActive(vpsId);
}
else
{
msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing VPS." );
}
m_activeVPSId = vpsId;
m_vpsMap.setActive(vpsId);
}
else
{
m_vpsMap.clear();
m_vpsMap.allocatePS(0);
m_activeVPSId = 0;
m_vpsMap.setActive(0);
msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing VPS." );
}
m_spsMap.clear();
m_spsMap.clearActive();
m_spsMap.setActive(spsId);
m_activeSPSId = spsId;
m_ppsMap.clear();
m_ppsMap.clearActive();
m_ppsMap.setActive(ppsId);
return true;
}
......
......@@ -216,7 +216,7 @@ public:
}
void setActive(int psId) { m_activePsId.push_back(psId); }
void clear() { m_activePsId.clear(); }
void clearActive() { m_activePsId.clear(); }
private:
std::map<int,MapData<T> > m_paramsetMap;
......@@ -235,7 +235,7 @@ public:
// store video parameter set and take ownership of it
// warning: vps object cannot be used after storing (repeated parameter sets are directly deleted)
void storeVPS(VPS *vps, const std::vector<uint8_t> &naluData) { m_vpsMap.storePS(vps->getVPSId(), vps, &naluData); }
VPS* getVPS( int vpsId ) { return m_vpsMap.getPS( vpsId ); };
VPS* getVPS( int vpsId );
// store sequence parameter set and take ownership of it
// warning: sps object cannot be used after storing (repeated parameter sets are directly deleted)
......
......@@ -2431,23 +2431,23 @@ unsigned Slice::getMinPictureDistance() const
// ------------------------------------------------------------------------------------------------
VPS::VPS()
: m_VPSId(0)
, m_uiMaxLayers(1)
, m_vpsMaxSubLayers(1)
, m_maxLayers(1)
, m_vpsMaxSubLayers(7)
, m_vpsAllLayersSameNumSubLayersFlag (true)
, m_vpsAllIndependentLayersFlag(true)
, m_vpsEachLayerIsAnOlsFlag (1)
, m_vpsOlsModeIdc (0)
, m_vpsNumOutputLayerSets (1)
, m_vpsNumPtls (1)
, m_vpsExtensionFlag()
, m_vpsExtensionFlag(false)
, m_vpsGeneralHrdParamsPresentFlag(false)
, m_vpsSublayerCpbParamsPresentFlag(false)
, m_numOlsHrdParamsMinus1(0)
, m_totalNumOLSs( 0 )
, m_totalNumOLSs( 1 )
, m_numMultiLayeredOlss( 0 )
, m_numDpbParams( 0 )
, m_sublayerDpbParamsPresentFlag( false )
, m_targetOlsIdx( -1 )
, m_targetOlsIdx( 0 )
{
for (int i = 0; i < MAX_VPS_SUBLAYERS; i++)
{
......@@ -2472,10 +2472,14 @@ VPS::VPS()
{
m_vpsOlsOutputLayerFlag[i][j] = 0;
}
if(i == 0)
if (i == 0)
{
m_ptPresentFlag[i] = 1;
}
else
{
m_ptPresentFlag[i] = 0;
}
m_ptlMaxTemporalId[i] = m_vpsMaxSubLayers - 1;
m_olsPtlIdx[i] = 0;
m_hrdMaxTid[i] = m_vpsMaxSubLayers - 1;
......@@ -2489,13 +2493,13 @@ VPS::~VPS()
void VPS::deriveOutputLayerSets()
{
if( m_uiMaxLayers == 1 )
if( m_maxLayers == 1 )
{
m_totalNumOLSs = 1;
}
else if( m_vpsEachLayerIsAnOlsFlag || m_vpsOlsModeIdc < 2 )
{
m_totalNumOLSs = m_uiMaxLayers;
m_totalNumOLSs = m_maxLayers;
}
else if( m_vpsOlsModeIdc == 2 )
{
......@@ -2506,25 +2510,25 @@ void VPS::deriveOutputLayerSets()
m_olsDpbPicSize.resize( m_totalNumOLSs, Size(0, 0) );
m_numOutputLayersInOls.resize( m_totalNumOLSs );
m_numLayersInOls.resize( m_totalNumOLSs );
m_outputLayerIdInOls.resize( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
m_numSubLayersInLayerInOLS.resize( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
m_layerIdInOls.resize( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
m_outputLayerIdInOls.resize( m_totalNumOLSs, std::vector<int>( m_maxLayers, NOT_VALID ) );
m_numSubLayersInLayerInOLS.resize( m_totalNumOLSs, std::vector<int>( m_maxLayers, NOT_VALID ) );
m_layerIdInOls.resize( m_totalNumOLSs, std::vector<int>( m_maxLayers, NOT_VALID ) );
m_olsDpbChromaFormatIdc.resize(m_totalNumOLSs);
m_olsDpbBitDepthMinus8.resize(m_totalNumOLSs);
std::vector<int> numRefLayers( m_uiMaxLayers );
std::vector<std::vector<int>> outputLayerIdx( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
std::vector<std::vector<int>> layerIncludedInOlsFlag( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, 0 ) );
std::vector<std::vector<int>> dependencyFlag( m_uiMaxLayers, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
std::vector<std::vector<int>> refLayerIdx( m_uiMaxLayers, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
std::vector<int> layerUsedAsRefLayerFlag( m_uiMaxLayers, 0 );
std::vector<int> layerUsedAsOutputLayerFlag( m_uiMaxLayers, NOT_VALID );
std::vector<int> numRefLayers( m_maxLayers );
std::vector<std::vector<int>> outputLayerIdx( m_totalNumOLSs, std::vector<int>( m_maxLayers, NOT_VALID ) );
std::vector<std::vector<int>> layerIncludedInOlsFlag( m_totalNumOLSs, std::vector<int>( m_maxLayers, 0 ) );
std::vector<std::vector<int>> dependencyFlag( m_maxLayers, std::vector<int>( m_maxLayers, NOT_VALID ) );
std::vector<std::vector<int>> refLayerIdx( m_maxLayers, std::vector<int>( m_maxLayers, NOT_VALID ) );
std::vector<int> layerUsedAsRefLayerFlag( m_maxLayers, 0 );
std::vector<int> layerUsedAsOutputLayerFlag( m_maxLayers, NOT_VALID );
for( int i = 0; i < m_uiMaxLayers; i++ )
for( int i = 0; i < m_maxLayers; i++ )
{
int r = 0;
for( int j = 0; j < m_uiMaxLayers; j++ )
for( int j = 0; j < m_maxLayers; j++ )
{
dependencyFlag[i][j] = m_vpsDirectRefLayerFlag[i][j];
......@@ -2553,7 +2557,7 @@ void VPS::deriveOutputLayerSets()
m_outputLayerIdInOls[0][0] = m_vpsLayerId[0];
m_numSubLayersInLayerInOLS[0][0] = m_vpsMaxSubLayers;
layerUsedAsOutputLayerFlag[0] = 1;
for (int i = 1; i < m_uiMaxLayers; i++)
for (int i = 1; i < m_maxLayers; i++)
{
if (m_vpsEachLayerIsAnOlsFlag || m_vpsOlsModeIdc < 2)
{
......@@ -2590,12 +2594,12 @@ void VPS::deriveOutputLayerSets()
else if( m_vpsOlsModeIdc == 2 )
{
int j = 0;
for( j = 0; j < m_uiMaxLayers; j++ )
for( j = 0; j < m_maxLayers; j++ )
{
m_numSubLayersInLayerInOLS[i][j] = 0;
}
j = 0;
for( int k = 0; k < m_uiMaxLayers; k++ )
for( int k = 0; k < m_maxLayers; k++ )
{
if( m_vpsOlsOutputLayerFlag[i][k] )
{
......@@ -2622,7 +2626,7 @@ void VPS::deriveOutputLayerSets()
}
}
}
for (int i = 0; i < m_uiMaxLayers; i++)
for (int i = 0; i < m_maxLayers; i++)
{
CHECK(layerUsedAsRefLayerFlag[i] == 0 && layerUsedAsOutputLayerFlag[i] == 0, "There shall be no layer that is neither an output layer nor a direct reference layer");
}
......@@ -2648,7 +2652,7 @@ void VPS::deriveOutputLayerSets()
else if( m_vpsOlsModeIdc == 2 )
{
int j = 0;
for( int k = 0; k < m_uiMaxLayers; k++ )
for( int k = 0; k < m_maxLayers; k++ )
{
if( layerIncludedInOlsFlag[i][k] )
{
......@@ -2699,7 +2703,7 @@ void VPS::checkVPS()
void VPS::deriveTargetOutputLayerSet( int targetOlsIdx )
{
m_targetOlsIdx = targetOlsIdx < 0 ? m_uiMaxLayers - 1 : targetOlsIdx;
m_targetOlsIdx = targetOlsIdx < 0 ? m_maxLayers - 1 : targetOlsIdx;
m_targetOutputLayerIdSet.clear();
m_targetLayerIdSet.clear();
......
......@@ -1037,7 +1037,7 @@ class VPS
{
private:
int m_VPSId;
uint32_t m_uiMaxLayers;
uint32_t m_maxLayers;
uint32_t m_vpsMaxSubLayers;
uint32_t m_vpsLayerId[MAX_VPS_LAYERS];
......@@ -1104,8 +1104,8 @@ public:
int getVPSId() const { return m_VPSId; }
void setVPSId(int i) { m_VPSId = i; }
uint32_t getMaxLayers() const { return m_uiMaxLayers; }
void setMaxLayers(uint32_t l) { m_uiMaxLayers = l; }
uint32_t getMaxLayers() const { return m_maxLayers; }
void setMaxLayers(uint32_t l) { m_maxLayers = l; }
uint32_t getMaxSubLayers() const { return m_vpsMaxSubLayers; }
void setMaxSubLayers(uint32_t value) { m_vpsMaxSubLayers = value; }
......
......@@ -1511,12 +1511,13 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
APS** apss = m_parameterSetManager.getAPSs();
memset(apss, 0, sizeof(*apss) * ALF_CTB_MAX_NUM_APS);
const PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId()); // this is a temporary PPS object. Do not store this value
CHECK(pps == 0, "No PPS present");
CHECK(pps == 0, "Referred to PPS not present");
const SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId()); // this is a temporary SPS object. Do not store this value
CHECK(sps == 0, "No SPS present");
CHECK(sps == 0, "Referred to SPS not present");
const VPS *vps = sps->getVPSId() ? m_parameterSetManager.getVPS( sps->getVPSId() ) : nullptr;
const VPS *vps = m_parameterSetManager.getVPS( sps->getVPSId() );
CHECK(vps == 0, "Referred to VPS not present");
if( nullptr != pps->pcv )
{
......@@ -1531,8 +1532,10 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
THROW("Parameter set activation failed!");
}
// update the stored VPS to the actually referred to VPS
m_vps = m_parameterSetManager.getVPS(sps->getVPSId());
m_parameterSetManager.getApsMap()->clear();
m_parameterSetManager.getApsMap()->clearActive();
for (int i = 0; i < ALF_CTB_MAX_NUM_APS; i++)
{
APS* aps = m_parameterSetManager.getAPS(i, ALF_APS);
......@@ -2861,17 +2864,23 @@ void DecLib::updatePrevIRAPAndGDRSubpic()
void DecLib::xDecodeVPS( InputNALUnit& nalu )
{
m_vps = new VPS();
VPS* vps = new VPS();
m_HLSReader.setBitstream( &nalu.getBitstream() );
CHECK( nalu.m_temporalId, "The value of TemporalId of VPS NAL units shall be equal to 0" );
m_HLSReader.parseVPS( m_vps );
m_HLSReader.parseVPS( vps );
// storeVPS may directly delete the new VPS in case it is a repetition. Need to retrieve proper initialized memory back
int vpsID = m_vps->getVPSId();
m_parameterSetManager.storeVPS( m_vps, nalu.getBitstream().getFifo());
m_vps = m_parameterSetManager.getVPS(vpsID);
m_parameterSetManager.storeVPS( vps, nalu.getBitstream().getFifo());
if (m_vps==nullptr)
{
// m_vps is used for conformance checks. Unless a VPS is referred to, just set the first one we received
// repeated parameter sets may be deleted, set a valid VPS pointer back from parameter set manager
m_vps = m_parameterSetManager.getVPS(vpsID);
}
}
void DecLib::xDecodeDCI(InputNALUnit& nalu)
......
......@@ -886,7 +886,7 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
memset(cs.slice->getAlfAPSs(), 0, sizeof(*cs.slice->getAlfAPSs())*ALF_CTB_MAX_NUM_APS);
m_apsIdStart = ALF_CTB_MAX_NUM_APS;
m_apsMap->clear();
m_apsMap->clearActive();
for (int i = 0; i < ALF_CTB_MAX_NUM_APS; i++)
{
APS* alfAPS = m_apsMap->getPS((i << NUM_APS_TYPE_LEN) + ALF_APS);
......
......@@ -3100,7 +3100,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
m_pcALF->setApsIdStart( ALF_CTB_MAX_NUM_APS );
ParameterSetMap<APS>* apsMap = m_pcEncLib->getApsMap();
apsMap->clear();
apsMap->clearActive();
for( int apsId = 0; apsId < ALF_CTB_MAX_NUM_APS; apsId++ )
{
......
Markdown is supported
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