H.264/H265码流解析
H.264/H265码流解析
一.H.264码流解析
一个原始的H.264 NALU 单元常由 [StartCode] [NALU Header] [NALU Payload] 三部分组成
一个原始的H.264 NALU 单元常由 [StartCode] [NALU Header] [NALU Payload] 三部分组成

NALU组成.jpeg
- StartCode : Start Code 用于标示这是一个NALU 单元的开始,必须是”00 00 00 01” 或”00 00 01”
- NALU Header
下表为 NAL Header Type

NAL Header Type.png
例如,下面幅图分别代表IDR与非IDR帧具体的码流信息:

2.IDR
在一个NALU中,第一个字节(即NALU header)用以表示其包含数据的类型及其他信息。我们假定一个头信息字节为0x67作为例子:
|
十六进制 |
二进制 |
|
0x67 |
0 11 00111 |
如表所示,头字节可以被解析成3个部分,其中:
1>.
forbidden_zero_bit = 0:占1个bit,禁止位,用以检查传输过程中是否发生错误,0表示正常,1表示违反语法;
2>. nal_ref_idc
= 3:占2个bit,用来表示当前NAL单元的优先级。非0值表示参考字段/帧/图片数据,其他不那么重要的数据则为0。对于非0值,值越大表示NALU重要性越高
3>.
nal_unit_type = 7:最后5位用以指定NALU类型,NALU类型定义如上表
从表中我们可以获知,NALU类型1-5为视频帧,其余则为非视频帧。在解码过程中,我们只需要取出NALU头字节的后5位,即将NALU头字节和0x1F进行与计算即可得知NALU类型,即:
NALU类型 = NALU头字节 & 0x1F
注意: 可以将start code理解为不同nalu的分隔符,header是某种类型的key,payload是该key的value.
码流格式
H.264标准中指定了视频如何编码成独立的包,但如何存储和传输这些包却未作规范,虽然标准中包含了一个Annex附件,里面描述了一种可能的格式Annex B,但这并不是一个必须要求的格式。
为了针对不同的存储传输需求,出现了两种打包方法。一种即Annex B格式,另一种称为AVCC格式。
- Annex B
从上文可知,一个NALU中的数据并未包含他的大小(长度)信息,因此我们并不能简单的将一个个NALU连接起来生成一个流,因为数据流的接收端并不知道一个NALU从哪里结束,另一个NALU从哪里开始。
Annex B格式用起始码(Start Code)来解决这个问题,它在每个NALU的开始处添加三字节或四字节的起始码0x000001或0x00000001。通过定位起始码,解码器就可以很容易的识别NALU的边界。
当然,用起始码定位NALU边界存在一个问题,即NALU中可能存在与起始码相同的数据。为了防止这个问题,在构建NALU时,需要将数据中的0x000000,0x000001,0x000002,0x000003中插入防竞争字节(Emulation Prevention Bytes)0x03,使其变为:
0x000000 = 0x0000
03 00
0x000001 = 0x0000 03 01
0x000002 = 0x0000 03 02
0x000003 = 0x0000 03 03
解码器在检测到0x000003时,将0x03抛弃,恢复原始数据。
由于Annex B格式每个NALU都包含起始码,所以解码器可以从视频流随机点开始进行解码,常用于实时的流格式。在这种格式中通常会周期性的重复SPS和PPS,并且经常时在每一个关键帧之前。
- AVCC
AVCC格式不使用起始码作为NALU的分界,这种格式在每个NALU前都加上一个指定NALU长度的大端格式表示的前缀。这个前缀可以是1、2或4个字节,所以在解析AVCC格式的时候需要将指定的前缀字节数的值保存在一个头部对象中,这个都通常称为extradata或者sequence header。同时,SPS和PPS数据也需要保存在extradata中。
H.264 extradata语法如下:
|
bits |
line by byte |
remark |
|
|
8 |
version |
always |
0x01 |
|
8 |
avc profile |
sps[0][1] |
|
|
8 |
avc compatibility |
sps[0][2] |
|
|
8 |
avc level |
sps[0][3] |
|
|
6 |
reserved |
all bits on |
|
|
2 |
NALULengthSizeMinusOne |
||
|
3 |
reserved |
all bits on |
|
|
5 |
number of SPS NALUs usually |
1 |
|
|
16 |
SPS size |
||
|
N |
variable SPS NALU data |
||
|
8 |
number of PPS NALUs usually |
1 |
|
|
16 |
PPS size |
||
|
N |
variable PPS NALU data |
其中第5字节的后2位表示的就是NAL size的字节数。需要注意的是,这个NALULengthSizeMinusOne是NALU前缀长度减一,即,假设前缀长度为4,那么这个值应该为3。
这里还需要注意的一点是,虽然AVCC格式不使用起始码,但防竞争字节还是有的。
AVCC格式的一个优点在于解码器配置参数在一开始就配置好了,系统可以很容易的识别NALU的边界,不需要额外的起始码,减少了资源的浪费,同时可以在播放时调到视频的中间位置。这种格式通常被用于可以被随机访问的多媒体数据,如存储在硬盘的文件。
二.
H.265码流解析
HEVC全称High Efficiency Video Coding(高效率视频编码,又称H.265),是比H.264更优秀的一种视频压缩标准。HEVC在低码率视频压缩上,提升视频质量、减少容量即节省带宽方面都有突出表现。
H.265标准围绕H.264编码标准,保留原有的某些技术,同时对一些技术进行改进,编码结构大致上和H.264的架构类似。这里着重讲一下两者编码格式的区别。
同H.264一样,H.265也是以NALU的形式组织起来。而在NALU header上,H.264的HALU header是一个字节,而H.265则是两个字节。我们同样假定一个头信息为0x4001作为例子:
|
十六进制 |
二进制 |
|
0x4001 |
0 100000 000000 001 |
如表所示,头信息可以被解析成4个部分,其中:
- forbidden_zero_bit
= 0:占1个bit,与H.264相同,禁止位,用以检查传输过程中是否发生错误,0表示正常,1表示违反语法; - nal_unit_type = 32:占6个bit,用来用以指定NALU类型
- nuh_reserved_zero_6bits
= 0:占6位,预留位,要求为0,用于未来扩展或3D视频编码 - nuh_temporal_id_plus1
= 1:占3个bit,表示NAL所在的时间层ID
对比H.264的头信息,H.265移除了nal_ref_idc,此信息被合并到了nal_unit_type中,H.265NALU类型规定如下:
|
nal_unit_type |
NALU类型 |
备注 |
|
0 |
NAL_UNIT_CODE_SLICE_TRAIL_N |
非关键帧 |
|
1 |
NAL_UNIT_CODED_SLICE_TRAIL_R |
|
|
2 |
NAL_UNIT_CODED_SLICE_TSA_N |
|
|
3 |
NAL_UINT_CODED_SLICE_TSA_R |
|
|
4 |
NAL_UINT_CODED_SLICE_STSA_N |
|
|
5 |
NAL_UINT_CODED_SLICE_STSA_R |
|
|
6 |
NAL_UNIT_CODED_SLICE_RADL_N |
|
|
7 |
NAL_UNIT_CODED_SLICE_RADL_R |
|
|
8 |
NAL_UNIT_CODED_SLICE_RASL_N |
|
|
9 |
NAL_UNIT_CODE_SLICE_RASL_R |
|
|
10 ~ 15 |
NAL_UNIT_RESERVED_X |
保留 |
|
16 |
NAL_UNIT_CODED_SLICE_BLA_W_LP |
关键帧 |
|
17 |
NAL_UNIT_CODE_SLICE_BLA_W_RADL |
|
|
18 |
NAL_UNIT_CODE_SLICE_BLA_N_LP |
|
|
19 |
NAL_UNIT_CODE_SLICE_IDR_W_RADL |
|
|
20 |
NAL_UNIT_CODE_SLICE_IDR_N_LP |
|
|
21 |
NAL_UNIT_CODE_SLICE_CRA |
|
|
22 ~ 31 |
NAL_UNIT_RESERVED_X |
保留 |
|
32 |
NAL_UNIT_VPS |
VPS(Video Paramater Set) |
|
33 |
NAL_UNIT_SPS |
SPS |
|
34 |
NAL_UNIT_PPS |
PPS |
|
35 |
NAL_UNIT_ACCESS_UNIT_DELIMITER |
|
|
36 |
NAL_UNIT_EOS |
|
|
37 |
NAL_UNIT_EOB |
|
|
38 |
NAL_UNIT_FILLER_DATA |
|
|
39 |
NAL_UNIT_SEI |
Prefix SEI |
|
40 |
NAL_UNIT_SEI_SUFFIX |
Suffix SEI |
|
41 ~ 47 |
NAL_UNIT_RESERVED_X |
保留 |
|
48 ~ 63 |
NAL_UNIT_UNSPECIFIED_X |
未规定 |
|
64 |
NAL_UNIT_INVALID |
具体type含义可以参考这篇文档type类型
H.265的NALU类型是在信息头的第一个字节的第2到7位,所以判断H.265NALU类型的方法是将NALU第一个字节与0x7E进行与操作并右移一位,即:
NALU类型 = (NALU头第一字节 & 0x7E) >> 1
与H.264类似,H.265码流也有两种封装格式,一种是用起始码作为分界的Annex B格式,另一种则是在NALU头添加NALU长度前缀的格式,称为HVCC。在HVCC中,同样需要一个extradata来保存视频流的编解码参数,其格式定义如下:
|
bits |
line by byte |
remark |
|
8 |
configurationVersion |
always 0x01 |
|
2 |
general_profile_space |
|
|
1 |
general_tier_flag |
|
|
5 |
general_profile_idc |
|
|
32 |
general_profile_compatibility_flags |
|
|
48 |
general_constraint_indicator_flags |
|
|
8 |
general_level_idc |
|
|
4 |
reserved |
‘1111’b |
|
12 |
min_spatial_segmentation_idc |
|
|
6 |
reserved |
‘111111’b |
|
2 |
parallelismType |
|
|
6 |
reserved |
‘111111’b |
|
2 |
chromaFormat |
|
|
5 |
reserved |
‘11111’b |
|
3 |
bitDepthLumaMinus8 |
|
|
5 |
reserved |
‘11111’b |
|
3 |
bitDepthChromaMinus8 |
|
|
16 |
avgFrameRate |
|
|
2 |
constantFrameRate |
|
|
3 |
numTemporalLayers |
|
|
1 |
tmporalIdNested |
|
|
2 |
lengthSizeMinusOne |
|
|
8 |
numOfArrays |
Repeated of
Array(VPS/SPS/PPS)
1| array_completeness
1| reserved| ‘0’b
6| NAL_unit_type
16| numNalus
16| nalUnitLength
N| NALU data
从上表可以看到,在H.265的extradata后半段是一段格式重复的数组数据,里面需要包含的除了与H.264相同的SPS、PPS外,还需多添加一个VPS。
VPS(Video Parament Set,视频参数集),在H.265中类型为32。VPS用于解释编码过的视频的整体结构,包括时域子层依赖关系等,主要目的在于兼容H.265标准在系统的多子层方面的扩展。
H.264/H265码流解析的更多相关文章
- 视音频数据处理入门:H.264视频码流解析
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- 【视频编解码·学习笔记】4. H.264的码流封装格式
一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...
- 【视频编解码·学习笔记】4. H.264的码流封装格式 & 提取NAL有效数据
一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...
- 视音频数据处理入门:AAC音频码流解析
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- Wireshark Lua: 一个从RTP抓包里导出H.264 Payload,变成264裸码流文件(xxx.264)的Wireshark插件
Wireshark Lua: 一个从RTP抓包里导出H.264 Payload,变成264裸码流文件(xxx.264)的Wireshark插件 在win7-64, wireshark Version ...
- 【雷神源码解析】无基础看懂AAC码流解析,看不懂你打我
一 前言 最近在尝试学习一些视频相关的知识,随便一搜才知道原来国内有雷神这么一个真正神级的人物存在,尤其是在这里(传送门)看到他的感言更是对他膜拜不已,雷神这种无私奉献的精神应当被我辈发扬光大.那写这 ...
- H265码流格式
一.H265码流格式 VPS:视频参数集,用于传输视频分级信息,有利于兼容标准在可分级视频编码或多视点视频的扩展. NALU header定义: NALU header(){ Descriptor f ...
- h.264码流解析_一个SPS的nalu及获取视频的分辨率
00 00 00 01 67 42 00 28 E9 00 A0 0B 77 FE 00 02 00 03 C4 80 00 00 03 00 80 00 00 1A 4D 88 10 94 0 ...
- H265码流分析
H265相比较于H264,除了包含SPS.PPS外,还多包含一个VPS:在NALU header上,H.264的HALU header是一个字节,而H.265则是两个字节. 以OX4001为例,头信息 ...
随机推荐
- 对c语言回调函数的理解
对于回调函数,可以简单的理解为一种特别的函数调用方法,我们可以对比一下回调函数与普通函数在调用方法上的区别. 1. 普通函数调用 一般为实现方在其函数体执行过程中直接调用. 代码示例: #includ ...
- Windows核心编程 第十八章 堆栈
第1 8章 堆 栈 对内存进行操作的第三个机制是使用堆栈.堆栈可以用来分配许多较小的数据块.例如,若要对链接表和链接树进行管理,最好的方法是使用堆栈,而不是第 1 5章介绍的虚拟内存操作方法或第1 7 ...
- MySQL数据库及注入方法
目录 MySQL数据库 mysql中比较常用的一些函数: 判断MySQL数据库是否存在SQL注入 MySQL数据库文件结构 MySQL数据库密码破解 MySQL UDF提权 MySQL数据库 MySQ ...
- 5.IA-32寄存器
寄存器(Register)是CPU内部用来存放数据的一些小型存储区域,它与RAM(Random Access Memory,随机存储器.内存)略有不同.CPU访问(Access)RAM中的数据时要经过 ...
- 深入浅出带你玩转sqlilabs(三)--GET,POST,COOKIE,万能密码注入
常见提交方式下的注入漏洞 WEB应用在数据传递接受中,针对SQL注入安全漏洞,由于数据大小,格式等原因,脚本在接受传递时会有多种传递方式,传递方式的不同将影响到安全测试的不同 第一点:数据常见提交方式 ...
- k3d入门指南:在Docker中运行K3s
在本文中,我们将简单了解k3d,这是一款可让您在安装了Docker的任何地方运行一次性Kubernetes集群的工具,此外在本文中我们还将探讨在使用k3d中可能会出现的一切问题. 什么是k3d? k3 ...
- Unreal: Dynamic load map from Pak file
Unreal: Dynamic load map from Pak file 目标:在程序运行时加载自定义 Pak 文件,并打开指定关卡,显示其中的完整 map 内容 Unreal 的 Pak 文件内 ...
- JDBC核心技术(获取数据库链接、数据库事务、数据库链接池)
@ 目录 前言 数据的持久化 Java数据存储技术 JDBC介绍 JDBC体系结构 获取数据库链接 Driver接口 加载注册JDBC驱动 获取数据库链接 数据库链接方式(实例) 方式一:代码中显示出 ...
- ==与equals比较
提到==与equals的区别,这就必须先回顾一下jvm内存的分配机制 ==和equals无非比较两个基本数据类型或者对象类型 八种基本类型: 基本类型 大小 默认值 封装类 byte 1 0 Byte ...
- 进入单用户模式修改root密码
进入单用户模式修改root密码 1.进入引导菜单界面2.按e进入grub,在linux或linux16那行结尾加上 rw init=/bin/bash,按Ctrl+x或F103.进入bash-4.3# ...