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码流解析的更多相关文章

  1. 视音频数据处理入门:H.264视频码流解析

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  2. 【视频编解码·学习笔记】4. H.264的码流封装格式

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

  3. 【视频编解码·学习笔记】4. H.264的码流封装格式 & 提取NAL有效数据

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

  4. 视音频数据处理入门:AAC音频码流解析

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  5. Wireshark Lua: 一个从RTP抓包里导出H.264 Payload,变成264裸码流文件(xxx.264)的Wireshark插件

    Wireshark Lua: 一个从RTP抓包里导出H.264 Payload,变成264裸码流文件(xxx.264)的Wireshark插件 在win7-64, wireshark Version ...

  6. 【雷神源码解析】无基础看懂AAC码流解析,看不懂你打我

    一 前言 最近在尝试学习一些视频相关的知识,随便一搜才知道原来国内有雷神这么一个真正神级的人物存在,尤其是在这里(传送门)看到他的感言更是对他膜拜不已,雷神这种无私奉献的精神应当被我辈发扬光大.那写这 ...

  7. H265码流格式

    一.H265码流格式 VPS:视频参数集,用于传输视频分级信息,有利于兼容标准在可分级视频编码或多视点视频的扩展. NALU header定义: NALU header(){ Descriptor f ...

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

  9. H265码流分析

    H265相比较于H264,除了包含SPS.PPS外,还多包含一个VPS:在NALU header上,H.264的HALU header是一个字节,而H.265则是两个字节. 以OX4001为例,头信息 ...

随机推荐

  1. Sqli 注入点解析

    目录 Less-1: 字符型注入 Less-2: 数字型注入 Less-3: 单引号字符型+括号 Less-4: 双引号字符型+括号 Less-5: 单引号字符型+固定输出信息 (floor报错注入& ...

  2. Windows Server系统加固

    目录 账户管理.认证授权 管理账户 管理口令 授权 审核策略 IP协议安全配置 设备其他配置操作 账户管理.认证授权 管理账户 说明: 对于管理员账号,要求更改缺省账户名称,并且禁用 guest (来 ...

  3. POJ1151基本的扫描线求面积

    题意:      给定n个矩形的对角坐标,分别是左下和右上,浮点型,求矩形覆盖的面积. 思路:       基本的线段树扫描线求面积,没有坑点,不解释了,提示一点,有的题尤其是线段树扫描线的题需要离散 ...

  4. CVE-2013-2551:Internet Explore VML COALineDashStyleArray 整数溢出漏洞简单调试分析

    0x01 2013 Pwn2Own 黑客大赛 在 Pwn2Own 的黑客大赛上,来自法国的 VUPEN 安全团队再一次利用 0day 漏洞攻破 Windows8 环境下的 IE10 浏览器,这一次问题 ...

  5. Win64 驱动内核编程-9.系统调用、WOW64与兼容模式

    系统调用.WOW64与兼容模式 这种东西都是偏向于概念的,我就把资料上的东西整理下粘贴过来,资料来源于胡文亮,感谢这位前辈. WIN64 的系统调用比 WIN32 要复杂很多,原因很简单,因为 WIN ...

  6. Intel汇编程序设计-高级过程(上)

    第八章 高级过程 8.1 简介 本章主要讲: 堆栈框架 变量作用域和生存期 对战参数的类型 通过传递值或者传递引用来传递参数 在堆栈上创建和初始化局部变量 递归 编写多模块程序 内存模型和语言关键字 ...

  7. C#-CMD

    private static string InvokeCmd(string cmdArgs) { string Tstr = ""; Process p = new Proces ...

  8. windows-API劫持(API-HOOK)

    API Hook ApiHook又叫做API劫持,也就是如果A程序调用了B.cll里面的C函数,我们可以做到当A调用C函数执行的时候,直接执行我们自己事先准备好的函数,之后我们在执行真正的C,当然我们 ...

  9. Django(10)ORM模型介绍

    前言 随着项目越来越大,采用写原生SQL的方式在代码中会出现大量的SQL语句,那么问题就出现了: 1.SQL语句重复利用率不高,越复杂的SQL语句条件越多,代码越长.会出现很多相近的SQL语句. 2. ...

  10. 企业是否可以用CRM做邮件营销?

    最近总有一些从事外贸,跨境电商的朋友问小Z:"我的企业能用CRM做邮件营销吗?" 我回答:"能,Zoho CRM系统不但能用来发营销邮件,还发得聪明.发得到位." ...