📄 extractor.cpp
字号:
Extractor::xSetParameters()
{
RNOK( xGetExtParameters() );
UInt uiLayer, uiLevel, uiFGSLayer;
UInt uiExtLayer = m_pcExtractorParameter->getLayer();
UInt uiExtLevel = m_pcExtractorParameter->getLevel();
//JVT-T054{
Bool bQuit = false;
//JVT-T054}
//=========== clear all ===========
for( uiLayer = 0; uiLayer < MAX_LAYERS; uiLayer++ )
for( uiLevel = 0; uiLevel <= MAX_DSTAGES; uiLevel++ )
{
m_aadTargetSNRLayer[uiLayer][uiLevel] = -1;
m_aadTargetSNRLayerNoUse[uiLayer][uiLevel] = -1;
}
//===== get and set required base layer packets ======
Double dRemainingBytes = m_pcExtractorParameter->getTargetRate();
RNOK( GetAndCheckBaseLayerPackets( dRemainingBytes ) );
if( dRemainingBytes < 0 )
return Err::m_nOK;
//===== set maximum possible bytes for included layers ======
for( uiLayer = 0; uiLayer < uiExtLayer; uiLayer++ )
{
for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
{
for( uiFGSLayer = 1; uiFGSLayer < MAX_QUALITY_LEVELS; uiFGSLayer++ )
{
Int64 i64NALUBytes = m_cScalableStreamDescription.getNALUBytes( uiLayer, uiLevel, uiFGSLayer );
if( (Double)i64NALUBytes <= dRemainingBytes )
{
dRemainingBytes -= (Double)i64NALUBytes;
m_aadTargetSNRLayer[uiLayer][uiLevel] = (Double)uiFGSLayer;
m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
}
else
{
//JVT-T054{
dRemainingBytes -= (Double)i64NALUBytes;
m_aadTargetSNRLayer[uiLayer][uiLevel] = (Double)uiFGSLayer;
m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
bQuit = true;
//JVT-T054}
}
}
}
}
//JVT-T054{
if(bQuit)
{
m_uiTruncateLayer = uiExtLayer;
m_uiTruncateLevel = uiExtLevel;
m_uiTruncateFGSLayer = m_pcExtractorParameter->getMaxFGSLayerKept();
//Then reset all above scalable layers' bitrate within the same layerId
for( UInt uiTL = 0; uiTL < MAX_TEMP_LEVELS; uiTL++ )
for( UInt uiQL = 1; uiQL < MAX_QUALITY_LEVELS; uiQL++ )
m_aaadSingleBitrate[uiExtLayer][uiTL][uiQL] = 0;
return Err::m_nOK;
}
//JVT-T054}
//===== set FGS layer for current layer =====
for( uiFGSLayer = 1; uiFGSLayer < MAX_QUALITY_LEVELS; uiFGSLayer++ )
{
Int64 i64FGSLayerBytes = 0;
for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
{
i64FGSLayerBytes += m_cScalableStreamDescription.getNALUBytes( uiExtLayer, uiLevel, uiFGSLayer );
}
if( (Double)i64FGSLayerBytes <= dRemainingBytes )
{
dRemainingBytes -= (Double)i64FGSLayerBytes;
for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
{
m_aadTargetSNRLayer[uiExtLayer][uiLevel] = (Double)uiFGSLayer;
m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
}
}
else
{
//JVT-T054{
m_uiTruncateLayer = uiExtLayer;
m_uiTruncateLevel = uiExtLevel;
m_uiTruncateFGSLayer = uiFGSLayer;
for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
{
i64FGSLayerBytes = m_cScalableStreamDescription.getNALUBytes( uiExtLayer, uiLevel, uiFGSLayer );
if( (Double)i64FGSLayerBytes <= dRemainingBytes )
{
dRemainingBytes -= (Double)i64FGSLayerBytes;
m_aadTargetSNRLayer[uiExtLayer][uiLevel] = (Double)uiFGSLayer;
m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
}
else
{
UInt uiTL;
m_uiTruncateLevel = uiLevel;
//Then reset all above layers' bitrate
for( uiTL = uiLevel; uiTL < MAX_TEMP_LEVELS; uiTL++ )
m_aaadSingleBitrate[uiExtLayer][uiTL][uiFGSLayer] = 0;
for( uiTL = 0; uiTL < MAX_TEMP_LEVELS; uiTL++ )
for( UInt uiFGS = m_uiTruncateFGSLayer+1; uiFGS < MAX_QUALITY_LEVELS; uiFGS++ )
m_aaadSingleBitrate[uiExtLayer][uiTL][uiFGS] = 0;
return Err::m_nOK;
}
}
}
}
//===== set maximum possible bytes for no use frames in included layers, for SIP ======
for( uiLayer = 0; uiLayer < uiExtLayer; uiLayer++ )
{
for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
{
for( uiFGSLayer = 0; uiFGSLayer < MAX_QUALITY_LEVELS; uiFGSLayer++ )
{
Int64 i64NALUBytes = m_cScalableStreamDescription.getNALUBytesNoUse( uiLayer, uiLevel, uiFGSLayer );
if( (Double)i64NALUBytes <= dRemainingBytes )
{
dRemainingBytes -= (Double)i64NALUBytes;
m_aadTargetSNRLayerNoUse[uiLayer][uiLevel] = (Double)uiFGSLayer;
}
else
{
//====== set fractional FGS layer and exit =====
Double dFGSLayer = dRemainingBytes / (Double)i64NALUBytes;
m_aadTargetSNRLayerNoUse[uiLayer][uiLevel] += dFGSLayer;
return Err::m_nOK;
}
}
}
}
m_uiTruncateLayer = uiExtLayer;
m_uiTruncateLevel = uiExtLevel;
m_uiTruncateFGSLayer = MAX_QUALITY_LEVELS - 1;
WARNING( dRemainingBytes>0.0, "Bit-rate overflow for extraction/inclusion point" );
return Err::m_nOK;
}
ErrVal
Extractor::xReCalculateBr()
{
UInt uiLayer, uiTLevel, uiQLevel;
UInt uiExtLayer = m_pcExtractorParameter->getLayer();
UInt uiExtLevel = m_pcExtractorParameter->getLevel();
for( UInt uiScalableLayer = 0; uiScalableLayer <= m_uiScalableNumLayersMinus1; uiScalableLayer++ )
{
uiLayer = m_auiDependencyId[uiScalableLayer];
uiTLevel = m_auiTempLevel[uiScalableLayer];
uiQLevel = m_auiQualityLevel[uiScalableLayer];
if( uiLayer > uiExtLayer || uiTLevel > uiExtLevel || uiQLevel > m_aadTargetSNRLayer[uiLayer][uiTLevel] ) // scalable layer to be discarded
{
m_adTotalBitrate[uiScalableLayer] = 0;
}
else if( uiLayer == 0 && uiQLevel <= m_aadTargetSNRLayer[uiLayer][uiTLevel] ) // all contained layers remain
{
; // remain unchanged
}
else // dependent layer changes, re-calculate
{
m_adTotalBitrate[uiScalableLayer] = m_aaadSingleBitrate[uiLayer][uiTLevel][uiQLevel]; //initialize
std::list<UInt>::iterator iIter = m_acDepLayerList[uiScalableLayer].begin();
std::list<UInt>::iterator iIterEnd = m_acDepLayerList[uiScalableLayer].end();
while ( iIter != iIterEnd )
{
UInt uiScalableLayerDep = (*iIter);
UInt uiLayerDep = m_auiDependencyId[uiScalableLayerDep];
UInt uiLevelDep = m_auiTempLevel[uiScalableLayerDep];
UInt uiQLDep = m_auiQualityLevel[uiScalableLayerDep];
Double dFactor = m_cScalableStreamDescription.getNumPictures( uiExtLayer, uiLevelDep )
/m_cScalableStreamDescription.getFrameRate(uiExtLayer, uiLevelDep )
*m_cScalableStreamDescription.getFrameRate(uiExtLayer, uiTLevel )
/m_cScalableStreamDescription.getNumPictures( uiExtLayer, uiTLevel ); //this factor represents the factor of different TL to current TL
m_adTotalBitrate[uiScalableLayer] += m_aaadSingleBitrate[uiLayerDep][uiLevelDep][uiQLDep] * dFactor;
iIter++;
}
}
}
return Err::m_nOK;
}
Void
Extractor::xMakeDepLayerList( UInt uiScalableLayerId, std::list<UInt>& DepLayerList )
{
//This function add all dependent layersId for "uiScalableLayerId" into list "DepLayerList"
//First, push the current layer into list
if( DepLayerList.size()==0 || std::find(DepLayerList.begin(), DepLayerList.end(), uiScalableLayerId) == DepLayerList.end() ) //doesn't exist
DepLayerList.push_back( uiScalableLayerId );
if( m_acDepLayerList[uiScalableLayerId].size() == 0 )
return;
else
{
std::list<UInt>::iterator iIterBgn = m_acDepLayerList[uiScalableLayerId].begin();
std::list<UInt>::iterator iIterEnd = m_acDepLayerList[uiScalableLayerId].end();
while( iIterBgn != iIterEnd )
{
UInt uiLayerId = (*iIterBgn);
if( std::find(DepLayerList.begin(), DepLayerList.end(), uiLayerId ) == DepLayerList.end() ) //doesn't exist
DepLayerList.push_back( uiLayerId );
xMakeDepLayerList( uiLayerId, DepLayerList );
iIterBgn++;
}
}
}
ErrVal
Extractor::go()
{
RNOK ( xPrimaryAnalyse());
// ROI ICU/ETRI DS
xSetROIParameters();
AllocateAndInitializeDatas();
if( m_pcExtractorParameter->minusRSpecified() )
{
xExtractMaxRate( m_pcExtractorParameter->getMaximumRate(), m_pcExtractorParameter->getDontTruncQLayer(), m_pcExtractorParameter->minusRPercentageMode() );
return Err::m_nOK;
}
RNOK ( xAnalyse() );
ROTRS( m_pcExtractorParameter->getAnalysisOnly(), Err::m_nOK );
if( m_pcExtractionTraceFile ) // HS: packet trace
{
RNOK( xExtractTrace() ); // HS: packet trace
}
else if( m_pcExtractorParameter->getExtractionList().empty() )
{
RNOK( xExtractLayerLevel() );
}
else
{
//if there is R/D information in the input stream
//with or without dead substream
if(m_bInInputStreamQL)
{
go_QL();
return Err::m_nOK;
}
//S051{
if(m_bUseSIP)
{
go_SIP();
return Err::m_nOK;
}
//S051}
//default case: there is no dead substream, nor R/D information
//in the input stream
//}}Quality level estimation and modified truncation- JVTO044 and m12007
RNOK( xSetParameters() );
RNOK( xExtractPoints() );
}
return Err::m_nOK;
}
ErrVal
Extractor::xExtractMaxRate( Double dMaxRate, Bool bDontTruncQLayer, Bool bPercentageMode )
{
Bool bQualityLayerPresent = false;
UInt uiLayer = MSYS_UINT_MAX;
Double dFrameRate = 0.0;
UInt uiDiffRate = 0;
UInt auiQLRate[MAX_QLAYERS+2];
//----- get layer number -----
for( Int i = MAX_LAYERS - 1; i >= 0; i--)
{
if( m_auiNbImages[i] > 0 )
{
uiLayer = (UInt)i;
break;
}
}
ROT( uiLayer == MSYS_UINT_MAX );
//----- analyze -----
RNOK( xAnalyse( uiLayer, dFrameRate, bQualityLayerPresent, auiQLRate, bDontTruncQLayer ) );
ROF ( dFrameRate > 0 );
ROF ( auiQLRate[0] > 0 );
//----- get parameters -----
Double dScale = 1000.0 / 8.0 * (Double)m_auiNbImages[uiLayer] / dFrameRate;
UInt uiTGRate;
if( bPercentageMode )
{
uiTGRate = auiQLRate[MAX_QLAYERS+1] + (UInt)floor( ( auiQLRate[0] - auiQLRate[MAX_QLAYERS+1] ) * dMaxRate );
}
else
{
uiTGRate = (UInt)floor( dScale * dMaxRate );
}
Int iExtPID = MAX_QLAYERS;
UInt uiInLRate = 0;
if( uiTGRate > auiQLRate[MAX_QLAYERS+1] )
{
for( Int iQId = MAX_QLAYERS; iQId >= 0; iQId-- )
{
if( uiTGRate < auiQLRate[iQId] )
{
iExtPID = iQId;
uiInLRate = uiTGRate - auiQLRate[iQId+1];
break;
}
else if( iQId == 0 )
{
iExtPID = -1;
uiInLRate = uiTGRate - auiQLRate[0];
}
}
}
else
{
uiDiffRate = uiTGRate - auiQLRate[MAX_QLAYERS+1];
}
if( bDontTruncQLayer )
{
uiDiffRate = uiInLRate;
uiInLRate = 0;
}
//---- extraction ----
RNOK( xExtract( uiLayer, bQualityLayerPresent, iExtPID, uiInLRate, bDontTruncQLayer ) );
UInt uiOutRate = uiTGRate - uiInLRate - uiDiffRate;
#if 1
printf("minimum rate = %8.2lf kbit/s\n", (Double)auiQLRate[MAX_QLAYERS+1] / dScale );
printf("maximum rate = %8.2lf kbit/s\n", (Double)auiQLRate[ 0] / dScale );
printf("\n");
if( iExtPID < 0 )
{
iExtPID = 0;
}
printf(" low limit = %8.2lf kbit/s\n", (Double)auiQLRate[ iExtPID+1] / dScale );
printf(" high limit = %8.2lf kbit/s\n", (Double)auiQLRate[ iExtPID ] / dScale );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -