如何将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
    评论
H.264和H.265(HEVC)是两种常用的视频编码标准,用于压缩和编码视频数据。RTP(Real-time Transport Protocol)是一种用于实时传输音视频数据的协议,常用于实时通信应用中。 封装H.264和H.265视频数据为RTP流的主要区别在于以下几个方面: 1. RTP负载类型:H.264和H.265在RTP中的负载类型不同。H.264的RTP负载类型为96,而H.265的RTP负载类型为265。这些负载类型用于标识传输的数据类型,以便接收方能够正确解析和处理数据。 2. NAL单元:H.264和H.265编码的视频数据被划分为多个NAL单元(Network Abstraction Layer Units),每个NAL单元含一部分视频数据。封装RTP流时,需要将NAL单元进行打。对于H.264,常用的打方式是将多个NAL单元打为一个RTP,或者将一个NAL单元拆分为多个RTP进行传输。而H.265在打方面引入了更多的灵活性,允许将多个NAL单元一起打为一个RTP,或者将一个NAL单元拆分为多个RTP。 3. RTP扩展头:H.265引入了RTP扩展头(RTP header extension),用于在RTP头部中传输一些额外的信息,如帧类型、解码时间戳等。这些信息在H.265的RTP封装中可以使用RTP扩展头进行传输,而在H.264的RTP封装中需要使用其他方式进行传输。 总体而言,H.264和H.265在RTP封装方面存在一些细微的区别,主要体现在负载类型的不同,NAL单元的打方式以及H.265引入的RTP扩展头。这些区别需要根据具体的应用场景和要求来选择适当的封装方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值