H264协议字段与RTP协议字段之东拼西凑却很有用

H264协议字段与RTP协议字段之东拼西凑却很有用


简介

在这里插入图片描述

在音视频编解码领域中,不仅仅要掌握编码技能和编码原理,还需要掌握其相关的协议字段,这样在我们自己开发一些流媒体传输时,可以选择适合自己的协议进行数据组包,如H264+RTP+UDP,推流到我们的媒体后台,实现我们的流媒体系统


H264协议字段分析

H264是视频编码中相对优秀的一种,比同类型编解码算法更好,在相同带宽下能够提供更好的图像质量!其编解码流程主要包括5个部分:帧间和帧内预测(Estimation)、变换(Transform)和反变换、量化(Quantization)和反量化、环路滤波(Loop Filter)、熵编码(Entropy Coding),更多相关细节,可点击参考

那经过H264编码后的数据是什么样子?

H264数据
大致就会如上图一样!
图像数据编码后是一个一个NALU单元构成
一 个 N A L U 单 元 = N A L _ h e a d e r + R B S P 一个NALU单元 = NAL\_header + RBSP NALU=NAL_header+RBSP

NAL header:这个NAL Unit发送的是什么类型的数据,里面包含了解释RBSP数据的相关信息
RBSP(raw byte Sequence Payload):原始字节序列负载,就是存储了视频编码的数据

NALU单元

NALU由这种格式组成:

[StartCode] [NALU Header] [NALU Payload]

Start Code 用于标示这是一个NALU 单元的开始,必须是 “00 00 00 01”或“00 00 01”,而且NALU内部其他位置不可能出现以上的字节结构,用于区分一个NALU的开始。

关于两种前缀startCode的区别:
在这里插入图片描述

NALU header

在这里插入图片描述
forbidden_bit: 此位必须为0,H264协议规定
nal_ref_idc: NAL unit的权重位,值越大,说明此单元的数据越重要,在解码器处理不及时时,可以丢掉为0的NAL unit

  • 不等于0时,NALU可能是SPS/PPS/参考帧的片
    SPS(Sequence Paramater Set):参数序列集,其保存了一组编码序列GOP所需要的全局参数,如视频尺寸、分辨率等;所以丢失掉SPS会导致GOP这个图像序列无法解码;PPS是图像序列集,
  • 等于0时,可能是非参考帧的片

nal_unit_type: 如下表所示:

其中,只有1~5才包含图像数据,其中 Slice表示片的意思,一个Slice包含一幅图像的一个或者所有的宏块数据,一个NALU载荷存放的就是Slice片结构,并且每个Slice之前是相互独立的,意思就是此片中的编码数据解码不需要其他片作为依赖,这样的好处就是可以防止错误扩大,如果出现错误就只在当前片内才有

最后,RBSP也就是数据负载了,真实的数据了!在献上整体结构体的数据组成图
在这里插入图片描述
感谢岁月斑驳7博主的文章H264 编解码协议详解


RTP协议字段分析

上述H264封装只是在编解码时会用到,如果要发送到网络,则要配置响应的网络协议标准,RTP是一款媒体流实时传输协议,可以用在单播/多播媒体系统中。此外,RTP可以和TCP组成RTCP协议,UDP配合成RUDP协议等,也即是RTP协议在开发中可以自己选择使用UDP还是TCP协议,而RTMP协议属于应用层协议,底层是TCP不可修改,RTP属于传输层的子层

所以,这里我们分析RTP协议字段构成,最后在使用UDP/TCP发送RTP报文即可!

  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             |
 |                             ....                              |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

V: RTP协议的版本号,占2bits,当前协议版本号为2
P: 填充标志,占1bit,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
X: 扩展标志,占1bit,如果X=1,则在RTP报头后跟有一个扩展报头
CC: CSRC计数器,占4位,指示CSRC 标识符的个数
M: 1bit,标记解释由设置定义,目的在于允许重要事件在包流中标记出来。如不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。

负载类型 Payload type(PT): 7bits
注:rfc里面对一些早期的格式定义了这个payload type。但是后来的,如h264并没有分配,那就用96来代替。因此现在96以上都不表示特定的格式,具体表示什么要用sdp或者其他协议来协商。
序列号 Sequence number(SN): 16bits,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1,序列号的初始值是随机产生的。可以用于检查丢包以及进行数据包排序。
时间戳 Timestamp: 32bits,必须使用90kHz时钟频率。

同步信源(SSRC)标识符: 32bits,用于标识同步信源。该标识符是随机随机产生的,参加同一视频会议的两个同步信源不能有相同的SSRC。
特约信源(CSRC)标识符: 每个CSRC标识符占32bits,可以有0~15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源。(可省略该字段)

在配置协议字段时,还要注意其网络字节序!

关于SSRC和CSRC字段的理解

SSRC同步信源,产生这个媒体流的源头,来自麦克风、camera摄像机还是混合器,参加同一视频会议的两个SSRC不能相同,因为RTP接收方根据SSRC来分组RTP包

CSRC特约信源,当多路不同信源SSRC的RTP包经过混合器时,混合器将把这多路信源RTP流转换成一个流发送出去,首先混合器会把多路流的SSRC记录下来,形成一个列表,叫CSRC表;然后经过混合器发送的第一个RTP包会将CSRC填充CSRC表,此包的复杂部分可能是无意义或无负载数据,接收方接收到后就知道有来自哪些地方的SSRC源了;此后,每经过混合器发送的流,SSRC都填写混合器自己的SSRC,而CSRC则填写流本身自己的SSRC,这样接收方接收到后就知道这个流来自哪里了


H264+RTP组合

RTP与H264组合包在实际发送中,还会再添加RTP的Header头,类似于NAL Header,占用1个字节,添加在RTP协议头后面,NALU前面,如下:

      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+

对应不同的组包方式,如一个RTP包含几个NALU单元,这里展示最简单的,一个RTP包一个NALU单元,直接删除掉NALU的startCode即可,上述:
F= NALU fobidden
NRI = NALU nal ref idc
type = NALU type
就是一一对应关系,同时删除NALU的start code部分,如下:

       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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |F|NRI|  type   |                                               |
      +-+-+-+-+-+-+-+-+                                               |
      |                                                               |
      |               Bytes 2..n of a Single NAL unit                 |
      |                                                               |
      |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                               :...OPTIONAL RTP padding        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

注意:删除NALU startcode,同时因为NALU header也已经补充到了RTP的相关bit位了,那NALU的header也要省略掉了,最后RTP的协议头在以上数据的最前面(上图没有写出来),F、NRI和Type前面

关于其他组包方式,可以参考H264协议数据如何封装成RTP协议数据,再次感谢jwybobo2007作者


扩展阅读

RTP包封装好后,选择哪个传输层协议就由你定义了,这里提供一个mbedtls传输加密库,由ARM公司研发开源的,特别适合以ARM结构基础的嵌入式系统

我的项目笔记,请不要点开

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅气好男人_Jack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值