RTP 协议解包为 H264 裸流

本文介绍了RTP协议为何优于TCP和UDP,并讲解了H264的封装结构。RTP解包时,需要处理NALU的开始码和可能的分片情况,通过RTP Header的m标志位、seq序列号以及NALU Header的nalu_type确定解包策略。当遇到被切片的NALU时,要关注FU Indicator和FU Header的标志位。核心代码实现解析RTP包以得到H264裸流。
摘要由CSDN通过智能技术生成
RTP 协议解包为 H264裸流
一. 为什么使用 RTP 协议?
  • TCP 传输流媒体数据由于其可靠性,会造成很大的网络延时和卡顿。
  • UDP 传输由于其不可靠性,会导致丢帧,如果是关键帧,则会花屏一个序列的时长。
  • RTP 使用了 RTP 和 RTCP 两个子协议来完成。
    • RTP 使用 UDP 完成流媒体数据传输,保证其时效性。
    • RTCP 也是使用 UDP,但只传输控制信息,占带宽很小,此时上层根据 RTCP 的信息,按照其重要性决定是否对丢失的流媒体数据进行重传。
    • RTP 在 1025-65535 之间选择一个未使用的偶数端口号作为其端口,RTCP 则使用下一个奇数端口号作为其端口,进而组成一个 UDP 端口对,端口号 5004 和 5005 作为 RTP 和 RTCP 的默认端口号。
  • RTP-Header 的流媒体特性,提供 帧边界、编码格式、序列号、时间戳等字段。
  • RTP 支持网络多播,而 TCP 不支持。
二. H264 的封装
  • 拆解:H264 --> 序列(SPS.PPS.IPBBP…) --> Frame(帧) --> slice(切片) --> 宏块 --> 子宏块。
    序列:一段 H264 序列是指从一个 I 帧开始到下一个 I 帧前的所有帧的集合。

  • NALU:H264 被封装在一个个 NALU(Network Abstraction Layer Unit)中进行传输。
    NALU 以 [00 00 00 01] 为开始码,之后是 NaluHeader,再之后是 NaluPayload。
    eg: [00 00 00 01 67 2F A4 1E 23 59 1E 42 … ].
    常见的帧头数据:
    00 00 00 01 67(SPS)
    00 00 00 01 68(PPS)
    00 00 00 01 65(IDR 帧)
    00 00 00 01 61(P帧)

三. RTP 解包概念解析
  • RTP 封包时会将 [00 00 00 01] 的开始码去除。(注:在收到 RTP 包时需要在每个 NALU 头的位置拼接此开始码)
    eg:[RTP-Header] + [ 67 2F A4 1E 23 59 1E 42 … ].

  • NALU 封包策略

    • 如果 NALU 长度比较小,则可以将其完整地装在一个 RTP 包中。
      此时,RTP 的结构为 RtpHeader + RtpPayload(NaluHeader + NaluPayload).

    • 如果 NALU 长度超过 MTU(最大传输单元) 时,则需要对 NALU 进行分片封包。
      此时,RTP 的结构为 RtpHeader + RtpPayload(FuIndicator + FuHeader + NaluPayload).
      会比完整包多一个字节的头信息,下文会详细解释其含义。

什么是 RtpHeader, NaluHeader, FuIndicator 和 FuHeader?

RtpHeader

  • 结构体

    /**
     * RtpHeader,普遍占用12个字节
     * 
     * 由于 IP 协议采用大端序,这里需要转成小端序 (Java-Byte 是大端序,java 代码中可以不用转),
     * 所以这里每一个字节内的各个属性跟标准 rtp 协议头刚好相反,
     * 并且在使用 "大于1bit" 的属性时需要将网络序转成字节序.
     */
    typedef struct rtp_header_t
    {
         
      	// 1byte (0)
      	unsigned int cc : 4;	  	/* CSRC count */
      	unsigned int x : 1;		 	/* header extension flag */
      	unsigned int p : 1;		  	/* padding flag */
      	unsigned int version : 2; 	/* protocol version */
      
      	// 1byte (1)
      	unsigned int pt : 7; 		/* payload type */
      	unsigned int m : 1;  		/* marker bit */
      	
      	// 2bytes (2,3)
      	unsigned int seq : 16; 		/* sequence number */
      
      	// 4bytes (4-7)
      	uint32_t ts
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值