入门理解H264编码

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

作用:

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

3、H264压缩方式

H264采用的核心算法是帧内压缩帧间压缩,帧内压缩是生成I帧的算法,帧间压缩是生成B帧和P帧的算法。

帧内(Intraframe)压缩也称为空间压缩(Spatialcompression)。当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间的冗余信息,这实际上与静态图像压缩类似。帧内一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩一般达不到很高的压缩,跟编码jpeg差不多。

帧间(Interframe)压缩的原理是:相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。也即连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。帧间压缩也称为时间压缩(Temporalcompression),它通过比较时间轴上不同帧之间的数据进行压缩。帧间压缩一般是无损的。帧差值(Framedifferencing)算法是一种典型的时间压缩法,它通过比较本帧与相邻帧之间的差异,仅记录本帧与其相邻帧的差值,这样可以大大减少数据量。

3.1、压缩方式说明

Step1:分组,也就是将一系列变换不大的图像归为一个组,也就是一个序列,也可以叫GOP(画面组);

Step2:定义帧,将每组的图像帧归分为I帧、P帧和B帧三种类型;

Step3:预测帧,
以I帧做为基础帧,以I帧预测P帧,再由I帧和P帧预测B帧;

Step4:数据传输,
最后将I帧数据与预测的差值信息进行存储和传输。

4、H264分层结构

H264的主要目标是为了有高的视频压缩比和良好的网络亲和性,为了达成这两个目标,H264的解决方案是将系统框架分为两个层面,分别是视频编码层面(VCL)和网络抽象层面(NAL),如图2;

图2

VLC层是对核心算法引擎、块、宏块及片的语法级别的定义,负责有效表示视频数据的内容,最终输出编码完的数据SODB;

NAL层定义了片级以上的语法级别(如序列参数集参数集和图像参数集,针对网络传输,后面会描述到),负责以网络所要求的恰当方式去格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。NAL层将SODB打包成RBSP然后加上NAL头组成一个NALU单元,具体NAL单元的组成也会在后面详细描述。

这里说一下SODB与RBSP的关联,具体结构如图3所示:

SODB: 数据比特串,是编码后的原始数据;

RBSP: 原始字节序列载荷,是在原始编码数据后面添加了结尾比特,一个bit“1”和若干个比特“0”,用于字节对齐。

图3

5.H264码流结构

我认为在具体讲述NAL单元前,十分有必要先了解一下H264的码流结构;在经过编码后的H264的码流如图4所示,
从图中我们需要得到一个概念,H264码流是由一个个的NAL单元组成,其中SPS、PPS、IDR和SLICE是NAL单元某一类型的数据。

图4

6、H264的NAL单元

6.1、H264的NAL结构

在实际的网络数据传输过程中H264的数据结构是以NALU(NAL单元)进行传输的,传输数据结构组成为[NALU Header]+[RBSP],如图5所示:

图5

从之前的分析我们可以知道,VCL层编码后的视频帧数据,帧有可能是I/B/P帧,这些帧也可能是属于不同的序列之中;同一序列也还有相应的序列参数集与图片参数集;综上所述,想要完成准确无误视频的解码,除了需要VCL层编码出来的视频帧数据,同时还需要传输序列参数集和图像参数集等等,所以RBSP不单纯只保存I/B/P帧的数据编码信息,还有其他信息也可能出现在里面。

上面知道NAL单元是作为实际视频数据传输的基本单元,NALU头是用来标识后面RBSP是什么类型的数据,同时记录RBSP数据是否会被其他帧参考以及网络传输是否有错误,所以针对NAL头和RBSP的作用以及结构与所承载的数据需要做个简单的了解;

6.2、NAL头

一、 NAL头的组成

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

1、F(forbiden):禁止位,占用NAL头的第一个位,当禁止位值为1时表示语法错误;

2、NRI:参考级别,占用NAL头的第二到第三个位;值越大,该NAL越重要。

3、Type:Nal单元数据类型,也就是标识该NAL单元的数据类型是哪种,占用NAL头的第四到第8个位;

图6

二、 NAL单元数据类型

NAL类型主要就是下面图7中这些类型每个类型都有特殊的作用;

图 7

图 8

在具体介绍NAL数据类型前,有必要知道
NAL分为VCL和非VCL的NAL单元。在图8中有介绍(图表中DIR应该为IDR),其中SPS、SEI、PPS等非VCL的NAL参数对解码和显示视频都是很有用的。

而另外一个需要了解的概念就是
参数集(Parameter sets),参数集是携带解码参数的NAL单元,参数集对于正确解码是非常重要的,在一个有损耗的传输场景中,传输过程中比特列或包可能丢失或损坏,在这种网络环境下,参数集可以通过高质量的服务来发送,比如向前纠错机制或优先级机制。Parameter sets与其之外的句法元素之间的关系如图9所示:

图 9

每种类型都有代表一种数据类型,比较重要的以下几种做个简单的介绍:

1、非VCL的NAL数据类型:

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

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

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

@:先标记一下,SPS、PPS内容是编码器给的。(出处的话,慢慢研究)

2、VCL的NAL数据类型

1)、 头信息块,包括宏块类型,量化参数,运动矢量。这些信息是最重要的,因为离开他们,被的数据块种的码元都无法使用。该数据分块称为A类数据分块。

2)、 帧内编码信息数据块,称为B类数据分块。它包含帧内编码宏块类型,帧内编码系数。对应的slice来说,B类数据分块的可用性依赖于A类数据分块。和帧间编码信息数据块不通的是,帧内编码信息能防止进一步的偏差,因此比帧间编码信息更重要。

3)、 帧间编码信息数据块,称为C类数据分块。它包含帧间编码宏块类型,帧间编码系数。它通常是slice种最大的一部分。帧间编码信息数据块是不重要的一部分。它所包含的信息并不提供编解码器之间的同步。C类数据分块的可用性也依赖于A类数据分块,但于B类数据分块无关。

以上三种数据块每种分割被单独的存放在一个NAL单元中,因此可以被单独传输。

6.3、
H264的
NAL单元
与片,宏之间的联系

其实到这里可能就比较难理解了,为什么数据NAL单元中有这么多数据类型,这个SLICE又是什么东西,为什么不直接是编码后出来的
原始字节序列载荷,所以
我觉得在这里再讲述帧所细分的一些片和宏的概念应该是比较合适的,也是能够参照上下文更能理解这些概念的位置,又能给这些困惑做一个合理一点的解释,所以在此做一个描述:

1帧(一幅图像) = 1~N个片(slice)  //也可以说1到多个片为一个片组

1个片 = 1~N个宏块(Marcroblock)

1个宏块 = 16X16的YUV数据(原始视频采集数据)

从数据层次角度来说,一幅原始的图片可以算作广义上的一帧,帧包含片组和片,片组由片来组成,片由宏块来组成,每个宏块可以是4*4、8*8、16*16像素规模的大小,它们之间的联系如图10所示。每个片都是一个独立的编码单位。

图10

从容纳数据角度来说,NAL单元除了容纳Slice编码的码流外,还可以容纳其他数据,这也就是为什么有SPS、PPS等这些数据出现的原因,并且这些数据在传输H264码流的过程中起到不可或缺的作用,具体作用上面也是有讲到的。

那么也就可以对下面这些概念做一个大小的排序了:

序列>图像>片>宏>像素(当然还有片组、亚宏块等等这些概念,初步了解就不了解这么深了,后面再慢慢研究)

同时有几点需要说明一下,这样能便于理解NAL单元:

(1)、如果
不采用 FMO(灵活宏块排序)
 机制,则

幅图像只有一个片组

(2)、如果
不使用多个片,则一个片组只有一个片;

(3)、如果
不采用 
DP(
数据分割
)机制,则

个片就是一个 NALU,一个 NALU 也就是一个片

否则,个片的组成需要由 三个 NALU 组成,也就是上面说到的A、B、C类数据块。

这时候在看下面这幅码流数据分层图11就比较能理解整体的码流结构组成了;

图11

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

图12

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

至此,我们对 H.264 的码流数据结构应该有了一个大致的了解。

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

像素的亮度和色度数据集等等信息。

至此,我们对 H.264 的码流数据结构应该有了一个大致的了解。

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
[外链图片转存中…(img-yhPkvOoK-1715800281234)]
[外链图片转存中…(img-Nt3TkeeW-1715800281234)]

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 28
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值