入门理解H264编码 |
您所在的位置:网站首页 › 导航解码什么意思呀怎么弄 › 入门理解H264编码 |
最近入门音视频技术,一直在学习H264编解码标准,了解了不少关于H264的相关知识,对于网上各种类型的资料,始终没有找到一篇适合的知识梳理资料。可能是查找方式不对,所以花费了比较多的时间。经过一段时间的熟悉后结合网上各类大神的指导资料和自己的理解决定自己整理一下关于H264编解码标准的知识。以后方便自己查阅,也让更多刚入门的人提供一个参考资料,由于是初次涉及,所以有些地方可能有理解不全面或有误,望各位前辈大神多多指导,不胜感激;
主要的参考资料在已贴在后面,大家可以详细了解;
0、序言
首先要弄明白编码的目的,有目的的学习效率会更好。编码是为了将数据进行压缩,这样在传输的过程中就不会使资源被浪费,用一个简单的例子来说明编码的必要性:
当你此刻显示器正在播放一个视频,分辨率是1280*720,帧率是25,那么一秒所产生正常的数据大小为:
1280*720(位像素)*25(张) / 8(1字节8位)(结果:B) / 1024(结果:KB) / 1024 (结果:MB) = 2.75MB
显然一秒这么大的数据你是无法接受的,所以如果不将数据进行压缩,那么只能一首凉凉表达此刻的感受了;
1、前言
H264里面很多文章梳理,具体标准定义就不多赘述了,但是有些概念一定要弄明白,这样在后面我就是因为有些概念模糊所以在理解某些知识点十分吃力,例如序列、GOP等等,我会逐一在后面描述到。 H264在视频采集到输出中属于编解码层次的数据,如图1所示,是在采集数据后做编码压缩时通过编码标准编码后所呈现的数据。 图1 2、H264相关概念 2.1序列 H264编码标准中所遵循的理论依据个人理解成:参照一段时间内相邻的图像中,像素、亮度与色温的差别很小。所以当面对一段时间内图像我们没必要去对每一幅图像进行完整一帧的编码,而是可以选取这段时间的第一帧图像作为完整编码,而下一幅图像可以记录与第一帧完整编码图像像素、亮度与色温等的差别即可,以此类推循环下去。 什么叫序列呢?上述的这段时间内图像变化不大的图像集我们就可以称之为一个序列。序列可以理解为有相同特点的一段数据。但是如果某个图像与之前的图像变换很大,很难参考之前的帧来生成新的帧,那么久结束删一个序列,开始下一段序列。重复上一序列的做法,生成新的一段序列。 2.2、帧类型 H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16x16的yuv数据组成。宏块作为H264编码的基本单位。 在H264协议内定义了三种帧,分别是I帧、B帧与P帧。I帧就是之前所说的一个完整的图像帧,而B、帧与P帧所对应的就是之前说的不编码全部图像的帧。P帧与B帧的差别就是P帧是参考之前的I帧而生成的,而B帧是参考前后图像帧编码生成的。 2.3、GOP(画面组) GOP我个人也理解为跟序列差不多意思,就是一段时间内变化不大的图像集。GOP结构一般有两个数字,如M=3,N=12。M指定I帧和P帧之间的距离,N指定两个I帧之间的距离。上面的M=3,N=12,GOP结构为:IBBPBBPBBPBBI。在一个GOP内I frame解码不依赖任何的其它帧,p frame解码则依赖前面的I frame或P frame,B frame解码依赖前最近的一个I frame或P frame 及其后最近的一个P frame。 2.4、IDR帧(关键帧) 在编码解码中为了方便,将GOP中首个I帧要和其他I帧区别开,把第一个I帧叫IDR,这样方便控制编码和解码流程,所以IDR帧一定是I帧,但I帧不一定是IDR帧;IDR帧的作用是立刻刷新,使错误不致传播,从IDR帧开始算新的序列开始编码。I帧有被跨帧参考的可能,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前面的帧 作用: 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所示:![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |