如何将H264封装为RTP包

//前12个字节
typedef struct
{
    /**//* byte 0 */
    unsigned char csrc_len:4;        /**//* expect 0 */
    unsigned char extension:1;        /**//* expect 1, see RTP_OP below */
    unsigned char padding:1;        /**//* expect 0 */
    unsigned char version:2;        /**//* expect 2 */
    /**//* byte 1 */
    unsigned char payload:7;        /**//* RTP_PAYLOAD_RTSP */
    unsigned char marker:1;        /**//* expect 1 */
    /**//* bytes 2, 3 */
    unsigned short seq_no;           
    /**//* bytes 4-7 */
    unsigned  long timestamp;       
    /**//* bytes 8-11 */
    unsigned long ssrc;            /**//* stream number is used here. */
} RTP_FIXED_HEADER;
//第13个字节
typedef struct {
    //byte 0
   unsigned char TYPE:5;
    unsigned char NRI:2;
   unsigned char F:1;   
        
} NALU_HEADER; /**//* 1 BYTES */
//第14个字节
typedef struct {
    //byte 0
    unsigned char TYPE:5;
  unsigned char R:1;
  unsigned char E:1;
  unsigned char S:1;   
} FU_HEADER; /**//* 1 BYTES */

static RTP_FIXED_HEADER        *rtp_hdr;
所有的NALU封装包都做如下固定赋值
 rtp_hdr->payload     = H264;  //负载类型号,
 rtp_hdr->version     = 2;  //版本号,此版本固定为2
 rtp_hdr->marker    = 0;   //标志位,由具体协议规定其值。
  rtp_hdr->ssrc        = htonl(10);    //随机指定为10,并且在本RTP会话中全局唯一
  


如果是小于等于MTU的nalu,采用一个包来封装
前12个字节
   rtp_hdr->marker=1;
   rtp_hdr->seq_no     = htons(seq_num ++); //序列号,每发送一个RTP包增1
   rtp_hdr->timestamp=htonl(ts_current);
第13个字节为NALU标示符之后的第一个字符做修改
   nalu_hdr->F=buf[0] & 0x80; //  1bit
   nalu_hdr->NRI=(nalu_key->buf[0] & 0x60; )>>5; 2 bit有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。
   nalu_hdr->TYPE=buf[0] & 0x1f;// 5 bit

第14个字节开始为NALU数据[1]开始的所有个字节       
总长度为12+nalu长度

如果大于MTU的NALU,采用mtu大小来分片
同一个NALU所有分片:采用同样的时间戳
   rtp_hdr->timestamp=htonl(ts_current);

第一个分片:
前12个字节:
    rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1
    rtp_hdr->marker=0;
第13个字节为NALU标示符之后的第一个字符做修改:
   nalu_hdr->F=buf[0] & 0x80; //  1bit
   nalu_hdr->NRI=(nalu_key->buf[0] & 0x60; )>>5; 2 bit有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。
   nalu_hdr->NRI->TYPE=28;
第14个字节为:
     fu_hdr.E=0;
     fu_hdr.R=0;
     fu_hdr.S=1;
     fu_hdr.TYPE=buf[0] & 0x1f;// 5 bit
第15个字节开始为NALU数据[1]开始的1400个字节 
      
总长度为1400+14;  

最后一个分片:
     rtp_hdr->marker=1;
第13个字节为NALU标示符之后的第一个字符做修改:
   nalu_hdr->F=buf[0] & 0x80; //  1bit
   nalu_hdr->NRI=(nalu_key->buf[0] & 0x60; )>>5; 2 bit有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。
   nalu_hdr->NRI->TYPE=28;
第14个字节为:
     fu_hdr.R=0;
     fu_hdr.S=0;
     fu_hdr.E=1;
     fu_hdr.TYPE=buf[0] & 0x1f;// 5 bit
第15个字节开始为剩余字节
     bytes=l-1+14;  //获得sendbuf的长度,为剩余nalu的长度l-1加上rtp_header,FU_INDICATOR,FU_HEADER三个包头共14字节

中间的分片:
     rtp_hdr->marker=0;
第13个字节:
   nalu_hdr->F=buf[0] & 0x80; //  1bit
   nalu_hdr->NRI=(nalu_key->buf[0] & 0x60; )>>5; 2 bit有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。
   nalu_hdr->NRI->TYPE=28;
第14个字节为:
     fu_hdr.R=0;
     fu_hdr.S=0;
     fu_hdr.E=1;
     fu_hdr.TYPE=buf[0] & 0x1f;// 5 bit
第15个字节开始为中间的的1400个字节 
总长度为:     bytes=1400+14;      //获得sendbuf的长度,为nalu的长度(除去原NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节


 timestamp_increse=(unsigned int)(90000.0 / framerate);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值