1. H.264码流结构

  H.264编码规范从逻辑上划分为视频编码层(VCL)和网络提取层(NAL)。
  VCL数据是由编码器直接输出的原始数据比特串(SODB),它表示图像被压缩后的编码比特流。
  VCL数据要在网络上传输或者存储到磁盘上之前,需要先被封装或映射进NAL单元(NALU)中,每个NAL单元之前需要添加StartCodePrefix,最后形成H.264码流,H.264码流结构如图1-1所示(annex-b byte stream format,详见H.264建议书附录B部分)。

图1-1 H.264码流结构
  关于H.264码流结构的详细内容可以参考我的另一篇文章:
  《 H.264码流格式》

2. NALU结构

  H.264码流由NALU序列组成,通过RTP协议封装和传输H.264码流实际上就是对H.264序列中NALU的封装和传输。在介绍RTP打包封装H.264码流之前,我们先来简单了解NALU的结构。
  NAL单元(NAL Unit,简称NALU)由1个NAL头(NAL Header)和1个RBSP(或EBSP)组成。
  NAL头(NAL Header)长度为1个字节,由“forbidden_zero_bit”、“nal_ref_idc”和“nal_unit_type”三个字段组成。NAL Header结构如果图2-1所示:

图2-1 NAL Header结构
  F:forbidden_zero_bit,1位,初始为0,当NAL单元在网络传输过程中识别为错误时,可设置该字段为 1,以便接收方纠错或丢掉该单元。
  NRI:nal_ref_idc,2 位,用来指示该NALU 的重要性等级。值越大,越重要,解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU。
  TYPE:nal_unit_type ,5 位,指出NALU 的类型。
nal_unit_type 是指包含在NALU中的 RBSP 数据结构的类型,取值如下图所示:

图 2-2 nal_unit_type
  nal_unit_type的值在1到5之间的NALU称为VCL NALU,其余的称为非VCL NALU。
  通过图2-2可以看到,nal_unit_type的取值除了H.264编码占用了一部分以外(取值为0~23),剩下的一部分(取值为24~31)在RTP打包时会使用。

3. RTP打包模式

3.1 RTP包结构

  RTP包由rtp header和rtp payload组成,RTP包结构如图3-1所示:

图 3-1 RTP包结构
  使用RTP打包H.264码流时,定义了三个不同的载荷结构:单一NAL单元包、组合包和分片单元。
  接收者可以通过payload的第一个字节识别载荷结构,我们称它为payload header。
  payload header总是被格式化为NALU header,也就是说它和NALU header的结构一致,各字段具有相同意义。
  payload header的TYPE字段用于描述payload中NALU的类型,通过图2-2可以看到,RTP打包时使用了24~31之间的TYPE值。
  图3-2描述了payload中NALU类型和载荷结构分类。

图 3-2 NALU类型和载荷结构

3.2 载荷结构

  载荷结构分为单个NAL单元包、组合包和分片单元三种类型。
  需要注意的是载荷结构并不等同于打包模式,它只是打包模式的子集,每个打包模式都支持若干个载荷结构,我们将在下一节描述每种打包模式支持的载荷结构。

3.2.1 单个NAL单元包

  单个NAL单元包是指,H.264码流(NALU序列)中的每个NALU都独立封装成一个RTP包,不拆分,不组合。
  单个NAL单元包的打包示意图如下:

图 3-3 单个NAL单元包
  单个NAL单元包必须只包含TYPE为1~23的NAL单元。这意味着组合包和分片单元不可以用在单个NAL单元包中。一个封装单个NAL单元包到RTP的NAL单元流的RTP序号必须符合NAL单元的解码顺序。单个NAL单元包的结构如图3-4所示。

图 3-4 单个NAL单元包结构

3.2.2 组合包

  组合包是指,H.264码流(NALU序列)中有若干NALU尺寸特别小,因此可以将多个NALU进行组合后封装进一个RTP包。
  组合包的打包示意图如下:

图 3-5 组合包

3.2.3 分片单元(FUs)

  分片单元是指,H.264码流(NALU序列)中NALU长度超过MTU大小限制,因此需要将这样的NALU进行分片。
  FU-A分片单元的打包示意图如下:

图 3-6 FU-A分片单元
  分片只定义于单个NAL单元不用于任何组合包。NAL单元的一个分片由整数个连续NAL单元字节组成。每个NAL单元字节必须正好是该NAL单元一个分片的一部分。相同NAL单元的分片必须使用递增的RTP序号连续顺序发送(第一和最后分片之间没有其他的RTP包)。相似,NAL单元必须按照RTP顺序号的顺序装配。
  当一个NAL单元被分片运送在分片单元(FUs)中时,被引用为分片NAL单元。 STAPs,MTAP不可以被分片。FUs不可以嵌套。即,一个FU 不可以包含另一个FU。
  运送FU的RTP时戳被设置成被分片NALU的时戳。
  图3-7表示FU-A的RTP荷载格式。 FU-A由1字节的分片单元指示(FU indicator),1字节的分片单元头(FU Header),和分片单元荷载(FU payload)组成。

图 3-7 FU-A分片结构
  FU indicator结构如下:

图 3-8 FU indicator结构
  FU indicator结构和payload header结构一致,TYPE为28代表FU-A分片,TYPE为29代表FU-B分片。
  Fu header结构如下:

图 3-9 FU header结构
  S:1 bit,开始位
  当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0。
  E:1 bit,结束位
  当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的FU荷载不是分片NAL单元的最后分片,结束位设置为0。
  R:1 bit,保留位
  保留位必须设置为0,接收者必须忽略该位。
  TYPE:5 bit,NALU类型
  与被分片的NALU类型一致。

3.3 打包模式

  基于H.264码流的RTP打包模式分为三种:
  (1)单NAL单元模式
  (2)非交错模式
  (3)交错模式
  图3-10总结了每种打包模式支持的NALU类型:

图 3-10 打包模式支持的NALU类型

4. 非交错打包模式组帧实例分析

  抓包实例文件下载地址:
  FU-A分片实例.7z
  文件“FU-A分片实例.7z”中包含两个文件:
  (1) FUA_SLICE.pcap,抓取的一段基于H.264码流的RTP包,打包模式为非交错模式,包含两种载荷结构:单个NAL单元包和FU-A分片单元。
  (2) frame.bin,从抓包文件中组出一个完整的IDR帧,包括SPS、PPS、SEI和4个IDR_SLICE。
  FUA_SLICE.pcap中一个完整的IDR帧包括序列号从23861到23896的RTP包,组帧示意图如下:

图 4-1 IDR组帧
  从图4-1可以看出,一个IDR帧包括了4个IDR_SLICE,每个IDR_SLICE都是完整图像的一部分,可以被独立解码。
  frame.bin中包含的就是从RTP包序列号23861到23896组装的完整IDR帧,其NALU序列为:SPS+PPS+SEI+SEI+IDR_SLICE(0)+ IDR_SLICE(1)+ IDR_SLICE(2)+ IDR_SLICE(3),如果4-2所示:

图 4-2 NALU序列

基于H.264的RTP打包原理和FU-A分片实例分析相关推荐

  1. 基于android手机实时监控ipcam视频之三:H.264的RTP打包解析

    因为项目中,ipcam的视频编码方式主要是基于H.264,因此ipcam出来的H.264码流会按照协议rfc3984来打包,mediastream2中收到rtp recv filter的数据后,必须先 ...

  2. 转 基于H.264的远程视频监控

    基于H.264的远程视频监控  分类: 嵌入式   http://blog.chinaunix.net/uid-26851094-id-3276088.html 有兴趣的留言一起研究     开始做自 ...

  3. 基于H.264的远程视频监控

    有兴趣的留言一起研究     开始做自己的毕业设计了,希望这个暑假能把毕业设计搞完,下学期就去找工作,希望能早到一份好工作.回到正题,经过几天的摸索对H.264远程监控有了一定的认识,特别是图像采集这 ...

  4. (转)基于H.264的远程视频监控

    http://blog.chinaunix.net/uid-26851094-id-3276088.html 有兴趣的留言一起研究     开始做自己的毕业设计了,希望这个暑假能把毕业设计搞完,下学期 ...

  5. H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式

    H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +------------ ...

  6. H.264的RTP封装(下)

    H.264的RTP封装(下) 3. RTP封装实现 3.1 封装程序流程图 4. RTP解封装实现 4.1 解封装程序流程图 5. 总结 愚见,望指正! 6. 参考文献 [1] Schuzrinne ...

  7. 深入理解视频编解码技术----基于H.264标准及参考模型 读书笔记

    书名: <深入理解视频编解码技术--基于H.264标准及参考模型> 第一章 1.各种变换,如DCT, 离散傅里叶变换等,是为了变换到另一个域中,便于对图像进行压缩(如果加入预测,残差值会更 ...

  8. 简单辨析关系和区别:YUV、H.264、RTP、UDP、RTSP

    在视频传输的过程中,涉及到的流程比较多,这些流程以及各环节的格式容易让人眼花缭乱,在此做一个简单分辨. 一个常见的视频流程如下: 摄像机-->网络-->计算机(显示器) 从功能上来讲,是下 ...

  9. H.264视频RTP负载格式/NALU的类型

    1. 网络抽象层单元类型(NALU) NALU 头由一个字节组成, 它的语法如下:       +===============+       |0|1|2|3|4|5|6|7|       +=+= ...

最新文章

  1. 关于不过洋节的通知_迁安各商家从今往后不再过“洋节”!
  2. 部署时服务端Excel的COM设置
  3. Jquery 单击_双击_鼠标经过_鼠标离开_背景样式变化
  4. 如何快速测试与数据库的连接并得到连接字符串
  5. 服务熔断、降级、限流、异步RPC -- HyStrix
  6. 面经——Java基础
  7. c语言程序设计考试改革,C语言程序设计课程考试改革实施方案.pdf
  8. html提交多个正则表达式,将多个html文件的正则表达式结果写入.txt outfile
  9. Linux 系统应用编程——多线程经典问题(生产者-消费者)
  10. ASIHTTPRequest详解
  11. 从源码看spring applicationContext在web容器中加载过程
  12. imx6 android8流畅,NXP iMX8和iMX6 ARM处理器网络性能对比
  13. 关闭WPS右键菜单,以及热点,广告弹窗推送
  14. 云计算 - 虚拟化技术 - 总结
  15. 南理工计算机专业好吗,吉大计算机or南理工计算机?(江苏考生)
  16. 模拟信号的采样定理MATLAB实现
  17. 服务器怎么连接无线路由器怎么设置,光猫连接无线路由器怎么设置
  18. owncloud创建app
  19. 笔记本电脑上的触摸板怎样关闭(神州战神)
  20. jquery实现输入框实时统计字数和设置字数限制功能

热门文章

  1. 沃谈小知识丨通俗科普4G、5G CPE
  2. Python 定时发送【每日天气】和【每日简报】至【邮件】或【钉钉】(代码部署在云服务器)
  3. CKEditor和CKFinder及CKEditor配置属性说明
  4. Windows update
  5. 英语字母c的语言教案,[小班英语教案认识字母]幼儿园小班英语教案:字母C
  6. 92.【SpringCloud NetFilx】
  7. 《Adobe Photoshop CS6中文版经典教程(彩色版)》—第2课2.7节使用海绵工具调整饱和度...
  8. gdut-与蓝神一起戳气球 hnust-硬币翻转 - 博弈论
  9. Java导出PDF样式详细解析(步骤+代码)
  10. 微信王者服务器怎么删掉,王者荣耀怎么删除微信好友 又快又好