前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >音视频压缩:H264码流层次结构和NALU详解

音视频压缩:H264码流层次结构和NALU详解

作者头像
潇湘落木
发布2020-11-12 12:00:21
5.6K0
发布2020-11-12 12:00:21
举报
文章被收录于专栏:智媒黑板报

问题背景:

前面在讲封装格式过程中,都有一个章节讲解如何将H.264的NALU单元如何打包到TS、FLV、RTP中,解装刚好相反,怎么从这些封装格式里面解析出一个个NALU单元。NALU即是编码器的输出数据又是解码器的输入数据,所以在封装和传输时,我们一般处理对象就是NALU,至于NALU内部到底是什么则很少关心。甚至我们在编解码时,我们只需要初始化好x264编码库,然后输入YUV数据,它就会给你经过一系列压缩算法后输出NALU,或者将NALU输入到x264解码库就会输出YUV数据。

这篇文章就初步带你看下NALU能传输那些数据,NALU的类型和结构以及H264码流的层次,最后通过分析工具分析下裸码流记性验证,你可以选择感兴趣章节阅读。


NALU结构:

H.264的基本流(elementary stream)就是一系列NALU的集合,如下图所示:

NALU结构分为两层,包含了视频编码层(VCL)和网络适配层(NAL):

视频编码层(VCL即Video Coding Layer):负责高效的视频内容表示,这是核心算法引擎,其中对宏块、片的处理都包含在这个层级上,它输出的数据是SODB;

网络适配层(NAL即Network Abstraction Layer):以网络所要求的恰当方式对数据进行打包和发送,比较简单,先报VCL吐出来的数据SODB进行字节对齐,形成RBSP,最后再RBSP数据前面加上NAL头则组成一个NALU单元。

分层目的:

这样做的目的:VCL只负责视频的信号处理,包含压缩,量化等处理,NAL解决编码后数据的网络传输,这样可以将VCL和NAL的处理放到不同平台来处理,可以减少因为网络环境不同对VCL的比特流进行重构和重编码;

NLAU结构:

其实NALU的承载数据真实并不是RBSP而是EBSP即(Extent Byte Sequence Payload),EBSP和RBSP的区别就是在 RBSP里面加入防伪起始码字节(0x03),因为H.264规范规定,编码器吐出来的数据需要在每个NALU添加起始码:0x00 00 01或者0x00 00 00 01,用来指示一个NALU的起始和终止位置,那么RBSP数据内部是有可能含有这种字节序列的,为了防止解析错误,所以在RBSP数据流里面碰到0x 00 00 00 01的0x01前面就会加上0x03,解码时将NALU的EBSP中的0x03去掉成为RBSP,称为脱壳操作。

原始数据字节流RBSP即Raw Byte Sequence Playload,因为VCL输出的原始数据比特流SODB即String Of Data Bits,其长度不一定是8bit的整数倍,为了凑成整数个字节,往往需要对SODB最后一个字节进行填充形成RBSP,所以从SODB到RBSP的示意图如下:

具体填充方式就是对VCL的输出数据进行8bit进行切分,最后一个不满8bit的字节第一bit位置1,然后后面缺省的bit置0即可,示意图已经非常明确。

其中H.264规范规定,编码器吐出来的数据需要在每个NALU添加起始码:0x00 00 01或者0x00 00 00 01,用来指示一个NALU的起始和终止位置。

所以H.264编码器输出的码流中每个帧开头3-4字节的start code起始码为0x00 00 01或者0x00 00 00 01。

上面我们分析了NALU的结构以及每层输出数据的处理方法,但是对于NALU的RBSP数据二进制表示的什么含义并不清楚,下面分析下NALU的类型。

NALU类型:

NALU的类型即RBSP可以承载的数据类型如下所示:

Nalu_Type

NALU内容

备注

0

未指定

1

非IDR图像编码的slice

比如普通I、P、B帧

2

编码slice数据划分A

2类型时,只传递片中最重要的信息,如片头,片中宏块的预测模式等;一般不会用到;

3

编码slice数据划分B

3类型是只传输残差;一般不会用到;

4

编码slice数据划分C

4时则只可以传输残差中的AC系数;一般不会用到;

5

IDR图像中的编码slice

IDR帧,IDR一定是I帧但是I帧不一定是IDR帧。

6

SEI补充增强信息单元

可以存一些私有数据等;

7

SPS 序列参数集

SPS对如标识符、帧数以及参考帧数目、解码图像尺寸和帧场模式等解码参数进行标识记录

8

PPS 图像参数集

PPS对如熵编码类型、有效参考图像的数目和初始化等解码参数进行标志记录。

9

单元定界符

视频图像的边界

10

序列结束

表明下一图像为IDR图像

11

码流结束

表示该码流中已经没有图像

12

填充数据

哑元数据,用于填充字节

13-23

保留

24-31

未使用

举例说明:

这其中NALU的RBSP除了能承载真实的视频压缩数据,还能传输编码器的配置信息,其中能传输视频压缩数据的为slice。

那么如果NLAU传输视频压缩数据时,编码器没有开启DP(数据分割)机制,则一个片就是一个NALU,一个 NALU 也就是一个片。否则,一个片由三个 NALU 组成,即DPA、DPB和DPC,对应的nal_unit_type 类型为 2、3和4。

通常情况我们看到的NLAU类型就是SPS、PPS、SEI、IDR的slice、非IDR这几种。

上面站在NALU的角度看了NALU的类型、结构、数据来源、分层处理的原因等,其中NLAU最主要的目的就是传输视频数据压缩结果。那么站在对数据本身的理解上,我们看下H.264码流的层次结构。


H.264层次结构:

其实为了理解H.264是如何看待视频数据,先要了解下视频的形成过程。其实你把多副连续的有关联图像连续播就可以形成视频,这主要利用了人视觉系统的暂留效应,当把连续的图片以每秒25张的速度播放,人眼基本就感觉是连续的视频了。为了说明这个概念,我下面准备了一个视频大家点开看下,加深对视频的理解。

从上面的视频播放过程中,我们大概能看出视频有下面几个特点:

一张图像里面相邻的区域或者一段时间内连续图像的相同位置,像素、亮度、色温差别比较小,所以视频压缩本质就是利于这种空间冗余和时间上冗余进行编码,我们可以选取一段时间第一幅图像的YUV值,后面的只需要记录和这个的完整图像的差别即可,同时即使记录一副图像的YUV值,当有镜头完全切换时,我们又选取切换后的第一张作为基本图像,后面有一篇文章回讲述下目前视频压缩的基本原理。

所以从这里面就可以引申以下几个概念:

GOP:一段时间内图像变化不大的图像集我们就可以称之为一个序列,这里的图像又在H264里面称为帧,所以就是一组视频帧,其中第一个我们称为是IDR帧。

帧:一副图像编码后的视频数据也叫做一帧,其中有I帧、B帧、P帧,前文多次提到,不再赘述;

片:一帧图像又可以划分为很多片,由一个片或者多个片组成;

宏块:视频编码的最小处理单元,承载了视频的具体YUV信息,一片由一个或者多个宏块组成;

所以视频流分析的对象可以用下面的图片描述:

如果站在数据的角度分析NALU的层次关系,如下图:

这里视频帧被划分为一个片或者多个片,其中slice数据主要就是通过NLAU进行传输,其中slice数据又是由:

一个Slice = Silce + Slice Data

Slice片类型:

片类型

含义

I片

只包含I宏块

P片

包含P和I宏块

B片

包含B和I宏块

SP片

包含P 和/或 I宏块,用于不同码流之间的切换

SI片

一种特殊类型的编码宏块

设置片的目的是限制误码的扩散和传输,也就是一帧图像中它们的编码片是互相独立的,这样假设其中一张图像的某一个片有问题导致解码花屏,但是这个影响范围就控制在这个片中,这就是我们平时看视频发现只有局部花屏和绿屏的原因。

Slice Data里面传输的是一个个宏块,宏块中的数据承载各个像素点YUV的压缩数据。一个图像通常被我们划分成宏块来研究,通常有16*16、16*8等格式。我们解码的过程也就是恢复这些像素阵列的过程,如果知道了每个像素点的亮度和色度,就能渲染出一张完整的图像,图像的快速播放即是视频。

其中宏块MB的类型:

宏块分类

意义

I宏块

利用从当前片中已解码的像素作为参考进行帧内预测

P宏块

利用前面已编码图像作为参考进行帧内预测,一个帧内编码的宏块可进一步作宏块的分割:即16×16.16×8.8×16.8×8亮度像素块。如果选了8×8的子宏块,则可再分成各种子宏块的分割,其尺寸为8×8,8×4,4×8,4×4

B宏块

利用双向的参考图像(当前和未来的已编码图像帧)进行帧内预测

宏块的结构:


H.264码流示例分析:

这里我们分析一下H.264的NLAU数据,其中包括了非VCL的NALU数据和VCL的NALU。

H.264码流的NLAU单元:

1. 我们发现视频流数据就是由一系列SPS、PPS、I、P、B帧序列组成,这些数据都是通过NALU进行承载的;

2. 我们看到了NALU不仅仅可以承载SPS、PPS、SEI等非VCL数据,也可以传输I、B、P帧的切片VCL数据。

3. 我们同时看到了NALU的Data部分,如果是VCL数据,则就是slice header+silce data这种结构,其中对VCL的SODB做了bit填充的字节对齐处理;

4. 这里由于没有数据分割机制,所以一个NALU承载一个片,同时一个片就是一个视频帧;

4.至于NALU的非VCL数据SPS、PPS、SEI各个字段的含义具体解析放到下篇文章,这个信息对于解码器进行播放视频很重要,很多播放问题都是这个数据有问题导致的;

上面看了视频的GOP序列,视频帧信息和片的组成,下面分析片中的宏块信息;

H.264的层次结构:

1. 我们能看到整个视频的视频序列,显示看了该视频有I、B、P帧信息,这和上面的分析结果是一致的;

2. 中间图片部分用不同颜色的点显示了宏块和子宏块信息,右上角是对宏块内容的具体说明;

3. 其中不同的帧类型上面的宏块类型也是不一样的;


总结:

本文主要讲述了平时研究和分析视频流对象的层次,然后这些视频数据通过NALU传输时,NALU的类型和层次关系,以及NALU数据在不同层次的输出。最后用视频分析工具分析了H.264裸码流验证了上述层次关系。

所以对H.264数据分析时,一定要了解你现在分析的层次和框架,因为每个层次我们关心的数据处理对象是不一样的,这个非常重要。

一般H.264的分析工具都是收费的,也有一些免费和裁剪版本供大家学习和使用。推荐几个:Elecard StreamEye、CodecVisa、VideoEye、H264Analyzer、H264Visa等,有时需要交叉使用才能完成对你关心信息的分析,这些都放到我的Git上了,大家获取使用即可。


今天就说这么多,祝您国庆快乐,工作顺利!

如果有疑问,你可以在公众号后台发消息咨询我。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 智媒黑板报 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档