📄 qualitylevelassigner.cpp
字号:
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.getQualityId( 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;
static Bool bAVCComaptible = false; //bug-fix suffix
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 };
UInt uiLevel_prefix = 0;//prefix unit
//===== 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 ) );
if(cPacketDescription.NalUnitType== NAL_UNIT_CODED_SLICE ||
cPacketDescription.NalUnitType== NAL_UNIT_CODED_SLICE_IDR )
{
cPacketDescription.Level = uiLevel_prefix;//prefix unit
}
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 )
{
// JVT-T083: modify the Position of SimplePriorityId
// clear previous value
pcBinData->data()[1] &= 0xC0;
// write new value of priority ID
pcBinData->data()[1] |= m_aaauiQualityID[cPacketDescription.Layer][cPacketDescription.FGSLayer][auiFrameNum[cPacketDescription.Layer]];
}
else
{
if(cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE_IDR || cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE)
{
bAVCComaptible = true;
}
if( ! cPacketDescription.ParameterSet && cPacketDescription.NalUnitType != NAL_UNIT_SEI &&
! cPacketDescription.FGSLayer && cPacketDescription.NalUnitType != NAL_UNIT_PREFIX && cPacketDescription.uiFirstMb == 0 )
{
auiFrameNum[cPacketDescription.Layer]++;
}
}
//prefix unit{{
if(cPacketDescription.NalUnitType == 14)
{
uiLevel_prefix = cPacketDescription.Level;
}
//prefix unit}}
//----- 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;
static Bool bAVCComaptible = false; //bug-fix suffix
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 };
UInt uiLevel_prefix = 0;//prefix unit
//===== 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 () ) );
Bool bPrevNALUnitWasPrefix = false; //JVT-W137
//===== 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 ) );
if(cPacketDescription.NalUnitType== NAL_UNIT_CODED_SLICE ||
cPacketDescription.NalUnitType== NAL_UNIT_CODED_SLICE_IDR )
{
cPacketDescription.Level = uiLevel_prefix;//prefix unit
}
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(cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE_IDR || cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE)
{
bAVCComaptible = true;
bNewAccessUnit = bNewAccessUnit && (!bPrevNALUnitWasPrefix); //JVT-W137
if(bPrevNALUnitWasPrefix)
bPrevNALUnitWasPrefix = false; //JVT-W137
}
//prefix unit{{
if(cPacketDescription.NalUnitType == 14)
{
uiLevel_prefix = cPacketDescription.Level;
//bNewAccessUnit = false; //JVT-W137 remove
bPrevNALUnitWasPrefix = true; //JVT-W137
}
//prefix unit}}
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] );//SEI changes update
xInsertPriorityLevelSEI( pcWriteBitStream, uiLayer, auiFrameNum[uiLayer] );//SEI changes update
}
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;
}
//SEI changes update {
//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] ); //JVT-W137
// }
// 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;
//}
ErrVal
QualityLevelAssigner::xInsertPriorityLevelSEI( WriteBitstreamToFile* pcWriteBitStream,
UInt uiLayer,
UInt uiFrameNum )
{
//===== init binary data =====
const UInt uiPRSEIMessageBufferSize = 1024;
UChar aucPRSEIMessageBuffer[uiPRSEIMessageBufferSize];
BinData cBinData;
ExtBinDataAccessor cExtBinDataAccessor;
cBinData.reset ();
cBinData.set ( aucPRSEIMessageBuffer, uiPRSEIMessageBufferSize );
cBinData.setMemAccessor ( cExtBinDataAccessor );
//===== create SEI message =====
SEI::PriorityLevelSEI* pcPriorityLevelSEI;
SEI::MessageList cSEIMessageList;
RNOK( SEI::PriorityLevelSEI::create( pcPriorityLevelSEI ) );
cSEIMessageList.push_back( pcPriorityLevelSEI );
//===== set content of SEI message =====
UInt uiNumLayers;
for( uiNumLayers = 0; uiNumLayers <= m_auiNumFGSLayers[uiLayer] && m_aaauiQualityID [uiLayer][uiNumLayers][uiFrameNum] != MSYS_UINT_MAX; uiNumLayers++ )
{
pcPriorityLevelSEI->setAltPriorityId ( uiNumLayers, m_aaauiQualityID [uiLayer][uiNumLayers][uiFrameNum] );
}
pcPriorityLevelSEI->setPrDependencyId ( uiLayer );
pcPriorityLevelSEI->setNumPriorityIds ( 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;
}
//SEI changes update }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -