GB28181中RTP封包C语言实现

今天带来一点rtp封包的代码,分享一下,很多刚刚入门音视频行业的新人都为此困惑,对于传输层,以及应用层的协议都有很多的疑问,也希望大家遇到困难可以向我提问:qq:1015787417
while(!feof(bits)) 
{
GetAnnexbNALU(nal);//每执行一次,文件的指针指向本次找到的NALU的末尾,
memset(sendbuf,0,1500);//清空sendbuf;\

//rtp固定包头,为12字节,
rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0]; 
rtp_hdr->version = 2;   //版本号,此版本固定为2
rtp_hdr->marker  = 0;   //标志位,由具体协议规定其值。
rtp_hdr->payload = H264;//负载类型号,
rtp_hdr->ssrc    = htonl(10);//随机指定为10,并且在本RTP会话中全局唯一

//当一个NALU小于1400字节的时候,采用一个单RTP包发送
if( nal->len<=UDP_MAX_SIZE)
{
//设置rtp M 位;
rtp_hdr->marker=1;
rtp_hdr->seq_no = htons(seq_num ++); //***,每发送一个RTP包增1

//设置NALU HEADER,并将这个HEADER填入sendbuf[12]
//将sendbuf[12]的地址赋给nalu_hdr,之后对nalu_hdr的写入就将写入sendbuf中;
nalu_hdr =(NALU_HEADER*)&sendbuf[12]; 

nalu_hdr->F=nal->forbidden_bit;
//有效数据在nal->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。
nalu_hdr->NRI=nal->nal_reference_idc>>5;
nalu_hdr->TYPE= nal->nal_unit_type;

nalu_payload =&sendbuf[13]; //同理将sendbuf[13]赋给nalu_payload
memcpy(nalu_payload,nal->buf+1,nal->len-1);//去掉nalu头的nalu剩余内容写入sendbuf[13]开始的字符串。

ts_current = ts_current+timestamp_increse;
rtp_hdr->timestamp = htonl(ts_current);
bytes= nal->len + 12 ; //获得sendbuf的长度,为nalu的长度(包含NALU头但除去起始前缀)加上rtp_header的固定长度12字节
res = send(socket1,sendbuf,bytes,0);//发送RTP包
if (res > 0) {
g_iSendCount+=res;
}

//Sleep(100);
}
else //FU-A
{
int packetNum = nal->len/UDP_MAX_SIZE;
if ( nal->len%UDP_MAX_SIZE != 0 )
packetNum ++;

int lastPackSize = nal->len - (packetNum-1)*UDP_MAX_SIZE;
int packetIndex = 1 ;

ts_current = ts_current+timestamp_increse;

rtp_hdr->timestamp = htonl( ts_current);

//发送第一个的FU,S=1,E=0,R=0
rtp_hdr->seq_no = htons(seq_num ++); //***,每发送一个RTP包增1

//设置rtp M 位;
rtp_hdr->marker=0;

//设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
fu_ind = (FU_INDICATOR*)&sendbuf[12]; //将sendbuf[12]的地址赋给fu_ind,之后对fu_ind的写入就将写入sendbuf中;
fu_ind->F = nal->forbidden_bit;
fu_ind->NRI = nal->nal_reference_idc>>5;
fu_ind->TYPE = 28;

//设置FU HEADER,并将这个HEADER填入sendbuf[13]
fu_hdr =(FU_HEADER*)&sendbuf[13];

fu_hdr->S= 1; // ***** 1.第一包
fu_hdr->E= 0;
fu_hdr->R= 0;
fu_hdr->TYPE = nal->nal_unit_type;

nalu_payload = &sendbuf[14];//同理将sendbuf[14]赋给nalu_payload
memcpy( nalu_payload,nal->buf+1,UDP_MAX_SIZE);//去掉NALU头
bytes = UDP_MAX_SIZE+14;//获得sendbuf的长度,为nalu的长度(除去起始前缀和NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节
res = send( socket1, sendbuf, bytes, 0 );//发送RTP包
if (res > 0) {
g_iSendCount+=res;
}
//****  2。 发送中间的FU,S=0,E=0,R=0
for( packetIndex=2;packetIndex<packetNum;packetIndex++)
{
rtp_hdr->seq_no = htons(seq_num ++); //***,每发送一个RTP包增1

//设置rtp M 位;
rtp_hdr->marker=0;
//设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
fu_ind =(FU_INDICATOR*)&sendbuf[12]; 
fu_ind->F=nal->forbidden_bit;
fu_ind->NRI=nal->nal_reference_idc>>5;
fu_ind->TYPE=28;

//设置FU HEADER,并将这个HEADER填入sendbuf[13]
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->S = 0;
fu_hdr->E = 0;
fu_hdr->R = 0;
fu_hdr->TYPE=nal->nal_unit_type;

nalu_payload = &sendbuf[14]; 
memcpy( nalu_payload,nal->buf+(packetIndex-1)*UDP_MAX_SIZE+1,UDP_MAX_SIZE);//去掉起始前缀的nalu剩余内容写入sendbuf[14]开始的字符串。
bytes = UDP_MAX_SIZE+14;//获得sendbuf的长度,为nalu的长度(除去原NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节
res = send( socket1, sendbuf, bytes, 0 );//发送rtp包
if (res > 0) {
g_iSendCount+=res;
}
}

//3.发送最后一个的FU,S=0,E=1,R=0

rtp_hdr->seq_no = htons(seq_num ++);
rtp_hdr->marker=1; //设置rtp M 位;当前传输的是最后一个分片时该位置1

//设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
fu_ind =(FU_INDICATOR*)&sendbuf[12]; //将sendbuf[12]的地址赋给fu_ind,之后对fu_ind的写入就将写入sendbuf中;
fu_ind->F = nal->forbidden_bit;
fu_ind->NRI = nal->nal_reference_idc>>5;
fu_ind->TYPE= 28;

//设置FU HEADER,并将这个HEADER填入sendbuf[13]
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->S=0;
fu_hdr->E=1;  // ***
fu_hdr->R=0;
fu_hdr->TYPE=nal->nal_unit_type;

nalu_payload=&sendbuf[14];
memcpy( nalu_payload, nal->buf+( packetIndex-1)*UDP_MAX_SIZE+1, lastPackSize-1);//将nalu最后剩余的-1(去掉了一个字节的NALU头)字节内容写入sendbuf[14]开始的字符串。
bytes=lastPackSize-1+14;//获得sendbuf的长度,为剩余nalu的长度l-1加上rtp_header,FU_INDICATOR,FU_HEADER三个包头共14字节
res = send( socket1, sendbuf, bytes, 0 );//发送rtp包
if (res > 0) {
g_iSendCount+=res;
}
}

Sleep(10);
}

如果大家有对接方面的问题欢迎咨询我的Chat快问:

GB28181中RTP封包C语言实现