前言
~~~~~~ 由于调试HI3516A进行RTP流媒体播放时,需要清楚怎么把H.264数据包 封包为 RTP数据包并发出去。本文章将详细解析H.264数据包 封包为 RTP数据包的协议格式和源代码。
硬件平台:hi3516a
软件平台:Hi3516A_SDK_V1.0.5.0
~~~~~~ H.264数据包 封包为 RTP数据包,网上找了很多资料,但是都不全,所以我尝试结合实例整理出一个比较全面的解析,结合具体的实例也更容易理解些。文章借鉴了很多文章,我都列在了文章最后,在此表示感谢。
~~~~~~ 无私分享,从我做起!
H.264数据包 封包为 RTP数据包的源代码
下面是H.264数据包 封包为 RTP数据包的源代码,这里面加了很多打印信息,不需要的可以自己去掉。
/**************************************************************************************************
RTSP(Real Time Streaming Protocol),RFC2326
RTP :Real Time Protocol 实时协议
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| |
| |
| payload |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :...OPTIONAL RTP padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
************************************************************************************************/
extern unsigned char sps_tmp[256];
extern unsigned char pps_tmp[256];
extern int sps_len;
extern int pps_len;
static int SendNalu264(HndRtp hRtp, char *pNalBuf, int s32NalBufSize)
{
printf("input H.264 raw data----count=%ld------\r\n",s32NalBufSize);
int i=0;
printf("0x");
while(i<100)
{
printf("%x ",pNalBuf[i]);
i++;
}
printf("......\r\n");
char *pNaluPayload;
char *pSendBuf;
int s32Bytes = 0;
int s32Ret = 0;
struct timeval stTimeval;
char *pNaluCurr;
int s32NaluRemain;
unsigned char u8NaluBytes;
pSendBuf = (char *)calloc(MAX_RTP_PKT_LENGTH + 100, sizeof(char)); //#define MAX_RTP_PKT_LENGTH 1400
if(NULL == pSendBuf)
{
s32Ret = -1;
goto cleanup;
}
hRtp->pRtpFixedHdr = (StRtpFixedHdr *)pSendBuf;
hRtp->pRtpFixedHdr->u7Payload = H264;
hRtp->pRtpFixedHdr->u2Version = 2;
hRtp->pRtpFixedHdr->u1Marker = 0;
hRtp->pRtpFixedHdr->u32SSrc = hRtp->u32SSrc;
//计算时间戳
hRtp->pRtpFixedHdr->u32TimeStamp = htonl(hRtp->u32TimeStampCurr * (90000 / 1000));
printf("timestamp:%lld\n",hRtp->u32TimeStampCurr);
if(gettimeofday(&stTimeval, NULL) == -1)
{
printf("Failed to get os time\n");
s32Ret = -1;
goto cleanup;
}
//保存nalu首byte
u8Na