名词解释:NAL
NAL的英文全称为Network Abstract Layer,即网络抽象层,在H264/AVC视频编解码标准中,整个系统框架分为两个层面,视频编解码层面(VCL)和网络抽象层面(NAL)。VCL负责有效表示视频数据内容,NAL负责格式化数据并加上相应的头信息,以保证数据适合各种信道和存储介质上的传输。NAL单元NALU是NAL的基本语法结构,它包含一个字节的头信息和一系列来自VCL的原始字节载序列载荷(RBSP)的字节流。

一、H.264 NAL单元(NALU)的组成:

NALU有多种类型,分为VCL和no-VCL。
VCL(Video Coding Layer):是图像编码数据
NO-VCL:非视频信息,配置信息。 (其中sps、pps等NALU单元都是非VCL NAL单元)
关于VCL和非VCL的分类: 其中NALU单元nal_unit_type 值等于 1 到 5(包括 1 和 5)的 NAL 单元是VCL NAL单元,其他的 NAL 单元都称作非 VCL NAL 单元。

NAL单元组成由起始码、NAL头、NAL Payload三部分组成

下面详解解析NAL单元三个组成部分
1、起始码:分为3或者4字节的0x000001和0x00000001两种的开始码
2、NAL头: 长度为1字节


3、NAL Payload:具体的NAL内容payload

一个简单的例子:
NALU头为0x67,转换为二进制0110 0111
禁止位为0
NAL重要性为11,即3,表示最重要
NALU类型为[00111],即7,类型为7表示该NALU是SPS

二、RTP报文的封包格式

一共有三种模式:
1、单一NALU模式
2、组合封包模式
3、分片封包模式

1、单一NALU模式


如下面是一个SPS帧的例子:
下面是SPS帧的格式如下:SPS的NALU头中的Type值为7,表示SPS(Sequence parameter set),SPS还包含一些图像编码的一些重要配置信息,比如profile_id,level_id,图像的宽高信息等,具体如下图


上图中图像的宽高为:1920*1088

2、组合封包模式


开头1个字节表示NAL单元类型,接着1个或多个聚合单元,后面是可选的RTP填充,组合包模式有以下四种类型:

组合包模式是当H264 NALU单元的长度较小时,将几个NALU单元封装在一个RTP数据包中,以STAP-A为例进行详细介绍。

   单时刻聚合包(STAP-A)应该用于当聚合在一起的NAL单元共享相同的NALU时间。STAP-A荷载不包括DON(Decoding Order Number),并且至少包含一个单时刻聚合单元,如下图所示


single-time aggregation unit的格式如下图所示:

一个RTP包含一个STAP-A组合包,一个STAP-A包含两个单时间聚合单元的示例如下图所示:

具体数据示例:
【00 00 00 01 67 42 C0 1F 8C 8D 40 48 14 B2 F0 0F 08 84 6A】
【00 00 00 01 68 CE 3C 80】
将以上SPS、PPS两个H264 NAL单元封装成STAP-A形式如下所示:
【RTP Header】【78 00 0F 67 42 C0 1F 8C 8D 40 48 14 B2 F0 0F 08 84 6A 00 04 68 CE 3C 80 】
78:第一位表示F为,值为0;第二三位表示NRI重要程度;后五位Type,值为24,表示STAP-A类型。
00 0F:NALU 1 size
67:NALU 1 HDR
42 C0 1F 8C 8D 40 48 14 B2 F0 0F 08 84 6A:NALU 1 data
00 04:NALU 2 size
68:NALU 2 HDR
CE 3C 80:NALU 2 data

3.分片封包模式

当H264 NALU 的长度超过 MTU 时, 就必须对 NALU 单元进行分片封包. 也称为 Fragmentation Units ,主要包含FU-A和FU-B两种形式,FU-A分包格式如下图所示:

FU indicator的格式如下图所示:

F:禁止位,与NALU Header的F位一致
NRI:重要程度,与NALU Header的NRI一致
Type:分包类型,28表示FU-A类型,29表示FU-B类型

FU header的格式如下图所示:

S:占1bit,值为1,表示NAL分包的开始,其余情况值为0。
E:占1bit,值为1,表示NAL分包的结束,其余情况为0。
R:占1bit,值为0,表示保留位。
Type:占5bit,值为H264 NALU Header中的Type。

        具体数据示例:
【00 00 00 01 65 b8 00 01 4d 00 00 ff bc 5d…】
将H264 I帧进行分包,具体的分包多少由I帧的数据长度和设置分包大小决定,示例如下所示:
【RTP Header】【7c 85】【H264 Payload Data】
【RTP Header】【7c 05】【H264 Payload Data】
【RTP Header】【7c 45】【H264 Payload Data】
7c 85:表示分包开始包。
7c 05:表示分包中间包。
7c 45:表示分包结束包。通过wiereshark抓包分析协议格式:



三、H264封装示例
读取一个H264文件,封装为RTP协议格式进行传输,具体实现如下所示:

1、SPS、PPS采用单包模式发送。
2、I帧、P帧采用FU-A分包模式发送。
3、注意RTP Header中Mark标记位的设置和相对时间戳的设置。 MARK标记的是首包

知识点:
AUD:
一般文档没有对AUD进行描叙,其实这是一个帧开始的标志,字节顺序为:00 00 00 01 09 f1,从结构上看,有start code, 所以确实是一个NALU,类型09在H264定义里就是AUD(分割器)。大部分播放器可以在没有AUD的情况下正常播放。紧随AUD,一般是SPS/PPS/SEI/IDR的组合或者简单就是一个SLICE,也就是一个帧的开始。像Flash这样的播放器,每次需要一个完整的帧数据,那么把2个AUD之间的数据按照格式打包给播放器就可以了。

H.264编码时,在每个NAL前添加起始码 0x000001,解码器在码流中检测到起始码,当前NAL结束。为了防止NAL内部出现0x000001的数据,h.264又提出’防止竞争 emulation prevention"机制,在编码完一个NAL时,如果检测出有连续两个0x00字节,就在后面插入一个0x03。当解码器在NAL内部检测到0x000003的数据,就把0x03抛弃,恢复原始数据。
0x000000 -----------> 0x00000300
0x000001 -----------> 0x00000301
0x000002 -----------> 0x00000302
0x000003 -----------> 0x00000303

总的来说,H264的码流的打包方式有两种,一种为annex-b byte stream format 的格式,这个是绝大部分编码器的默认输出格式,就是每个帧的开头的3~4个字节是H264的start_code,0x00000001或者0x000001;另一种是原始的NAL打包格式,就是开始的若干字节(1,2,4字节)是NAL的长度,而不是start_code,此时必须借助某个全局的数据来获得编 码器的profile,level,PPS,SPS等信息才可以解码。

H.264的NALU单元组织格式

这里需要了解下H264打包方式,所谓打包方式就是如何组织一连串的NALU单元为完整的H264码流,目前有两种主流格式:
Annex-B 和 AVCC

一、Annex-B: :
通过起始码startCode(0x00000001或0x000001)来分割NALU,打包方式如下:
[start Code]–[NALU]–[start code]–[NALU]…

二、AVCC:
([extradata]) | ([length] NALU) | ([length] NALU) | …
这种模式也叫AVC1格式,和上述Annex-b相比没有起始码。 其中AVCC这种格式下NALU一般没有sps、pps等参数信息,这些信息属于额外数据extradata存放在其他地方。 extradata后面就是nalu数据,在每帧前面几个字节(通常是4字节)是帧长度。

第1字节:version (通常0x01)
第2字节:avc profile (值同第1个sps的第2字节)
第3字节:avc compatibility (值同第1个sps的第3字节)
第4字节:avc level (值同第1个sps的第3字节)
第5字节前6位:保留全1
第5字节后2位:NALU Length 字段大小减1,通常这个值为3,即NAL码流中使用3+1=4字节表示NALU的长度
第6字节前3位:保留,全1
第6字节后5位:SPS NALU的个数,通常为1
第7字节开始后接1个或者多个SPS数据SPS结构 [16位 SPS长度][SPS NALU data]SPS数据后
第1字节:PPS的个数,通常为1
第2字节开始接1个或多个PPS数据PPS结构 [16位 PPS长度][SPS NALU data]

上述内容参考 https://titanwolf.org/Network/Articles/Article?AID=7efa4423-1e7d-46e0-ba19-6f5c6eec84a7

关于Annex-B和AVCC两种格式总结
1、两种格式都有防止竞争字节
2、使用场景如下:

Annex B格式通常用于实时的流格式,比如说传输流,通过无线传输的广播、DVD等。在这些格式中通常会周期性的重复SPS和PPS包,经常是在每一个关键帧之前,因此据此建立解码器可以一个随机访问的点,这样就可以加入一个正在进行的流,及播放一个已经在传输的流。

AVCC格式的一个优点是在开始配置解码器的时候可以跳到流的中间播放,这种格式通常用于可以被随机访问的多媒体数据,如存储在硬盘的文件。
也因为这个特性,MP4、MKV通常用AVCC格式来存储。

RTP中H264封装NALU格式详细解析相关推荐

  1. RTP中H264封装NALU(SPS,PPS等)

    NAL的英文全称为Network  Abstract Layer,即网络抽象层,在H264/AVC视频编解码标准中,整个系统框架分为两个层面,视频编解码层面(VCL)和网络抽象层面(NAL).VCL负 ...

  2. H265 NALU类型详细解析

    1. H265 NALU类型解析 F: 禁止位,必须为0,表示有效:为1的话表示无效. Type: 6-bits NALType 确定NAL的类型,其中VCL NAL和non-VCL NAL各有32类 ...

  3. java封装264成flv,FLV视频封装格式详细解析

    FLV的定义: Flash Video(简称FLV),是一种流行的网络格式,是Adobe推出的.目前大部分视频网站都支持这种格式. FLV的文件结构 FLV文件由FLV Header 和 FLV Bo ...

  4. 森林中的兔子(超详细解析)

    森林中的兔子题目题解 题目 解析 题解一 题解二 题目 森林中,每个兔子都有颜色.其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色.我们将这些回答放在 answers 数组里. 返 ...

  5. Python中字符串前u的详细解析,以及字符串前添加'b','r'的简单解释

    一.字符串前添加u,例如u'hello 世界你好!' 中文编码问题是用中文的程序员经常头大的问题,在python下也是如此,那么应该怎么理解和解决python的编码问题呢? 我们要知道python内部 ...

  6. c 语言 可变参数前要加形参,C/C++中可变参数的用法详细解析

    可变参数即表示参数个数可以变化,可多可少,也表示参数的类型也可以变化,可以是int,double还可以是char*,类,结构体等等.可变参数是实现printf(),sprintf()等函数的关键之处, ...

  7. 【基础】TLV 报文格式详细解析

    BER 编码一种,ASN.1标准 ASN.1 浅析,全称 Type(类型),Length(长度),Value(值). IS-IS 数据通信领域中,TLV 三元组: Type-length-value( ...

  8. 流媒体开发中H264编码NALU结构介绍与I帧判断方法

    背景分析 随着互联网基础设施建设的发展,4G/5G/NB-IoT各种网络技术的大规模商用,视频随时随地可看.可控的诉求越来越多,互联网思维.架构和技术引入进传统监控行业里,成为新形势下全终端监控的基础 ...

  9. HDMI EDID格式详细解析

    在网上看到一片文章,分析HDMI EDID格式,介绍的还是蛮详细的,这里直接引用这位网友整理的数据,链接如下: https://www.likecs.com/show-204638091.html

最新文章

  1. nsTimer的简单用法
  2. IE下a标签会触发window.onbeforeunload的问题
  3. Sklearn-train_test_split随机划分训练集和测试集
  4. LINUX CP 命令强制覆盖功能开启/关闭
  5. php pdo 参数绑定,PDO预处理之参数绑定和列绑定
  6. 如何重启_消费市场按下重启键,企业该如何提前布局
  7. The import org.junit.jupiter cannot be resolved 报错
  8. 知道创宇杨冀龙:2B产品经理的自我修养
  9. 《软件开发性能优化系列》之死锁
  10. VSTT Rosario CTP
  11. 华为交换机命令基础入门学习,小白也能看得懂!
  12. 注册github账号详细中文版教程【精选】
  13. ffmpeg 双轨的mp3转成8k的wav 脚本
  14. 用计算机怎么刷试听量,QQ音乐怎么刷播放次数,快速增加播放量
  15. android 卸载预装软件,手机自带软件怎么卸载?安卓预装软件卸载方法
  16. NLP情感分析——KNN算法
  17. 计算机图标右击管理打不开,电脑图标打不开怎么办6
  18. [心灵] 我对这个世界充满了想象力和好奇心
  19. java实现图片反色
  20. Opencv inRang() 和HSV色彩空间表

热门文章

  1. Haskell99题答案
  2. Mysql主从模式部署过程
  3. 微信私域流量池运营:提升客户终生价值(LTV)之激励老客户重复购买!
  4. centos7部署minio
  5. html写微信推送,QQ/微信实现网站内容推送
  6. 评论有礼丨你关心的都安排上了!Cocos开发者沙龙「深圳站」下周回归,点击报名...
  7. AI制作金属字感的立体文字效果
  8. ObjectARX_面域
  9. java如何创建一个dao类_java – 如何设计一个DAO类?
  10. TortoiseSVN安装汉化包后没出现选择中文的选项