📄 extractor.cpp
字号:
MyList<ExtractorParameter::Point>::const_iterator cIter = rcExtList.begin ();
MyList<ExtractorParameter::Point>::const_iterator cEnd = rcExtList.end ();
const ExtractorParameter::Point& rcExtPoint = *cIter;
Int Count = 0;
printf("\n\n============Extraction Information======");
printf("\nExtracted spatail layer : %dx%d", rcExtPoint.uiWidth, rcExtPoint.uiHeight);
printf("\nExtracted temporal rate : %2.0ff/s", rcExtPoint.dFrameRate);
RNOK( m_pcH264AVCPacketAnalyzer->init() );
while( ! bEOS )
{
//=========== get packet ===========
BinData* pcBinData;
// JVT-S080 LMI {
BinData * pcBinDataSEILysNotPreDepChange;
ROT( NULL == ( pcBinDataSEILysNotPreDepChange = new BinData ) );
Bool bWriteBinDataSEILysNotPreDepChange = false;
Bool bWriteBinData = true;
// JVT-S080 LMI }
RNOK( m_pcReadBitstream->extractPacket( pcBinData, bEOS ) );
if( bEOS )
{
RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
pcBinData = NULL;
continue;
}
//========== get packet description ==========
h264::SEI::SEIMessage* pcScalableSEIMessage = 0;
h264::PacketDescription cPacketDescription;
RNOK( m_pcH264AVCPacketAnalyzer->process( pcBinData, cPacketDescription, pcScalableSEIMessage ) );
if( pcScalableSEIMessage )
{
// JVT-S080 LMI {
if( pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI || pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI_LAYERS_NOT_PRESENT || pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI_DEPENDENCY_CHANGE )
// if( pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI )
{
// BUG_FIX liuhui
if( pcScalableSEIMessage->getMessageType() != h264::SEI::SCALABLE_SEI )
bWriteBinData = false;
RNOK( xChangeScalableSEIMesssage( pcBinData, pcBinDataSEILysNotPreDepChange, pcScalableSEIMessage, MSYS_UINT_MAX,//uiKeepScalableLayer,
uiWantedScalableLayer, uiWantedLayer, uiWantedLevel, dWantedFGSLayer , MSYS_UINT_MAX ) );
if( pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI )
{
h264::SEI::ScalableSeiLayersNotPresent* pcScalableSeiLayersNotPresent = ( h264::SEI::ScalableSeiLayersNotPresent*) pcScalableSEIMessage;
bWriteBinDataSEILysNotPreDepChange = pcScalableSeiLayersNotPresent->getOutputFlag();
}
if( pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI_LAYERS_NOT_PRESENT )
{
h264::SEI::ScalableSeiLayersNotPresent* pcScalableSeiLayersNotPresent = ( h264::SEI::ScalableSeiLayersNotPresent*) pcScalableSEIMessage;
bWriteBinDataSEILysNotPreDepChange = pcScalableSeiLayersNotPresent->getOutputFlag();
}
if( pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI_DEPENDENCY_CHANGE )
{
h264::SEI::ScalableSeiDependencyChange* pcScalableSeiDepChange = ( h264::SEI::ScalableSeiDependencyChange*) pcScalableSEIMessage;
bWriteBinDataSEILysNotPreDepChange = pcScalableSeiDepChange->getOutputFlag();
}
// JVT-S080 LMI }
// BUG_FIX liuhui}
}
}
delete pcScalableSEIMessage;
// consider ROI Extraction ICU/ETRI DS
if (false == CurNalKeepingNeed(cPacketDescription, rcExtPoint))
{
uiNumInput++;
Count++;
continue;
}
// JVT-S080 LMI {
if( bWriteBinData )
{
// JVT-S080 LMI }
//============ get packet size ===========
while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
{
RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove zero at end
}
uiPacketSize = 4 + pcBinData->size();
uiShrinkSize = 0;
//============ set parameters ===========
if( ! bApplyToNext )
{
uiLayer = cPacketDescription.Layer;
uiLevel = cPacketDescription.Level;
uiFGSLayer = cPacketDescription.FGSLayer;
}
bApplyToNext = cPacketDescription.ApplyToNext;
//JVT-P031
if(!cPacketDescription.ParameterSet && cPacketDescription.NalUnitType != NAL_UNIT_SEI && uiFGSLayer == 0)
uiNumFrame[uiLayer]++;
//~JVT-P031
if(cPacketDescription.uiNumLevelsQL != 0) // fix provided by Nathalie
{
//QL SEI packet
bApplyToNext = false;
}
//============ check packet ===========
Double dSNRLayerDiff = m_aadTargetSNRLayer[uiLayer][uiLevel] - (Double)uiFGSLayer;
Double dUpRound = ceil ( dSNRLayerDiff );
Double dDownRound = floor ( dSNRLayerDiff );
bKeep = ( dUpRound >= 0.0 );
bCrop = bKeep && ( dDownRound < 0.0 );
//JVT-T054{
if(uiFGSLayer > 0 && bCrop && !m_bEnableQLTruncation[uiLayer][uiFGSLayer-1])
{
bCrop = false;
bKeep = false;
}
//JVT-T054}
if( bCrop && uiFGSLayer == 0 )
{
bKeep = bCrop = false;
}
if( bCrop )
{
Double dWeight = -dSNRLayerDiff;
uiShrinkSize = (UInt)ceil( (Double)uiPacketSize * dWeight );
if( uiPacketSize - uiShrinkSize > 25 ) // 25 bytes should be enough for the slice headers
{
RNOK( pcBinData->decreaseEndPos( uiShrinkSize ) );
pcBinData->data()[pcBinData->size()-1] |= 0x01; // trailing one
}
else
{
bKeep = bCrop = false;
}
}
UInt eNalUnitType = cPacketDescription.NalUnitType;
Bool bRequired = false;
if( eNalUnitType == NAL_UNIT_SPS )
{
for( UInt layer = 0; layer <= m_pcExtractorParameter->getLayer(); layer ++ )
{
if( m_cScalableStreamDescription.m_bSPSRequired[layer][cPacketDescription.SPSid] )
{
bRequired = true;
break;
}
}
bKeep = bRequired;
}
else if( eNalUnitType == NAL_UNIT_PPS )
{
for( UInt layer = 0; layer <= m_pcExtractorParameter->getLayer(); layer ++ )
{
if( m_cScalableStreamDescription.m_bPPSRequired[layer][cPacketDescription.PPSid] )
{
bRequired = true;
break;
}
}
bKeep = bRequired;
}
uiNumInput++;
if( bKeep ) uiNumKept ++;
if( bCrop ) uiNumCropped++;
//============ write and release packet ============
if( bKeep )
{
RNOK( m_pcWriteBitstream->writePacket( &m_cBinDataStartCode ) );
RNOK( m_pcWriteBitstream->writePacket( pcBinData ) );
}
}
RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
pcBinData = NULL;
// consider ROI Extraction ICU/ETRI DS
Count++;
// JVT-S080 LMI {
if ( bWriteBinDataSEILysNotPreDepChange )
{
while( pcBinDataSEILysNotPreDepChange->data()[ pcBinDataSEILysNotPreDepChange->size() - 1 ] == 0x00 )
{
RNOK( pcBinDataSEILysNotPreDepChange->decreaseEndPos( 1 ) ); // remove zero at end
}
uiPacketSize = 4 + pcBinDataSEILysNotPreDepChange->size();
RNOK( m_pcWriteBitstream->writePacket( &m_cBinDataStartCode ) );
RNOK( m_pcWriteBitstream->writePacket( pcBinDataSEILysNotPreDepChange ) );
}
RNOK( m_pcReadBitstream->releasePacket( pcBinDataSEILysNotPreDepChange ) );
pcBinDataSEILysNotPreDepChange = NULL;
// JVT-S080 LMI }
}
RNOK( m_pcH264AVCPacketAnalyzer->uninit() );
printf("\n\nNumber of input packets: %d\nNumber of output packets: %d (cropped: %d)\n\n", uiNumInput, uiNumKept, uiNumCropped );
return Err::m_nOK;
}
ErrVal
Extractor::xWriteScalableSEIToBuffer(h264::SEI::ScalableSei* pcScalableSei, BinData* pcBinData )
{
const UInt uiSEILength = 1000;
UChar pulStreamPacket[uiSEILength];
pcBinData->reset();
pcBinData->set( new UChar[uiSEILength], uiSEILength );
UChar *m_pucBuffer = pcBinData->data();
ScalableModifyCode cScalableModifyCode;
ScalableTestCode cScalableTestCode;
RNOK( cScalableTestCode.init() );
RNOK( cScalableModifyCode.init( (ULong*) pulStreamPacket ) );
RNOK( cScalableTestCode.SEICode( pcScalableSei, &cScalableTestCode ) );
UInt uiBits = cScalableTestCode.getNumberOfWrittenBits();
UInt uiSize = (uiBits+7)/8;
RNOK( cScalableModifyCode.WriteFlag( 0 ) );
RNOK( cScalableModifyCode.WriteCode( 0 ,2 ) );
RNOK( cScalableModifyCode.WriteCode( NAL_UNIT_SEI, 5 ) );
RNOK( cScalableModifyCode.WritePayloadHeader( pcScalableSei->getMessageType(), uiSize ) );
RNOK( cScalableModifyCode.SEICode( pcScalableSei, &cScalableModifyCode ) );
uiBits = cScalableModifyCode.getNumberOfWrittenBits();
uiSize = (uiBits+7)/8;
UInt uiAlignedBits = 8 - (uiBits&7);
if( uiAlignedBits != 0 && uiAlignedBits != 8 )
{
RNOK( cScalableModifyCode.WriteCode( 1 << (uiAlignedBits-1), uiAlignedBits ) );
}
RNOK ( cScalableModifyCode.WriteTrailingBits() );
RNOK ( cScalableModifyCode.flushBuffer() );
uiBits = cScalableModifyCode.getNumberOfWrittenBits();
uiBits = ( uiBits >> 3 ) + ( 0 != ( uiBits & 0x07 ) );
uiSize = uiBits;
RNOK( cScalableModifyCode.ConvertRBSPToPayload( m_pucBuffer, pulStreamPacket, uiSize, 2 ) );
pcBinData->decreaseEndPos( uiSEILength - uiSize );
return Err::m_nOK;
}
//JVT-S080 LMI {
ErrVal
Extractor::xWriteScalableSEILyrsNotPreToBuffer(h264::SEI::ScalableSeiLayersNotPresent* pcScalableSei, BinData* pcBinData )
{
const UInt uiSEILength = 1000;
UChar pulStreamPacket[uiSEILength];
pcBinData->reset();
pcBinData->set( new UChar[uiSEILength], uiSEILength );
UChar *m_pucBuffer = pcBinData->data();
ScalableModifyCode cScalableModifyCode;
ScalableTestCode cScalableTestCode;
RNOK( cScalableTestCode.init() );
RNOK( cScalableModifyCode.init( (ULong*) pulStreamPacket ) );
RNOK( cScalableTestCode.SEICode( pcScalableSei, &cScalableTestCode ) );
UInt uiBits = cScalableTestCode.getNumberOfWrittenBits();
UInt uiSize = (uiBits+7)/8;
RNOK( cScalableModifyCode.WriteFlag( 0 ) );
RNOK( cScalableModifyCode.WriteCode( 0 ,2 ) );
RNOK( cScalableModifyCode.WriteCode( NAL_UNIT_SEI, 5 ) );
RNOK( cScalableModifyCode.WritePayloadHeader( pcScalableSei->getMessageType(), uiSize ) );
RNOK( cScalableModifyCode.SEICode( pcScalableSei, &cScalableModifyCode ) );
uiBits = cScalableModifyCode.getNumberOfWrittenBits();
uiSize = (uiBits+7)/8;
UInt uiAlignedBits = 8 - (uiBits&7);
if( uiAlignedBits != 0 && uiAlignedBits != 8 )
{
RNOK( cScalableModifyCode.WriteCode( 1 << (uiAlignedBits-1), uiAlignedBits ) );
}
RNOK ( cScalableModifyCode.WriteTrailingBits() );
RNOK ( cScalableModifyCode.flushBuffer() );
uiBits = cScalableModifyCode.getNumberOfWrittenBits();
uiBits = ( uiBits >> 3 ) + ( 0 != ( uiBits & 0x07 ) );
uiSize = uiBits;
RNOK( cScalableModifyCode.ConvertRBSPToPayload( m_pucBuffer, pulStreamPacket, uiSize, 2 ) );
pcBinData->decreaseEndPos( uiSEILength - uiSize );
return Err::m_nOK;
}
ErrVal
Extractor::xWriteScalableSEIDepChangeToBuffer(h264::SEI::ScalableSeiDependencyChange* pcScalableSei, BinData* pcBinData )
{
const UInt uiSEILength = 1000;
UChar pulStreamPacket[uiSEILength];
pcBinData->reset();
pcBinData->set( new UChar[uiSEILength], uiSEILength );
UChar *m_pucBuffer = pcBinData->data();
ScalableModifyCode cScalableModifyCode;
ScalableTestCode cScalableTestCode;
RNOK( cScalableTestCode.init() );
RNOK( cScalableModifyCode.init( (ULong*) pulStreamPacket ) );
RNOK( cScalableTestCode.SEICode( pcScalableSei, &cScalableTestCode ) );
UInt uiBits = cScalableTestCode.getNumberOfWrittenBits();
UInt uiSize = (uiBits+7)/8;
RNOK( cScalableModifyCode.WriteFlag( 0 ) );
RNOK( cScalableModifyCode.WriteCode( 0 ,2 ) );
RNOK( cScalableModifyCode.WriteCode( NAL_UNIT_SEI, 5 ) );
RNOK( cScalableModifyCode.WritePayloadHeader( pcScalableSei->getMessageType(), uiSize ) );
RNOK( cScalableModifyCode.SEICode( pcScalableSei, &cScalableModifyCode ) );
uiBits = cScalableModifyCode.getNumberOfWrittenBits();
uiSize = (uiBits+7)/8;
UInt uiAlignedBits = 8 - (uiBits&7);
if( uiAlignedBits != 0 && uiAlignedBits != 8 )
{
RNOK( cScalableModifyCode.WriteCode( 1 << (uiAlignedBits-1), uiAlignedBits ) );
}
RNOK ( cScalableModifyCode.WriteTrailingBits() );
RNOK ( cScalableModifyCode.flushBuffer() );
uiBits = cScalableModifyCode.getNumberOfWrittenBits();
uiBits = ( uiBits >> 3 ) + ( 0 != ( uiBits & 0x07 ) );
uiSize = uiBits;
RNOK( cScalableModifyCode.ConvertRBSPToPayload( m_pucBuffer, pulStreamPacket, uiSize, 2 ) );
pcBinData->decreaseEndPos( uiSEILength - uiSize );
return Err::m_nOK;
}
// JVT-S080 LMI }
// JVT-S080 LMI {
// BUG_FIX liuhui{
ErrVal
Extractor::xChangeScalableSEIMesssage( BinData *pcBinData, BinData *pcBinDataSEILysNotPreDepChange, h264::SEI::SEIMessage* pcScalableSEIMessage,
UInt uiKeepScalableLayer, UInt& uiWantedScalableLayer, UInt& uiMaxLayer, UInt& uiMaxTempLevel, Double& dMaxFGSLayer, UInt uiMaxBitrate)
// BUG_FIX liuhui}
{
Bool bLayerNotPresent[MAX_SCALABLE_LAYERS];
h264::SEI::ScalableSeiLayersNotPresent* pcNewScalableSeiLayersNotPresent;
RNOK( h264::SEI::ScalableSeiLayersNotPresent::create(pcNewScalableSeiLayersNotPresent) );
h264::SEI::ScalableSeiLayersNotPresent* pcOldScalableSeiLayersNotPresent = (h264::SEI::ScalableSeiLayersNotPresent* ) pcScalableSEIMessage;
if(pcScalableSEIMessage->getMessageType() == h264::SEI::SCALABLE_SEI)
{
::memset( bLayerNotPresent, 1, MAX_SCALABLE_LAYERS*sizeof(Bool));
// JVT-S080 LMI }
h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -