RTP 承载H.264 Payload的解包类源码
// class CH264_RTP_UNPACK start
- class CH264_RTP_UNPACK
- {
-
- #define RTP_VERSION 2
- #define BUF_SIZE (1024 * 500)
-
- typedef struct
- {
-
- unsigned short cc:4;
- unsigned short x:1;
- unsigned short p:1;
- unsigned short v:2;
- unsigned short pt:7;
- unsigned short m:1;
-
- unsigned short seq;
- unsigned long ts;
- unsigned long ssrc;
- } rtp_hdr_t;
- public:
-
- CH264_RTP_UNPACK ( HRESULT &hr, unsigned char H264PAYLOADTYPE = 96 )
- : m_bSPSFound(false)
- , m_bWaitKeyFrame(true)
- , m_bPrevFrameEnd(false)
- , m_bAssemblingFrame(false)
- , m_wSeq(1234)
- , m_ssrc(0)
- {
- m_pBuf = new BYTE[BUF_SIZE] ;
- if ( m_pBuf == NULL )
- {
- hr = E_OUTOFMEMORY ;
- return ;
- }
-
- m_H264PAYLOADTYPE = H264PAYLOADTYPE ;
- m_pEnd = m_pBuf + BUF_SIZE ;
- m_pStart = m_pBuf ;
- m_dwSize = 0 ;
- hr = S_OK ;
- }
-
- ~CH264_RTP_UNPACK(void)
- {
- delete [] m_pBuf ;
- }
-
-
-
- BYTE* Parse_RTP_Packet ( BYTE *pBuf, unsigned short nSize, int *outSize )
- {
- if ( nSize <= 12 )
- {
- return NULL ;
- }
-
- BYTE *cp = (BYTE*)&m_RTP_Header ;
- cp[0] = pBuf[0] ;
- cp[1] = pBuf[1] ;
-
- m_RTP_Header.seq = pBuf[2] ;
- m_RTP_Header.seq <<= 8 ;
- m_RTP_Header.seq |= pBuf[3] ;
-
- m_RTP_Header.ts = pBuf[4] ;
- m_RTP_Header.ts <<= 8 ;
- m_RTP_Header.ts |= pBuf[5] ;
- m_RTP_Header.ts <<= 8 ;
- m_RTP_Header.ts |= pBuf[6] ;
- m_RTP_Header.ts <<= 8 ;
- m_RTP_Header.ts |= pBuf[7] ;
-
- m_RTP_Header.ssrc = pBuf[8] ;
- m_RTP_Header.ssrc <<= 8 ;
- m_RTP_Header.ssrc |= pBuf[9] ;
- m_RTP_Header.ssrc <<= 8 ;
- m_RTP_Header.ssrc |= pBuf[10] ;
- m_RTP_Header.ssrc <<= 8 ;
- m_RTP_Header.ssrc |= pBuf[11] ;
-
- BYTE *pPayload = pBuf + 12 ;
- DWORD PayloadSize = nSize - 12 ;
-
-
- if ( m_RTP_Header.v != RTP_VERSION )
- {
- return NULL ;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if ( m_RTP_Header.pt != m_H264PAYLOADTYPE )
- {
- return NULL ;
- }
-
- int PayloadType = pPayload[0] & 0x1f ;
- int NALType = PayloadType ;
- if ( NALType == 28 )
- {
- if ( PayloadSize < 2 )
- {
- return NULL ;
- }
-
- NALType = pPayload[1] & 0x1f ;
- }
-
- if ( m_ssrc != m_RTP_Header.ssrc )
- {
- m_ssrc = m_RTP_Header.ssrc ;
- SetLostPacket () ;
- }
-
- if ( NALType == 0x07 )
- {
- m_bSPSFound = true ;
- }
-
- if ( !m_bSPSFound )
- {
- return NULL ;
- }
-
- if ( NALType == 0x07 || NALType == 0x08 )
- {
- m_wSeq = m_RTP_Header.seq ;
- m_bPrevFrameEnd = true ;
-
- pPayload -= 4 ;
- *((DWORD*)(pPayload)) = 0x01000000 ;
- *outSize = PayloadSize + 4 ;
- return pPayload ;
- }
-
- if ( m_bWaitKeyFrame )
- {
- if ( m_RTP_Header.m )
- {
- m_bPrevFrameEnd = true ;
- if ( !m_bAssemblingFrame )
- {
- m_wSeq = m_RTP_Header.seq ;
- return NULL ;
- }
- }
-
- if ( !m_bPrevFrameEnd )
- {
- m_wSeq = m_RTP_Header.seq ;
- return NULL ;
- }
- else
- {
- if ( NALType != 0x05 )
- {
- m_wSeq = m_RTP_Header.seq ;
- m_bPrevFrameEnd = false ;
- return NULL ;
- }
- }
- }
- if ( m_RTP_Header.seq != (WORD)( m_wSeq + 1 ) )
- {
- m_wSeq = m_RTP_Header.seq ;
- SetLostPacket () ;
- return NULL ;
- }
- else
- {
-
-
- m_wSeq = m_RTP_Header.seq ;
- m_bAssemblingFrame = true ;
-
- if ( PayloadType != 28 )
- {
- *((DWORD*)(m_pStart)) = 0x01000000 ;
- m_pStart += 4 ;
- m_dwSize += 4 ;
- }
- else
- {
- if ( pPayload[1] & 0x80 )
- {
- *((DWORD*)(m_pStart)) = 0x01000000 ;
- m_pStart += 4 ;
- m_dwSize += 4 ;
-
- pPayload[1] = ( pPayload[0] & 0xE0 ) | NALType ;
-
- pPayload += 1 ;
- PayloadSize -= 1 ;
- }
- else
- {
- pPayload += 2 ;
- PayloadSize -= 2 ;
- }
- }
-
- if ( m_pStart + PayloadSize < m_pEnd )
- {
- CopyMemory ( m_pStart, pPayload, PayloadSize ) ;
- m_dwSize += PayloadSize ;
- m_pStart += PayloadSize ;
- }
- else
- {
- SetLostPacket () ;
- return NULL ;
- }
-
- if ( m_RTP_Header.m )
- {
- *outSize = m_dwSize ;
-
- m_pStart = m_pBuf ;
- m_dwSize = 0 ;
-
- if ( NALType == 0x05 )
- {
- m_bWaitKeyFrame = false ;
- }
- return m_pBuf ;
- }
- else
- {
- return NULL ;
- }
- }
- }
-
- void SetLostPacket()
- {
- m_bSPSFound = false ;
- m_bWaitKeyFrame = true ;
- m_bPrevFrameEnd = false ;
- m_bAssemblingFrame = false ;
- m_pStart = m_pBuf ;
- m_dwSize = 0 ;
- }
-
- private:
- rtp_hdr_t m_RTP_Header ;
-
- BYTE *m_pBuf ;
-
- bool m_bSPSFound ;
- bool m_bWaitKeyFrame ;
- bool m_bAssemblingFrame ;
- bool m_bPrevFrameEnd ;
- BYTE *m_pStart ;
- BYTE *m_pEnd ;
- DWORD m_dwSize ;
-
- WORD m_wSeq ;
-
- BYTE m_H264PAYLOADTYPE ;
- DWORD m_ssrc ;
- };
-
-
使用范例:
- HRESULT hr ;
- CH264_RTP_UNPACK unpack ( hr ) ;
- BYTE *pRtpData ;
- WORD inSize;
- int outSize ;
- BYTE *pFrame = unpack.Parse_RTP_Packet ( pRtpData, inSize, &outSize ) ;
- if ( pFrame != NULL )
- {
-
-
- }
文章:来源
(dengzikun) |