📄 nalunitparser.cpp
字号:
DTRACE_TH ( "NALU HEADER: tl0_pic_idx_present_flag" );
DTRACE_TY ( " u(1)" );
DTRACE_POS;
DTRACE_CODE ( m_bTl0PicIdxPresentFlag );
DTRACE_BITS ( m_bTl0PicIdxPresentFlag, 1 );
DTRACE_COUNT( 1 );
DTRACE_N;
// JVT-U116 LMI }
// JVT-V088 LMI }
}
//JVT-P031
UInt
NalUnitParser::getNalHeaderSize( BinDataAccessor* pcBinDataAccessor )
{
ROF( pcBinDataAccessor->size() );
ROF( pcBinDataAccessor->data() );
NalUnitType eNalUnitType;
NalRefIdc eNalRefIdc;
UInt uiHeaderLength = 1;
UChar ucByte = pcBinDataAccessor->data()[0];
//===== NAL unit header =====
ROT( ucByte & 0x80 ); // forbidden_zero_bit ( &10000000b)
eNalRefIdc = NalRefIdc ( ucByte >> 5 ); // nal_ref_idc ( &01100000b)
eNalUnitType = NalUnitType ( ucByte & 0x1F ); // nal_unit_type ( &00011111b)
if( eNalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE ||
eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE )
{
uiHeaderLength += NAL_UNIT_HEADER_SVC_EXTENSION_BYTES;
// JVT-U116 LMI {
ucByte = pcBinDataAccessor->data()[3];
if ( ucByte & 1 )
uiHeaderLength ++;
// JVT-U116 LMI }
}
return uiHeaderLength;
}
ErrVal
NalUnitParser::initSODBNalUnit( BinDataAccessor* pcBinDataAccessor )
{
m_pucBuffer = pcBinDataAccessor->data();
UInt uiPacketLength = pcBinDataAccessor->size();
UInt uiBits;
xConvertRBSPToSODB(uiPacketLength, uiBits);
RNOK( m_pcBitReadBuffer->initPacket( (ULong*)(m_pucBuffer), uiBits) );
return Err::m_nOK;
}
UInt
NalUnitParser::getBytesLeft()
{
return(m_pcBitReadBuffer->getBytesLeft());
}
UInt
NalUnitParser::getBitsLeft()
{
return(m_pcBitReadBuffer->getBitsLeft());
}
//~JVT-P031
ErrVal
NalUnitParser::initNalUnit( BinDataAccessor* pcBinDataAccessor,
UInt& uiNumBytesRemoved, //FIX_FRAG_CAVLC
Bool bPreParseHeader,
Bool bConcatenated, //FRAG_FIX
Bool bCheckGap, //TMM_EC
UInt* puiNumFragments,
UChar** ppucFragBuffers )
{
ROF( pcBinDataAccessor->size() );
ROF( pcBinDataAccessor->data() );
UInt uiHeaderLength = 1;
UChar ucByte = pcBinDataAccessor->data()[0];
//===== NAL unit header =====
ROT( ucByte & 0x80 ); // forbidden_zero_bit ( &10000000b)
m_eNalRefIdc = NalRefIdc ( ucByte >> 5 ); // nal_ref_idc ( &01100000b)
m_eNalUnitType = NalUnitType ( ucByte & 0x1F ); // nal_unit_type ( &00011111b)
// TMM_EC {{
if ( *(int*)(pcBinDataAccessor->data()+1) != 0xdeadface)
{
if( m_eNalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE ||
m_eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE ||
m_eNalUnitType == NAL_UNIT_PREFIX)//prefix unit
{
ROF( pcBinDataAccessor->size() > 3 );
ucByte = pcBinDataAccessor->data()[1];
ROT( ucByte & 0xC0 ); // reserved_zero_two_bitst ( &11000000b)
m_uiPriorityId = ( ucByte >> 2); // priority_id ( &00111111b)
ucByte = pcBinDataAccessor->data()[2];
m_uiTemporalLevel = ( ucByte >> 5 ); // temporal_level ( &11100000b)
m_uiLayerId = ( ucByte >> 2 ) & 7; // dependency_id ( &00011100b)
m_uiQualityLevel = ( ucByte ) & 3; // quality_level ( &00000011b)
ucByte = pcBinDataAccessor->data()[3];
// JVT-U116 LMI {
//ROT( ucByte & 0x80 ); // reserved_zero_one_bit ( &10000000b)
m_bLayerBaseFlag = ( ucByte >> 7) & 1; // layer_base_flag ( &10000000b)
m_bUseBasePredFlag = ( ucByte >> 6) & 1; // use_base_prediction_flag ( &01000000b)
m_bDiscardableFlag = ( ucByte >> 5) & 1; // discardable_flag ( &00100000b)
m_bFGSFragFlag = ( ucByte >> 4) & 1; // fgs_frag_flag ( &00010000b)
m_bFGSLastFragFlag = ( ucByte >> 3) & 1; // fgs_last_frag_flag ( &00001000b)
m_uiFGSFragOrder = ( ucByte >> 1) & 3; // fgs_frag_order ( &00000110b)
// JVT-V088 LMI {
m_bTl0PicIdxPresentFlag = ( ucByte >> 0) & 1; // tl0_pic_idx_present_flag ( &00000001b)
uiHeaderLength += NAL_UNIT_HEADER_SVC_EXTENSION_BYTES;
// JVT-V088 LMI }
// JVT-U116 LMI }
}
else
{
m_uiPriorityId = 0;
m_uiTemporalLevel = 0;
m_uiLayerId = 0;
m_uiQualityLevel = 0;
m_bLayerBaseFlag = 1; // m_bLayerBaseFlag indicate that the content of the NAL is compatible with NAL_UNIT_CODED_SLICE
m_bUseBasePredFlag= 0;
m_bDiscardableFlag= 0;
m_bFGSFragFlag = 0;
m_bFGSLastFragFlag= 0;
m_uiFGSFragOrder = 0;
}
}
else //TMM_EC
{
uiNumBytesRemoved = 0;
m_pucBuffer = pcBinDataAccessor->data() + uiHeaderLength;
return Err::m_nOK;
}
//===== TRACE output =====
xTrace( uiHeaderLength > 1 );
//===== NAL unit payload =====
m_pucBuffer = pcBinDataAccessor->data() + uiHeaderLength;
UInt uiPacketLength = pcBinDataAccessor->size() - uiHeaderLength;
//JVT-P031
if(m_bDiscardableFlag == true && m_uiDecodedLayer > m_uiLayerId && !m_bCheckAllNALUs)
{
//Nal unit or fragment must be discarded
uiPacketLength = 0;
}
//~JVT-P031
// nothing more to do
ROTRS( NAL_UNIT_END_OF_STREAM == m_eNalUnitType ||
NAL_UNIT_END_OF_SEQUENCE == m_eNalUnitType, Err::m_nOK );
uiNumBytesRemoved = uiPacketLength;//FIX_FRAG_CAVLC
if ( !bCheckGap)
{
// Unit->RBSP
if(bPreParseHeader) //FRAG_FIX
{//FIX_FRAG_CAVLC
RNOK( xConvertPayloadToRBSP ( uiPacketLength ) );
uiNumBytesRemoved -= uiPacketLength; //FIX_FRAG_CAVLC
}//FIX_FRAG_CAVLC
}
else //TMM_EC
{
uiNumBytesRemoved = 0;
}
UInt uiBitsInPacket;
// RBSP->SODB
RNOK( xConvertRBSPToSODB ( uiPacketLength, uiBitsInPacket ) );
//FRAG_FIX
if(!(m_bDiscardableFlag && m_uiDecodedLayer > m_uiLayerId)) //FRAG_FIX_3
{
if(bPreParseHeader)
m_uiBitsInPacketSaved = uiBitsInPacket;
if(!bPreParseHeader && !bConcatenated) //FRAG_FIX_3
uiBitsInPacket = m_uiBitsInPacketSaved;
} //FRAG_FIX_3
if(!m_bDiscardableFlag || (m_bDiscardableFlag && m_uiDecodedLayer == m_uiLayerId) || m_bCheckAllNALUs) //JVT-P031
{
RNOK( m_pcBitReadBuffer->initPacket( (ULong*)(m_pucBuffer), uiBitsInPacket, puiNumFragments, ppucFragBuffers ) );
}
return Err::m_nOK;
}
ErrVal
NalUnitParser::closeNalUnit()
{
m_pucBuffer = NULL;
m_eNalUnitType = NAL_UNIT_EXTERNAL;
m_eNalRefIdc = NAL_REF_IDC_PRIORITY_LOWEST;
m_uiLayerId = 0;
m_uiTemporalLevel = 0;
m_uiQualityLevel = 0;
return Err::m_nOK;
}
ErrVal
NalUnitParser::xConvertPayloadToRBSP( UInt& ruiPacketLength )
{
UInt uiZeroCount = 0;
UInt uiWriteOffset = 0;
UInt uiReadOffset = 0;
for( ; uiReadOffset < ruiPacketLength; uiReadOffset++, uiWriteOffset++ )
{
if( 2 == uiZeroCount && 0x03 == m_pucBuffer[uiReadOffset] )
{
uiReadOffset++;
uiZeroCount = 0;
}
m_pucBuffer[uiWriteOffset] = m_pucBuffer[uiReadOffset];
if( 0x00 == m_pucBuffer[uiReadOffset] )
{
uiZeroCount++;
}
else
{
uiZeroCount = 0;
}
}
ruiPacketLength = uiWriteOffset;
return Err::m_nOK;
}
ErrVal
NalUnitParser::xConvertRBSPToSODB( UInt uiPacketLength,
UInt& ruiBitsInPacket )
{
uiPacketLength--;
UChar *puc = m_pucBuffer;
//remove zero bytes at the end of the stream
while (puc[uiPacketLength] == 0x00)
{
uiPacketLength-=1;
}
// find the first non-zero bit
UChar ucLastByte=puc[uiPacketLength];
Int i;
for( i = 0; (ucLastByte & 1 ) == 0; i++ )
{
ucLastByte >>= 1;
AOT_DBG( i > 7 );
}
ruiBitsInPacket = (uiPacketLength << 3) + 8 - i;
return Err::m_nOK;
}
ErrVal NalUnitParser::readAUDelimiter()
{
DTRACE_HEADER("Access Unit Delimiter");
UInt uiPicDelimiterType;
m_pcBitReadBuffer->get(uiPicDelimiterType, 3);
DTRACE_TH( "AUD: primary_pic_type" );
DTRACE_TY( " u(3)" );
DTRACE_BITS(uiPicDelimiterType, 3);
DTRACE_POS;
DTRACE_CODE(uiPicDelimiterType);
DTRACE_COUNT(3);
DTRACE_N;
return Err::m_nOK;
}
ErrVal NalUnitParser::readEndOfSeqence()
{
DTRACE_HEADER("End of Sequence");
return Err::m_nOK;
}
ErrVal NalUnitParser::readEndOfStream()
{
DTRACE_HEADER("End of Stream");
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -