1、学习思路

在了解rtp对h264数据的打包之前,需要对rtp、h264的一些基本概念有一个初步的了解,然后再使用rtp对h264的打包解包做解析

2、rtp认知

实时传送协议(Real-time Transport Protocol或简写RTP,也可以写成RTTP)是一个网络传输协议,它是由IETF的多媒体传输工作小组1996年在RFC 1889中公布的。
RTP协议详细说明了在互联网上传递音频和视频的标准数据包格式。它一开始被设计为一个多播协议,但后来被用在很多单播应用中。RTP协议常用于流媒体系统(配合RTCP协议或者RTSP协议)。因为RTP自身具有Time stamp所以在ffmpeg 中被用做一种formate.
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                        |
   |                             ....                                                                         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
上图引自rfc3550,由上图中可知道RTP报文由两个部分构成--RTP报头和RTP的负载:
RTP报文由两部分组成:报头和有效载荷。RTP报头格式如图6.7所示,其中:
1.V:RTP协议的版本号,占2位,当前协议版本号为2。
2. P:填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
3. X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头。
4.  CC:CSRC计数器,占4位,指示CSRC 标识符的个数。
5. M: 标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。
6. PT: 有效载荷类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等,在流媒体中大部分是用来区分音频流和视频流的,这样便于客户端进行解析。
7. 序列号:占16位,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。这个字段当下层的承载协议用UDP的时候,网络状况不好的时候可以用来检查丢包。同时出现网络抖动的情况可以用来对数据进行重新排序,在helix服务器中这个字段是从0开始的,同时音频包和视频包的sequence是分别记数的。
8. 时戳(Timestamp):占32位,时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。
9. 同步信源(SSRC)标识符:占32位,用于标识同步信源。该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。
10. 特约信源(CSRC)标识符:每个CSRC标识符占32位,可以有0~15个。每个CSRC标识了包含在该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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      defined by profile                  |           length                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        header extension                                                   |
   |                             ....                                                                             |

3、h264认知

H264数据2层结构:
一:视频编码层(VCL)
二:网络适配层(NAL)
    在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。NAL占一个字节。
    NAL单元(NALU):NAL的基本语法结构,它包含一个字节的头信息和一系列来自VCL的称为原始字节序列载荷(RBSP)的字节流。
数据流是储存在介质上时: 每个NALU 前添加起始码:0x00000001(或者0x000001),用来指示一个 NALU的起始和终止位置。

NALU头由一个字节组成, 它的语法如下:
      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+
F: 1 个比特.
  forbidden_zero_bit. 在 H.264 规范中规定了这一位必须为 0.
NRI: 2 个比特.
  nal_ref_idc. 取 00 ~ 11, 似乎指示这个 NALU 的重要性, 如 00 的 NALU 解码器可以丢弃它而不影响图像的回放. 不过一般情况下不太关心
这个属性.
Type: 5 个比特.
 nal_unit_type. 这个 NALU 单元的类型. 简述如下:
0    没有定义
1     一个非IDR图像的编码条带 (bp帧)
slice_layer_without_partitioning_rbsp( )     
2     编码条带数据分割块A
slice_data_partition_a_layer_rbsp( )     
3     编码条带数据分割块B
slice_data_partition_b_layer_rbsp( )     
4     编码条带数据分割块C
slice_data_partition_c_layer_rbsp( )     
5     IDR图像的编码条带 (i帧)
slice_layer_without_partitioning_rbsp( )     
6     辅助增强信息 (SEI)
sei_rbsp( )     
7     序列参数集 (sps帧)
seq_parameter_set_rbsp( )     
8     图像参数集
pic_parameter_set_rbsp( pps帧)     
9     访问单元分隔符
access_unit_delimiter_rbsp( )     
10     序列结尾
end_of_seq_rbsp( )     
11     流结尾
end_of_stream_rbsp( )     
12     填充数据
filler_data_rbsp( )     
13     序列参数集扩展
seq_parameter_set_extension_rbsp( )     
14...18     保留     
19     未分割的辅助编码图像的编码条带
slice_layer_without_partitioning_rbsp( )     
20...23     保留     
24    STAP-A   单一时间的组合包
25    STAP-B   单一时间的组合包
26    MTAP16   多个时间的组合包
27    MTAP24   多个时间的组合包
28    FU-A     分片的单元
29    FU-B     分片的单元
30-31 没有定义

4、rtp 对h264的打包和解包

rtp 打包结构分类:
  1. 单一 NAL 单元模式
     即一个 RTP 包仅由一个完整的 NALU 组成. 这种情况下 RTP NAL 头类型字段和原始的 H.264的
  NALU 头类型字段是一样的.
  2. 组合封包模式
    即可能是由多个 NAL 单元组成一个 RTP 包. 分别有4种组合方式: STAP-A, STAP-B, MTAP16, MTAP24.
  那么这里的类型值分别是 24, 25, 26 以及 27.
  3. 分片封包模式
    用于把一个 NALU 单元封装成多个 RTP 包. 存在两种类型 FU-A 和 FU-B. 类型值分别是 28 和 29.通用采用FU-A 。
2.1 单一 NAL 单元模式
  对于 NALU 的长度小于 MTU 大小的包, 一般采用单一 NAL 单元模式.
  对于一个原始的 H.264 NALU 单元常由 [Start Code] [NALU Header] [NALU Payload] 三部分组成, 其中 Start Code 用于标示这是一个
NALU 单元的开始, 必须是 "00 00 00 01" 或 "00 00 01", NALU 头仅一个字节, 其后都是 NALU 单元内容.
  打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码, 把其他数据封包的 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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |F|NRI|  type   |                                                                                 |
      +-+-+-+-+-+-+-+-+                                                                           |
      |                                                                                                         |
      |               Bytes 2..n of a Single NAL unit                                    |
      |                                                                                                          |
      |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                               :...OPTIONAL RTP padding                          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

如有一个 H.264 的 NALU 是这样的:
  [00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]
  这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是 NALU 内容.
  封装成 RTP 包将如下:
  [ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]
  即只要去掉 4 个字节的开始码就可以了.

2.2 组合封包模式
  其次, 当 NALU 的长度特别小时, 可以把几个 NALU 单元封在一个 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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                          RTP Header                                                         |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |STAP-A NAL HDR |         NALU 1 Size           | NALU 1 HDR    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                         NALU 1 Data                                                          |
      :                                                               :
      +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |               | NALU 2 Size                   | NALU 2 HDR    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                         NALU 2 Data                                                         |
      :                                                               :
      |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                               :...OPTIONAL RTP padding                          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.3 分片打包(FU A).
  而当 NALU 的长度超过 MTU 时, 就必须对 NALU 单元进行分片封包. 也称为 Fragmentation Units (FUs).
 
       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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      | FU indicator  |   FU header   |                                                      |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                              |
      |                                                                                                          |
      |                         FU payload                                                            |
      |                                                                                                          |
      |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                               :...OPTIONAL RTP padding                          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      Figure 14.  RTP payload format for FU-A
   The FU indicator octet has the following format:
      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+
      F     NALU头中的F
      NRI     NALU头中的NRI
      type    28 表示 FU-A打包
   The FU header has the following format:
      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |S|E|R|  Type   |
      +---------------+
      S     bit为1表示分片的NAL开始,当它为1时,E不能为1
      E     bit为1表示结束,当它为1,S不能为1
      R     bit保留位,必须是0
      Type    就是NALU头中的Type,取1-23的那个值

分片打包解包实例:

80 60 01 0f 00 0e 1000 00 00 00 00 7c 85 8882

00 0a 7f  ca 94 053b 7f  3e 7f  fe14  2b 27 26 f8

89 88 dd85 62 e1 6dfc 33 01 38 1a 10 35 f214

84 6e 21 24 8f  7262 f0 51 7e 10 5f 0d 42 71 12

17 65 62 a1 f1  44dc df 4b 4a 38 aa 96 b7dd 24

前12字节为RTP头

7c是分片单元指示,01111100 1c-28(FU-A)

85是分片单元头, 1000 0101NAl Type=5(关键帧)

解包时,取FU-A indicator的前三位和FU Header的后五位,即01100101(0x65)为NAL类型

rtp h264打包和解包相关推荐

  1. RTP之H264封包和解包

    RTP之H264封包和解包 目录 H264打包RTP的方法 打包方式之Single NAL Unit 打包方式之FU-A FU indication FU header 1. H264打包RTP的方法 ...

  2. Python赋值、打包和解包,90%人不清楚的知识点!

      人生苦短,快学Python! 关于赋值.打包和解包这 3个概念,我觉得有必要做一个分享,因为很多朋友确实不清楚. 如果有这样一个元组t: >> t = ('foo', 'bar', ' ...

  3. Python从入门到实践:打包和解包(*和**)的使用

    目录 一.打包参数 二.解包参数 三.几点注意 *和**在函数的定义和调用阶段,有着不同的功能,并且,*和**不能离开函数使用! 一.打包参数 * 的作用:在函数定义中,收集所有位置参数到一个新的元组 ...

  4. android 根目录 文件 打包,Android image文件的打包和解包

    Android image文件的打包和解包 平台:msm8909+android5.1 用file *查看img文件的类型: 图1 Ramdisk.img和ramdisk-recovery.img为g ...

  5. [oeasy]python0019_ 打包和解包_struct_pack_unpack

    打包和解包 回忆上次内容 ASCII 由这样几类字符构成 英文大写字符 英文小写字符 数字 符号 电报时代对于英文.数字的编码 使用的是摩斯电码 这摩斯电码是3进制的编码方式 长短空 怎么演化成asc ...

  6. python基础第五课--从字符串中打包和解包大整数(小白piao分享)

    #4.从字符串打包和解包大整数 #将一个字符串解包成一个大整数,将一个大整数打包成一个字符串 #4.1 解决方案: #假设程序需要处理一个有16个元素的字节串,其中保存着一个128位的大整数 data ...

  7. linux打包文件命令行,Linux 命令行 | 打包和解包命令

    .tar 解包:tar  xvf  FileName.tar 打包:tar  cvf  FileName.tar  fName  (单个文件打包) tar  cvf  FileName.tar   f ...

  8. Java 集合之自动打包和解包以及泛型

    自动打包与解包: 泛型: 上栗子: TestMap1.java: package com.zhj.www; import java.util.*;public class TestMap {publi ...

  9. pak文件的打包和解包

    pak格式的文件 一般游戏有资源 游戏素材会打包放进去 比如游戏语音 游戏多加点语音  多加一些贴图资源 外部文件实现的 素材--->pak文件--->用的时候从文件中取出来 文件的打包 ...

最新文章

  1. python读取excel画散点图-matplotlib两种画散点图的方式
  2. Kubernetes 2018 年度简史
  3. python初学者用什么开发环境_python初学者用什么开发环境
  4. 光驱怎么挂载第二个光驱_电脑光驱经常自己打开自己关闭,怎么回事
  5. HTML精仿ios相册,iOS开发-仿微信相册选择Demo
  6. python 中的运算符重载
  7. Sublime Text 3安装、配置和快捷键
  8. python爬虫难度排行榜_无聊写了一个python爬虫程序,用来爬夕阳试炼场排行榜的...
  9. mappedBy reference an unknown target entity property错误
  10. VBS基础教程(收藏)
  11. html导航栏可以展开的下拉菜单,html导航栏下拉菜单如何制作
  12. 十大算法之迪杰斯特拉算法
  13. WSL2 真香!跟 Sugar 一起搞定 Windows 10 最佳 Linux 伴侣
  14. 基金公司以及各大平台发布的那些亮眼的收益率数据,是你个人真实的投资收益率吗
  15. 题目0073-双十一
  16. 八边形类 Octagon
  17. 人工神经网络与神经网络,消息传递神经网络
  18. GetKeyState()和GetAsyncKeyState()的区别
  19. 多模态 |COGMEN: COntextualized GNN based Multimodal Emotion recognitioN论文详解
  20. linux aria2界面,如何使用aria2及webui

热门文章

  1. tf.ConfigProto()详解
  2. linux查看python线程,Python多线程详解
  3. centos离线安装mysql8_CentOS7离线安装Mysql8.0
  4. c++ 从混合中英文数字等的string 中按顺序分别输出
  5. 17.Spark第1部分
  6. Android(安卓)一个简单的聊天界面的实现(eclipse实现)
  7. 通过踩坑带你读透虚拟机的“锁粗化”
  8. QuartZ Cron表达式详解
  9. Hibernate开发中常见错误总结
  10. 让latex写论文更方便的几个工具