📄 nalunitparser.cpp
字号:
}
}
//JVT-P031
UInt
NalUnitParser::getNalHeaderSize( BinDataAccessor* pcBinDataAccessor )
{
ROF( pcBinDataAccessor->size() );
ROF( pcBinDataAccessor->data() );
NalUnitType eNalUnitType;
NalRefIdc eNalRefIdc;
Bool bReservedZeroBit;//JVT-S036 lsj
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)
//{{Variable Lengh NAL unit header data with priority and dead substream flag
//France Telecom R&D- (nathalie.cammas@francetelecom.com)
m_bDiscardableFlag = false;
//}}Variable Lengh NAL unit header data with priority and dead substream flag
if( eNalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE ||
eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE )
{
ROF( pcBinDataAccessor->size() > 1 );
ucByte = pcBinDataAccessor->data()[1];
//JVT-S036 start
bReservedZeroBit = ( ucByte ) & 1;
uiHeaderLength += 3;
//JVT-S036 end
}
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, Bool* KeyPicFlag,
UInt& uiNumBytesRemoved, //FIX_FRAG_CAVLC
Bool bPreParseHeader, Bool bConcatenated, //FRAG_FIX
Bool bCheckGap) //TMM_EC
{
ROF( pcBinDataAccessor->size() );
ROF( pcBinDataAccessor->data() );
UInt uiHeaderLength = 1;
UChar ucByte = pcBinDataAccessor->data()[0];
m_svc_mvc_flag = false;
//===== NAL unit header =====
ROT( ucByte & 0x80 ); // forbidden_zero_bit ( &10000000b)
m_eNalRefIdc = NalRefIdc ( ucByte >> 5 ); // nal_ref_idc ( &01100000b)
if ( m_eNalRefIdc == NAL_REF_IDC_PRIORITY_HIGHEST && KeyPicFlag != NULL )
*KeyPicFlag = true;
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_CODED_SLICE_PREFIX )// JVT-W035
{
ROF( pcBinDataAccessor->size() > 1 );
ucByte = pcBinDataAccessor->data()[1];
m_svc_mvc_flag = (ucByte >> 7)& 1;
if (!m_svc_mvc_flag)
{
m_uiSimplePriorityId = ( ucByte >> 1) & 0x3f ;
m_bDiscardableFlag = ( ucByte ) & 1;
ucByte = pcBinDataAccessor->data()[2];
m_uiTemporalLevel = ( ucByte >> 5 );
m_uiLayerId = ( ucByte >> 2 ) & 0x07;
m_uiQualityLevel = ( ucByte ) & 0x03;
uiHeaderLength += 3;
}
else
{
// 1 bit
// priority_id
m_uiSimplePriorityId = ( ucByte >> 1 ) & 0x3f ; // 6
// temporal_level
m_uiTemporalLevel = ( ucByte ) &0x01 ; // 1 bit first
m_uiTemporalLevel <<= 2;
ucByte = pcBinDataAccessor->data()[2];
m_uiTemporalLevel += ( ucByte >> 6 ) & 0x03; // 2 bits more
// anchor_pic_flag
m_anchor_pic_flag = ( ucByte >>5 ) & 0x01; // 1 bit
// view_id
m_view_id = ( ucByte ) & 0x1f ; // 5 bit first
m_view_id <<=5;
ucByte = pcBinDataAccessor->data()[3];
m_view_id += (ucByte >>3 ) & 0x1f; // 5 bit more
//idr_flag
m_bIDRFlag = (ucByte >>2 ) & 0x01;
m_inter_view_flag = (ucByte >>1 ) & 0x01; // 1 bit JVT-W056 Samsung
m_reserved_zero_bits = (ucByte) & 0x01; // 1 bit
//For trace
m_AvcViewId = (m_eNalUnitType == NAL_UNIT_CODED_SLICE_PREFIX) ? m_view_id : m_AvcViewId;
uiHeaderLength += 3;
}
}
else
{
m_uiTemporalLevel = ( m_eNalRefIdc > 0 ? 0 : 1 );
m_uiLayerId = 0;
m_uiQualityLevel = 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) );
}
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 + -