简述h264编码

本文深入介绍了H264编码技术,包括帧的组成、帧类型(I、P、B帧)、PTS与DTS、GOP结构、IDR帧的作用以及压缩方式。通过详细阐述宏块划分、帧内与帧间压缩、DCT和CABAC压缩原理,揭示了视频数据如何被高效压缩。此外,还讨论了码流结构和NAL单元,为理解H264编码流程提供了全面的知识框架。
摘要由CSDN通过智能技术生成

————————————————分割线———1 序言————————————————

最近从iot公司跳到了安防公司,由于之前没有接触过音视频相关对项目,所以在这边记录一下音视频相关的学习过程

 

那么什么是h264编码?作用是什么呢?

答:h264编码是MPEG-4标准定义的最新格式,也称AVC,主要作用是对视频数据进行压缩的编码

 

学习h264编码的具体细节之前,首先需要理解一些h264相关的一些概念,这些概念对后面的学习很有帮助

————————————————分割线———2 概念篇————————————————

1 h264帧的组成

一个帧 由 一个或者多个片 组成

一个片 由 一个或者多个宏快组成

一个宏块由16*16或者8*8的yuv数据组成(宏块还能划分出更小的子块(8*16 8*8 4*8 4*4等))

 

每个片都是一个独立的编码单位

 

宏块是h264编码的基本单位

 

2 H264帧类型

I帧:关键帧

一帧画面的完整保留,解码只需要本帧数据即可,不依赖任何的其它帧

特点

I帧是P和B帧参考帧,其质量直接影响整个GOP组后各帧的质量

 

采用帧内压缩技术

压缩率:%7-10

 

P帧:向前预测编码帧

P帧表示这一帧和之前的I或者P帧的差别,解码解码依赖前面的I frame或P frame,需要用之前缓存的画面叠加本帧定义的差别生成最终画面(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)

 

特点

1 P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差)

2 P帧也可以是其后P帧和B帧的参考帧

3 若P帧作为后续帧的参考帧,可能会造成解码错误的扩散

 

采用帧间压缩技术

压缩率:%20

 

B帧:双向预测内插编码帧

B帧记录的是本帧与前后帧的差别,解码依赖前最近的一个I frame或P frame 及其后最近的一个P frame,不仅需要取得之前的缓存画面,还得解码之后画面,通过前后画面与本帧数据的叠加取得最终画面

 

特点

1 B帧不可作为其他帧的参考帧

2 B帧传送的是它与前面I(或P)以及后面的P帧之间的预测误差及运动矢量

3 B帧压缩率高,但是解码时CPU会比较累

 

采用帧间压缩技术

压缩率:%50

 

3 pts和dts

 

3 图像序列GOP

GOP是一段时间内变化不大的图像集

 

GOP结构有两个数字比较重要----M和N

M指的是I帧和P帧之间的距离,N指的是两个I帧之间的距离

 

例如:M=3,N=12

GOP结构为:IBBPBBPBBPBBI。

 

4 IDR帧(立即刷新图像)

在一个GOP中,首个I帧和其他I帧不同,是IDR帧(大华的I帧=IDR帧,不会有除了IDR之外的I帧)

 

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

IDR帧的主要作用是立即刷新,使错误不至传播

I帧有被跨帧参考的风险,IDR不会,IDR之后的帧都不能参考IDR之前的帧

I帧不用参考任何帧,但是之后的P帧和B帧是有可能参考这个I帧之前的帧的。IDR就不允许这样

例如:

IDR1 P4 B2 B3   P7   B5 B6   I10   B8   B9 P13 B11 B12 P16 B14 B15   

这里的B8可以跨过I10去参考P7

------------------------------------------------------------------------

IDR1 P4 B2 B3 P7 B5 B6   IDR8   P11   B9   B10 P14 B11 B12             

这里的B9就只能参照IDR8和P11,不可以参考IDR8前面的帧

 

从随机存取的视频流中,播放器永远可以从一个IDR帧播放,因为在它之后没有任何帧引用之前的帧。

 

h264引入IDR帧的目的是什么?

为了解码的重同步

当解码器解码到 IDR图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。

 

5 h264压缩方式及其之间的差别

帧内预测压缩(空间压缩)

帧内一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示

 

帧间压缩

相邻几帧的数据有很大的相关性,信息变化很小。

也即连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。

帧间压缩也称为时间压缩,它通过比较时间轴上不同帧之间的数据进行压缩。

帧间压缩一般是无损的

 

帧差值(Framedifferencing)算法是一种典型的时间压缩法,它通过比较本帧与相邻帧之间的差异,仅记录本帧与其相邻帧的差值,这样可以大大减少数据量。

 

6 花屏现象以及解决方法

花屏现象

如果在GOP分组中的P帧丢失,会造成解码端的图像发生错误。这就是花屏。GOP一组帧呈现出的连贯效果,由于P帧丢失,它需要更新的部分就没有,所以无法正常呈现。故出现花屏现象。

 

解决方法

为了解决花屏问题,我们可以将丢失P帧或是I帧 的 GOP 丢掉(包含其中的所有帧),直到下一个I帧再重新刷新图像。但是由于这一帧丢掉了,所以会出现卡顿。

 

 

————————————————分割线———3 分析篇————————————————

思考:当摄像头采集数据后如何进行h264压缩?

请见下文

1 宏块的划分

2 图像分组

3 帧内压缩技术原理

4 帧间压缩技术原理。

5 DCT

6 CABAC压缩原理。

 

简要概述一下

举例:

1 摄像头1s采集到30张图,将30张图传给h264编码器缓存区中

下面是一张摄像头采集到的的图

 

2 宏块划分与填充

2.1对每一幅图进行宏块划分,计算每个宏块的像素值(宏块一般为16*16或者8*8)

 

2.2 计算一幅图中每个宏块的像素值,处理完如下图

 

3 对宏块进行子块划分(子块大小为4*4 8*4 8*8 16*8)

 

上图中三只老鹰在宏块内,为了更好处理则在16*16的宏块中又划分了几个子块,如下

 

3 帧分组(将一系列变换不大的图像归为一个组,即GOP(序列))

以打台球为例

H264编码器会按顺序,每次取出两幅相邻的帧进行宏块比较,计算两帧的相似度

 

通过宏块扫描与宏块搜索可以发现这两帧的关联度非常高,进而发现这一组帧的关联度都非常高。

 

其算法是:在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内,我们认为这样的图可以分到一组。

 

帧分组后我们只保留GOP中第一帧为完整数据I帧,然后根据I帧预测出P,B帧

 

4 运动估计与补偿

H264编码器首先按顺序从缓冲区头部取出两帧视频数据,然后进行宏块扫描。当发现其中一幅图片中有物体时,就在另一幅图的邻近位置(搜索窗口中)进行搜索。如果此时在另一幅图中找到该物体,那么就可以计算出物体的运动矢量了

 

H264依次把每一帧中球移动的距离和方向都记录下来,如下

计算出运动矢量后,将每张图片相同的部分(绿色部分)减去,则得到补偿数据,我们只需要保存补偿数据即可(数据很小),这就是帧间压缩技术

 

5 帧内预测

将一幅图像中人眼不敏感的数据去除掉。这样就提出了帧内预测技术

 

一幅图像被划分好宏块后,对每个宏块可以进行 9 种模式的预测。找出与原图最接近的一种预测模式

下图为9种预测模式

 

预测完后的图像如下

 

帧内预测后的图像与原始图像的对比如下:

 

将原始图像与帧内预测后的图像相减得残差值

 

将1 残差值和之前的2 预测模式信息一起保存起来即可

这样就完成了帧内预测,对数据进行了大幅压缩(但是还可以进一步的压缩,见6)

 

6 残差数据做DCT

将残差数据做整数离散余弦变换DCT,去掉数据的相关性,进一步压缩数据。

 

将残差数据宏块数字化后如下图

 

将残差数据宏块进行 DCT 转换

 

去掉相关联的数据后,我们可以看出数据被进一步压缩了

做完 DCT 后,还不够,还要进行 CABAC 进行无损压缩

 

7 CABAC无损压缩

VLC就是这种算法,我们以 A-Z 作为例子,A属于高频数据,Z属于低频数据。看看VCL是如何做的

 

CABAC也是给高频数据短码,给低频数据长码。同时还会根据上下文相关性进行压缩,这种方式又比VLC高效很多。其效果如下:

 

现在将 A-Z 换成视频帧,它就成了下面的样子

从上面这张图中明显可以看出采用 CACBA 的无损压缩方案要比 VLC 高效的多

 

————————————————分割线———4 数据篇————————————————

1 H264的分层结构

h264分为VLC层和NAL层

VLC层(视频编码层)

被压缩后的视频数据序列,负责表示有效视频数据的内容,最终输出编码后的原始数据SODB(数据比特串)

 

NAL层(网络提取层)

NAL层定义了片级以上的语法级别(如序列参数集和图像参数集,针对网络传输),负责以网络所要求的恰当方式去格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。

 

2 聊一聊NULA和EBSP RBSP SODP

NALU的起始码为0x000001或0x00000001

NALU的结束码为0x000000

SODB:原始比特流

RBSP:始字节序列载荷

EBSP:扩展字节序列载荷

 

EBSP相较于RBSP,在两个0x00 x00后,加了防止竞争的一个字节:0x03,这样可以避免数据内误判断起始码和结束码

 

在h264的文档中,并没有EBSP这一名词出现,但是在h264的官方参考软件JM里,却使用了EBSP,所以有的地方说NALU(NUL单元) = NALU Header + RBSP也是对的

 

RBSP尾部语法

1 SODB在它的最后一个字节的最后一个比特后,紧跟值为1的1个比特,然后增加若干比特的0,以补齐这个字节

2 当NALU类型为条带时,也即nal_unit_type等于1~5时,这时RBSP使用下面这种尾部

当entropy_coding_mode_flag值为1,也即当前采用的熵编码为CABAC,而且more_rbsp_trailing_data()返回为true,也即RBSP中有更多数据时,添加一个或多个0x0000

 

总结一下

NALU(NUL单元) = NALU Header + EBSP(RBSP + 0x00000003)

EBSP = RBSP + 插入的防止竞争的0x03

RBSP = SODB + + RBSP尾部

EBSP包含RBSP,RBSP包含SODB

 

h264码流结构

一个gop中一般都会有SPS PPS IDR等等

 

nal单元

 

nal头

NAL单元的头部是由forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)三个部分组成的

 

F:0表示正常,1表示错误

NRI:重要级别,11表示最重要,00最不重要

TYPE:见上图

 

看一个大华抓出来的帧数据例子

1)、SPS(序列参数集):SPS对如标识符、帧数以及参考帧数目、解码图像尺寸和帧场模式等

解码参数进行标识记录。

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

3)、SEI(补充增强信息):这部分参数可作为H264的比特流数据而被传输,每一个SEI信息被封装成一个NAL单元。SEI对于解码器来说可能是有用的,但是对于基本的解码过程来说,并不是必须的

 

H264常见帧头数据

SPS:00 00 00 00 67

PPS:00 00 00 00 68

IDR:00 00 00 00 65

非IDR:00 00 00 00 61

 

实际码流解读

I帧码流解读

我们可以看到除了起始帧00 00 00 01(也可以认为结束帧00 00 00,看你个人怎么去理解),其他帧中有两个00的,都会插入一个03防止竞争,将RBSP组成EBSP

这边码流类型如下

SPS + PPS + IDR

 

P帧码流类型

非I帧61

 

h264码流的分层结构

每个分片也包含着头和数据两部分,分片头中包含着分片类型、分片中的宏块类型、分片帧的数量以及对应的帧的设置和参数等信息,而分片数据中则是宏块,这里就是我们要找的存储像素数据的地方;宏块是视频信息的主要承载者,因为它包含着每一个像素的亮度和色度信息。视频解码最主要的工作则是提供高效的方式从码流中获得宏块中的像素阵列。宏块数据的组成如下图12所示:

 

 从上图中,可以看到,宏块中包含了宏块类型、预测类型、Coded Block Pattern、Quantization Parameter、像素的亮度和色度数据集等等信息。

 

————————————————分割线———5 代码篇————————————————

下期会写一个手写简单的h264编解码器,敬请期待

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>