H264的RTP包如何解包

冰川人看世界 2015-09-28 05:09:52
各位论坛的大神,请教一下,H264的RTP包如何解包。live555的源码太复杂,没怎么去研究。参考网上其它人的方法,进行解包,把解包后的数据写入到文件中,用Elecard StreamEye工具查看,发现只有I帧是正常的,P帧B帧全部花屏没法看。下面是我解包代码。

bool CRtp::ParseRtpPacket(BYTE *pInBuf, int nSize, BYTE **pOutBuf, int *outSize)
{
if (nSize < RTP_HEADER_LENGTH)
{
return NULL;
}

memset(&m_RtpHdr, 0, sizeof(m_RtpHdr));

BYTE *pStart = (BYTE *)&m_RtpHdr;

pStart[0] = pInBuf[0];
pStart[1] = pInBuf[1];

m_RtpHdr.seq = pInBuf[2];
m_RtpHdr.seq <<= 8;
m_RtpHdr.seq |= pInBuf[3];

m_RtpHdr.ts = pInBuf[4];
m_RtpHdr.ts <<= 8;
m_RtpHdr.ts |= pInBuf[5];
m_RtpHdr.ts <<= 8;
m_RtpHdr.ts |= pInBuf[6];
m_RtpHdr.ts <<= 8;
m_RtpHdr.ts |= pInBuf[7];

m_RtpHdr.ssrc = pInBuf[8];
m_RtpHdr.ssrc <<= 8;
m_RtpHdr.ssrc |= pInBuf[9];
m_RtpHdr.ssrc <<= 8;
m_RtpHdr.ssrc |= pInBuf[10];
m_RtpHdr.ssrc <<= 8;
m_RtpHdr.ssrc |= pInBuf[11];

//检查RTP版本
if (m_RtpHdr.v != 2)
{
return false;
}

//检查RTP载荷类型
if (m_RtpHdr.pt != H264_PAYLOADTYPE)
{
return false;
}

BYTE *pPayload = pInBuf + RTP_HEADER_LENGTH;
BYTE nalType = pPayload[0] & 0x1f;
BYTE *pBuf = NULL;

if (nalType == 0x1c) //FU-A
{
if ((pPayload[1] & 0xe0) == 0x80)
{
pBuf = pPayload - 3;
*((DWORD *)pBuf) = 0x01000000;
*(pBuf + 4) = (pPayload[0] & 0xe0) | (pPayload[1] & 0x1f);
*outSize = nSize - RTP_HEADER_LENGTH + 3;
}
else
{
pBuf = pPayload + 2;
*outSize = nSize - RTP_HEADER_LENGTH - 2;
}
}
else
{
pBuf = pPayload - 4;
*((DWORD *)pBuf) = 0x01000000;
*outSize = nSize - RTP_HEADER_LENGTH + 4;
}

memcpy(*pOutBuf, pBuf, nSize);

if (m_RtpHdr.m == 1)
{
return true;
}
else
{
return false;
}
}
...全文
987 点赞 收藏 4
写回复
4 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
放到百度网盘了,自己去下。 http://pan.baidu.com/s/1kTMsJzD
回复
yangzcc 2015-10-18
楼主你好,你是不是有破解版的elecard工具啊 能够传我一下 万分感谢了 ~
回复
lcyw 2015-10-13

#include "stdafx.h"

#include "Rtp2H264.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>



#define MAX_FRAME_SIZE 1024*1024*2// 409600 //2MB

CRtp2H264::CRtp2H264(void)
{
m_pData = (unsigned char *)malloc(MAX_FRAME_SIZE);
m_nDataLen = 0;
m_nNewFrame = 1;
m_nSeq = -1;
}

CRtp2H264::~CRtp2H264(void)
{
if( m_pData)
free( m_pData );
m_pData = NULL;
}

int CRtp2H264::OnRtpData(unsigned char *pRtpData, int nLen)
{
if ((NULL == pRtpData) || (nLen < 12))
return -1;

_RTP_HEADER *pRtpHeader = (_RTP_HEADER*)pRtpData;

int nSeq = ntohs( pRtpHeader->nSeq );
m_nSeq++;
if ( m_nSeq != nSeq )
{//
;
}

m_nSeq = nSeq;
nLen = nLen - 12;//RtpPayload

unsigned char *pRtpPayload = pRtpData + 12;

if( pRtpHeader->pt < 12)// audio
{
memcpy(m_pData, pRtpPayload, nLen);
m_nNewFrame = 1;
return 1;
}

unsigned char nNalType = (unsigned char)pRtpPayload[0] & 0x1f;
if( nNalType < 24)
{
if (0 == m_nNewFrame)
{// some thing error.
;
}
memset(m_pData, 0, 4);
m_pData[3] = 1;
memcpy( m_pData+4, pRtpPayload, nLen);
m_nDataLen = nLen + 4;
m_nNewFrame = 1;
}
else if( nNalType < 28) //24 <= nNalType <= 27
{
short nSize = 0;
pRtpPayload++;
while( nLen > 3)
{
memset( m_pData+m_nDataLen, 0, 4);
m_pData[m_nDataLen+3] = 1;
memcpy(&nSize, pRtpPayload, 2);

pRtpPayload++;
pRtpPayload++;
// nSize = ntohs (nSize); // ????
if(nSize > nLen)
break;

m_nDataLen = m_nDataLen + 4;
memcpy(m_pData+m_nDataLen, pRtpPayload, nSize);
m_nDataLen = m_nDataLen + nSize;
pRtpData = pRtpData + nSize;
nLen = nLen - nSize;
}
m_nNewFrame = 1;
}
else if((28 == nNalType) || (29 == nNalType))// FU-A
{
nNalType = pRtpPayload[0] & 0x60;//0xe0
nNalType = nNalType | (pRtpPayload[1] & 0x1F);
if( pRtpPayload[1] &0x80 ) //first pkt
{
if (0 == m_nNewFrame)
{// something error.
;
}
m_nNewFrame = 0;
memset(m_pData, 0, 4);
m_pData[3] = 1;
m_pData[4] = nNalType;

memcpy(m_pData+5, pRtpPayload+2, nLen-2 );
m_nDataLen = 4 + 1 + nLen - 2;
}
else if( pRtpPayload[1] &0x40 )// last pkt
{
m_nNewFrame = 1;
if (0 == pRtpHeader->m )
{// something error.
;
}
memcpy(m_pData+m_nDataLen, pRtpPayload+2, nLen-2);
m_nDataLen = m_nDataLen + nLen - 2;
}
else // middle pkt
{
memcpy(m_pData+m_nDataLen, pRtpPayload+2, nLen-2);
m_nDataLen = m_nDataLen + nLen - 2;
}
}
else
{
return -1;
}

return m_nNewFrame;
}


unsigned char *CRtp2H264::GetH264Data(int *nLen)
{
*nLen = m_nDataLen;
if (0 == m_nNewFrame)
return NULL;

return m_pData;
}



回复
rightorwrong 2015-09-29
看ffmpeg rtp_enc文件
回复
相关推荐
发帖
多媒体/流媒体开发
创建于2007-08-27

2451

社区成员

专题开发/技术/项目 多媒体/流媒体开发
申请成为版主
帖子事件
创建了帖子
2015-09-28 05:09
社区公告
暂无公告