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视频码流解析(java)

    参考文献 : 视音频数据处理入门:H.264视频码流解析 测试文件:H264文件 链接:https://pan.baidu.com/s/1eRTJwTsXTgHf2Ez8Inab1A  提取码:1c7 ...

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

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

  3. 【H.264】码流解析 annexb vs avcc

    H264码流解析及NALU AVCC和ANNEXB 前者是FLV容器.mp4 常用的. 后者 是实时传输使用,所以是TS 一类的标准. VLC显示AVC1就是AVCC AVCC格式 也叫AVC1格式, ...

  4. H.264/H265的NAL解析

    1.H.264的NAL解析 在有序字节流格式的H.264码流中,我们可以根据前缀起始码0x 00 00 01或0x 00 00 01获取到一个完整的NAL Unit所包含的的字节数据.H.264码流中 ...

  5. 【音视频数据数据处理 12】【H.264篇】解析H.264原始码流中的I帧 / P帧 / B帧数据(暂未解决,本文先放着,来日更新)

    [音视频数据数据处理 12][H.264篇]解析H.264原始码流中的I帧 / P帧 / B帧数据 一.如何判断是 I帧 / P帧 / B帧 1.1 slice_type 1.2 slice_head ...

  6. 将h.264裸码流推送到RTMP服务器

    h.264裸码流的格式,参考"H.264-AVC-ISO_IEC_14496-10.pdf, page 211.",这个文档的下载地址:https://github.com/win ...

  7. PX2板实现H.264裸码流的解码

    2019独角兽企业重金招聘Python工程师标准>>> 之前已经有人尝试使用了PX2板实现H.264裸码流的解码,并且给了例程,不过楼主尝试时碰到了一点小问题,现在也是解决了,现在楼 ...

  8. Python解码H.264(二)——将海思处理器编码的H.264裸码流转换为jpg序列

    上一篇我们历尽千辛万苦完成了PyAV的安装,这一篇我们来小试牛刀. 思路:通过PyAV来把海思Hi3516编码处理器编码的h.264裸码流中的每一帧都转换为一张jpeg编码的图片,然后将这些jpg图像 ...

  9. 音视频开发——H265码流解析

    概述 H.265技术的应用 编码技术主要运用于视频播放设备.软件应用以及拍摄.录制视频的设备.人们最熟悉的莫过于PPS网络视频播放器.在PC屏客户端产品上面,PPS已经于2013年初推出了基于H.26 ...

最新文章

  1. .NET Core微服务之路:不断更新中的目录 (v0.42)
  2. VR是一场“大骗局”, 另一种声音
  3. oracle 怎么判断是不是第一条记录_怎么判断自己是不是阳痿呢?防治阳痿的5个方法值得一试...
  4. 手机投屏到电视的5种方法_安卓手机、苹果手机投屏到电视史上最全的方法
  5. 自编码器及其相关模型
  6. python实现二叉搜索树_python实现二叉查找树
  7. cesium米转换经纬度_cesium 常见坐标系及坐标转换(工具篇)
  8. SpringCloud企业实战专栏
  9. mysql master 监控_可用于监控 mysql Master Slave 状态的python代码
  10. 链上存证、链下传输的可信数据共享平台
  11. WCF读取配置动态生成客户端对象
  12. 苹果紧急修复已遭利用的两个0day
  13. 【Java与智能设备】 CH05_2 Intent启动内置程序
  14. jQuery jqGrid 文档
  15. Instsrv.exe和Srvany.exe的使用方法
  16. 数控dda法直线插补程序c语言,DDA法直线插补
  17. 黑马点评项目-优惠券秒杀
  18. 应届生面试这样准备,最能展现自己优势!
  19. SRM 613 div1 500pt
  20. python配置(二)——机器学习环境

热门文章

  1. tf.placeholder函数说明
  2. TVM 高效保护隐私 ML
  3. MindSpore部署图像分割示例程序
  4. nvJPEG Codec库
  5. python 爬取手机app的信息
  6. git clean和git reset结合用法
  7. Python七大原则,24种设计模式
  8. 【网站汇总】论文相关
  9. [JS] for-each和map()的区别
  10. Python数据挖掘2:pandas使用:Series一串数字和DataFrame数据框