当前位置:首页 > RTP封包拆包
//////////////////////////////////////////////////////////////////////////////////////////
// class CH264_RTP_PACK start
class CH264_RTP_PACK {
#define RTP_VERSION 2
typedef struct NAL_msg_s {
bool eoFrame ;
unsigned char type; // NAL type unsigned char *start; // pointer to first location in the send buffer
unsigned char *end; // pointer to last location in send buffer unsigned long size ; } NAL_MSG_t;
typedef struct {
//LITTLE_ENDIAN
unsigned short cc:4; /* CSRC count */ unsigned short x:1; /* header extension flag */ unsigned short p:1; /* padding flag */ unsigned short v:2; /* packet type */ unsigned short pt:7; /* payload type */ unsigned short m:1; /* marker bit */
unsigned short seq; /* sequence number */ unsigned long ts; /* timestamp */ unsigned long ssrc; /* synchronization source */ } rtp_hdr_t;
typedef struct tagRTP_INFO {
NAL_MSG_t nal; // NAL information
rtp_hdr_t rtp_hdr; // RTP header is assembled here int hdr_len; // length of RTP header
unsigned char *pRTP; // pointer to where RTP packet has beem assembled
unsigned char *start; // pointer to start of payload unsigned char *end; // pointer to end of payload
unsigned int s_bit; // bit in the FU header unsigned int e_bit; // bit in the FU header bool FU_flag; // fragmented NAL Unit flag } RTP_INFO;
public:
CH264_RTP_PACK(unsigned long H264SSRC, unsigned char H264PAYLOADTYPE=96, unsigned short MAXRTPPACKSIZE=1472 ) {
m_MAXRTPPACKSIZE = MAXRTPPACKSIZE ; if ( m_MAXRTPPACKSIZE > 10000 ) {
m_MAXRTPPACKSIZE = 10000 ; }
if ( m_MAXRTPPACKSIZE < 50 ) {
m_MAXRTPPACKSIZE = 50 ; }
memset ( &m_RTP_Info, 0, sizeof(m_RTP_Info) ) ;
m_RTP_Info.rtp_hdr.pt = H264PAYLOADTYPE ; m_RTP_Info.rtp_hdr.ssrc = H264SSRC ; m_RTP_Info.rtp_hdr.v = RTP_VERSION ;
m_RTP_Info.rtp_hdr.seq = 0 ; }
~CH264_RTP_PACK(void) { }
//′?è?Setμ?êy?Y±?D?ê?ò???íê??μ?NAL,?eê????a0x00000001?£ //?eê??????°?áéù?¤á?10??×??ú£?ò?±ü?a?ú′?COPY2ù×÷?£ //′ò°üíê3éoó£??-?o3????úμ?êy?Y±????μ?£ bool Set ( unsigned char *NAL_Buf, unsigned long NAL_Size, unsigned long Time_Stamp, bool End_Of_Frame ) {
unsigned long startcode = StartCode(NAL_Buf) ;
if ( startcode != 0x01000000 ) {
return false ; }
int type = NAL_Buf[4] & 0x1f ; if ( type < 1 || type > 12 ) {
return false ; }
m_RTP_Info.nal.start = NAL_Buf ; m_RTP_Info.nal.size = NAL_Size ;
m_RTP_Info.nal.eoFrame = End_Of_Frame ;
m_RTP_Info.nal.type = m_RTP_Info.nal.start[4] ; m_RTP_Info.nal.end = m_RTP_Info.nal.start + m_RTP_Info.nal.size ;
m_RTP_Info.rtp_hdr.ts = Time_Stamp ;
m_RTP_Info.nal.start += 4 ; // skip the syncword
if ( (m_RTP_Info.nal.size + 7) > m_MAXRTPPACKSIZE ) {
m_RTP_Info.FU_flag = true ; m_RTP_Info.s_bit = 1 ; m_RTP_Info.e_bit = 0 ;
m_RTP_Info.nal.start += 1 ; // skip NAL header } else {
m_RTP_Info.FU_flag = false ;
m_RTP_Info.s_bit = m_RTP_Info.e_bit = 0 ; }
m_RTP_Info.start = m_RTP_Info.end = m_RTP_Info.nal.start ; m_bBeginNAL = true ;
return true ; }
//?-?·μ÷ó?Get??è?RTP°ü£??±μ?·μ???μ?aNULL
unsigned char* Get ( unsigned short *pPacketSize ) {
if ( m_RTP_Info.end == m_RTP_Info.nal.end ) {
*pPacketSize = 0 ;
return NULL ; }
if ( m_bBeginNAL ) {
m_bBeginNAL = false ; } else {
m_RTP_Info.start = m_RTP_Info.end; // continue with the next RTP-FU packet }
int bytesLeft = m_RTP_Info.nal.end - m_RTP_Info.start ;
int maxSize = m_MAXRTPPACKSIZE - 12 ; // sizeof(basic rtp header) == 12 bytes
if ( m_RTP_Info.FU_flag ) maxSize -= 2 ;
if ( bytesLeft > maxSize ) {
m_RTP_Info.end = m_RTP_Info.start + maxSize ; // limit RTP packetsize to 1472 bytes } else {
m_RTP_Info.end = m_RTP_Info.start + bytesLeft ; }
if ( m_RTP_Info.FU_flag )
{ // multiple packet NAL slice
if ( m_RTP_Info.end == m_RTP_Info.nal.end ) {
m_RTP_Info.e_bit = 1 ; } }
m_RTP_Info.rtp_hdr.m = m_RTP_Info.nal.eoFrame ? 1 : 0 ; // should be set at EofFrame
if ( m_RTP_Info.FU_flag && !m_RTP_Info.e_bit ) {
m_RTP_Info.rtp_hdr.m = 0 ; }
共分享92篇相关文档