?? qualitylevelassigner.cpp
字號:
fclose( pFile );
printf("\n");
return Err::m_nOK;
}
ErrVal
QualityLevelAssigner::xDetermineQualityIDs()
{
printf( "determine quality levels ..." );
//===== determine minimum and maximum quality level id's =====
UInt auiMinQualityLevel[MAX_LAYERS];
UInt auiMaxQualityLevel[MAX_LAYERS];
{
for( Int iLayer = (Int)m_uiNumLayers-1; iLayer >= 0; iLayer-- )
{
UInt uiMinQLLayer = ( iLayer == (Int)m_uiNumLayers-1 ? 0 : auiMaxQualityLevel[iLayer+1]+1 );
UInt uiNumQLInLayer = ( 63 - uiMinQLLayer ) / ( iLayer + 1 );
auiMinQualityLevel[iLayer] = uiMinQLLayer;
auiMaxQualityLevel[iLayer] = uiMinQLLayer + uiNumQLInLayer - 1;
}
}
//===== determine optimized quality levels per layer =====
for( UInt uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
{
//----- create quality estimation object -----
QualityLevelEstimation cQualityLevelEstimation;
RNOK( cQualityLevelEstimation.init( m_uiNumLayers, m_auiNumFGSLayers, m_auiNumFrames ) );
//----- initialize with packets -----
{
for( UInt uiFGSLayer = 1; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
for( UInt uiFrame = 0; uiFrame < m_auiNumFrames [uiLayer]; uiFrame ++ )
{
RNOK( cQualityLevelEstimation.addPacket( uiLayer, uiFGSLayer, uiFrame,
m_aaauiPacketSize [uiLayer][uiFGSLayer][uiFrame],
m_aaadDeltaDist [uiLayer][uiFGSLayer][uiFrame] ) );
}
}
//----- determine quality levels -----
RNOK( cQualityLevelEstimation.optimizeQualityLevel( uiLayer, uiLayer, auiMinQualityLevel[uiLayer], auiMaxQualityLevel[uiLayer] ) );
//----- assign quality levels -----
{
for( UInt uiFGSLayer = 0; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
for( UInt uiFrame = 0; uiFrame < m_auiNumFrames [uiLayer]; uiFrame ++ )
{
m_aaauiQualityID[uiLayer][uiFGSLayer][uiFrame] = ( uiFGSLayer ? cQualityLevelEstimation.getQualityLevel( uiLayer, uiFGSLayer, uiFrame ) : 63 );
}
}
}
printf("\n");
return Err::m_nOK;
}
//JVT-S043
ErrVal
QualityLevelAssigner::xDetermineMultiLayerQualityIDs()
{
printf( "determine ML quality levels ..." );
//===== determine minimum and maximum quality level id's =====
UInt uiMinQualityLevel = 0;
UInt uiMaxQualityLevel = 62;
UInt uiLayer;
//----- create quality estimation object -----
QualityLevelEstimation cQualityLevelEstimation;
RNOK( cQualityLevelEstimation.init( m_uiNumLayers, m_auiNumFGSLayers, m_auiNumFrames ) );
//===== determine optimized quality levels per layer =====
for( uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
{
//----- initialize with packets -----
{
for( UInt uiFGSLayer = 1; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
for( UInt uiFrame = 0; uiFrame < m_auiNumFrames [uiLayer]; uiFrame ++ )
{
RNOK( cQualityLevelEstimation.addPacket( uiLayer, uiFGSLayer, uiFrame,
m_aaauiPacketSize [uiLayer][uiFGSLayer][uiFrame],
m_aaadDeltaDist [uiLayer][uiFGSLayer][uiFrame] ) );
}
}
}
//----- determine quality levels -----
RNOK( cQualityLevelEstimation.optimizeQualityLevel( m_uiNumLayers-1, 0, uiMinQualityLevel, uiMaxQualityLevel ) );
for( uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
{
//----- assign quality levels -----
{
for( UInt uiFGSLayer = 0; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
for( UInt uiFrame = 0; uiFrame < m_auiNumFrames [uiLayer]; uiFrame ++ )
{
m_aaauiQualityID[uiLayer][uiFGSLayer][uiFrame] = ( uiFGSLayer ? cQualityLevelEstimation.getQualityLevel( uiLayer, uiFGSLayer, uiFrame ) : 63 );
}
}
}
printf("\n");
return Err::m_nOK;
}
ErrVal
QualityLevelAssigner::xWriteQualityLayerStreamPID()
{
printf( "write stream with quality layer (PID) \"%s\" ...", m_pcParameter->getOutputBitStreamName().c_str() );
BinData* pcBinData = 0;
SEI::SEIMessage* pcScalableSEI = 0;
PacketDescription cPacketDescription;
UInt auiFrameNum[MAX_LAYERS] = { MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX };
//===== init =====
RNOK( m_pcH264AVCPacketAnalyzer->init() );
ReadBitstreamFile* pcReadBitStream = 0;
WriteBitstreamToFile* pcWriteBitStream = 0;
RNOK( ReadBitstreamFile ::create( pcReadBitStream ) );
RNOK( WriteBitstreamToFile::create( pcWriteBitStream ) );
RNOK( pcReadBitStream ->init( m_pcParameter->getInputBitStreamName () ) );
RNOK( pcWriteBitStream->init( m_pcParameter->getOutputBitStreamName () ) );
//===== loop over packets =====
while( true )
{
//----- read packet -----
Bool bEOS = false;
RNOK( pcReadBitStream->extractPacket( pcBinData, bEOS ) );
if( bEOS )
{
//manu.mathew@samsung : memory leak fix
RNOK( pcReadBitStream ->releasePacket ( pcBinData ) );
pcBinData = NULL;
//--
break;
}
//----- get packet description -----
RNOK( m_pcH264AVCPacketAnalyzer->process( pcBinData, cPacketDescription, pcScalableSEI ) );
delete pcScalableSEI; pcScalableSEI = 0;
//----- set packet size -----
while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
{
RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove trailing zeros
}
//----- analyse packets -----
if( cPacketDescription.FGSLayer )
{
pcBinData->data()[1] |= ( m_aaauiQualityID[cPacketDescription.Layer][cPacketDescription.FGSLayer][auiFrameNum[cPacketDescription.Layer]] << 2 );
}
else
{
if( ! cPacketDescription.ParameterSet && cPacketDescription.NalUnitType != NAL_UNIT_SEI &&
! cPacketDescription.FGSLayer )
{
auiFrameNum[cPacketDescription.Layer]++;
}
}
//----- write and delete bin data -----
RNOK( pcWriteBitStream->writePacket ( &m_cBinDataStartCode ) );
RNOK( pcWriteBitStream->writePacket ( pcBinData ) );
RNOK( pcReadBitStream ->releasePacket ( pcBinData ) );
}
//===== uninit =====
RNOK( m_pcH264AVCPacketAnalyzer->uninit() );
RNOK( pcReadBitStream ->uninit () );
RNOK( pcWriteBitStream->uninit () );
RNOK( pcReadBitStream ->destroy () );
RNOK( pcWriteBitStream->destroy () );
printf("\n");
return Err::m_nOK;
}
ErrVal
QualityLevelAssigner::xWriteQualityLayerStreamSEI()
{
printf( "write stream with quality layer (SEI) \"%s\" ...", m_pcParameter->getOutputBitStreamName().c_str() );
UInt uiNumAccessUnits = 0;
UInt uiPrevLayer = 0;
UInt uiPrevLevel = 0;
BinData* pcBinData = 0;
SEI::SEIMessage* pcScalableSEI = 0;
PacketDescription cPacketDescription;
UInt auiFrameNum[MAX_LAYERS] = { MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX };
//===== init =====
RNOK( m_pcH264AVCPacketAnalyzer->init() );
ReadBitstreamFile* pcReadBitStream = 0;
WriteBitstreamToFile* pcWriteBitStream = 0;
RNOK( ReadBitstreamFile ::create( pcReadBitStream ) );
RNOK( WriteBitstreamToFile::create( pcWriteBitStream ) );
RNOK( pcReadBitStream ->init( m_pcParameter->getInputBitStreamName () ) );
RNOK( pcWriteBitStream->init( m_pcParameter->getOutputBitStreamName () ) );
//===== loop over packets =====
while( true )
{
//----- read packet -----
Bool bEOS = false;
RNOK( pcReadBitStream->extractPacket( pcBinData, bEOS ) );
if( bEOS )
{
//manu.mathew@samsung : memory leak fix
RNOK( pcReadBitStream ->releasePacket ( pcBinData ) );
pcBinData = NULL;
//--
break;
}
//----- get packet description -----
RNOK( m_pcH264AVCPacketAnalyzer->process( pcBinData, cPacketDescription, pcScalableSEI ) );
delete pcScalableSEI; pcScalableSEI = 0;
//----- set packet size -----
while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
{
RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove trailing zeros
}
//----- detect first slice data of access unit -----
Bool bNewAccessUnit = ( !cPacketDescription.ParameterSet &&
!cPacketDescription.ApplyToNext &&
cPacketDescription.NalUnitType != NAL_UNIT_SEI &&
cPacketDescription.FGSLayer == 0U );
if( bNewAccessUnit )
{
bNewAccessUnit = ( cPacketDescription.Layer == 0 );
bNewAccessUnit = bNewAccessUnit || ( cPacketDescription.Layer >= uiPrevLayer && cPacketDescription.Level > uiPrevLevel );
bNewAccessUnit = bNewAccessUnit || ( cPacketDescription.Layer == uiPrevLayer && cPacketDescription.Level == uiPrevLevel );
bNewAccessUnit = bNewAccessUnit || ( cPacketDescription.Layer < uiPrevLayer );
}
//----- insert quality layer SEI and increase frame number -----
if( bNewAccessUnit )
{
for( UInt uiLayer = cPacketDescription.Layer; uiLayer < m_uiNumLayers; uiLayer++ )
{
auiFrameNum[uiLayer]++;
xInsertQualityLayerSEI( pcWriteBitStream, uiLayer, auiFrameNum[uiLayer] );
}
uiNumAccessUnits++;
}
//----- write and delete bin data -----
RNOK( pcWriteBitStream->writePacket ( &m_cBinDataStartCode ) );
RNOK( pcWriteBitStream->writePacket ( pcBinData ) );
RNOK( pcReadBitStream ->releasePacket ( pcBinData ) );
//----- update previous layer information -----
uiPrevLayer = cPacketDescription.Layer;
uiPrevLevel = cPacketDescription.Level;
}
//===== uninit =====
RNOK( m_pcH264AVCPacketAnalyzer->uninit() );
RNOK( pcReadBitStream ->uninit () );
RNOK( pcWriteBitStream->uninit () );
RNOK( pcReadBitStream ->destroy () );
RNOK( pcWriteBitStream->destroy () );
printf(" (%d AU's)\n", uiNumAccessUnits );
return Err::m_nOK;
}
ErrVal
QualityLevelAssigner::xInsertQualityLayerSEI( WriteBitstreamToFile* pcWriteBitStream,
UInt uiLayer,
UInt uiFrameNum )
{
//===== init binary data =====
const UInt uiQLSEIMessageBufferSize = 1024;
UChar aucQLSEIMessageBuffer[uiQLSEIMessageBufferSize];
BinData cBinData;
ExtBinDataAccessor cExtBinDataAccessor;
cBinData.reset ();
cBinData.set ( aucQLSEIMessageBuffer, uiQLSEIMessageBufferSize );
cBinData.setMemAccessor ( cExtBinDataAccessor );
//===== create SEI message =====
SEI::QualityLevelSEI* pcQualityLevelSEI;
SEI::MessageList cSEIMessageList;
RNOK( SEI::QualityLevelSEI::create( pcQualityLevelSEI ) );
cSEIMessageList.push_back( pcQualityLevelSEI );
//===== set content of SEI message =====
UInt uiNumLayers;
for( uiNumLayers = 0; uiNumLayers <= m_auiNumFGSLayers[uiLayer] && m_aaauiQualityID [uiLayer][uiNumLayers][uiFrameNum] != MSYS_UINT_MAX; uiNumLayers++ )
{
pcQualityLevelSEI->setQualityLevel ( uiNumLayers, m_aaauiQualityID [uiLayer][uiNumLayers][uiFrameNum] );
pcQualityLevelSEI->setDeltaBytesRateOfLevel ( uiNumLayers, m_aaauiPacketSize [uiLayer][uiNumLayers][uiFrameNum] );
}
pcQualityLevelSEI->setDependencyId ( uiLayer );
pcQualityLevelSEI->setNumLevel ( uiNumLayers );
//===== encode SEI message =====
UInt uiBits = 0;
RNOK( m_pcNalUnitEncoder->initNalUnit ( &cExtBinDataAccessor ) );
RNOK( m_pcNalUnitEncoder->write ( cSEIMessageList ) );
RNOK( m_pcNalUnitEncoder->closeNalUnit( uiBits ) );
//===== write SEI message =====
RNOK( pcWriteBitStream->writePacket( &m_cBinDataStartCode ) );
RNOK( pcWriteBitStream->writePacket( &cExtBinDataAccessor ) );
//===== reset =====
cBinData.reset();
return Err::m_nOK;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -