上一篇文章我们主要讲解了音频压缩算法的主要指标,以及几个典型的音频压缩算法。本章将延续上一讲的内容,分析视频压缩算法。

视频压缩算法

视频压缩算法比较,Wiki百科官方收录分类,请自备梯子

视频压缩算法比较​en.wikipedia.org

这里建议大家关注三个东西。H264/5,DCT算法,FFmpeg开源库。

目前市面上主流的视频编码算法有:x264/5,vp8/9。本文简单记录一下它们的编译方法。其中x264现在占据着H.264视频编码器的半壁江山,x265则是目前实现H.265标准最好的开源视频编码器。是x264的潜在替代者。而vp8/9则是Google推出的开源视频编码器,它提出的VP9编码标准的性能也不错,但目前主要是Google这家公司在玩。

对于视频的编解码,常常还会涉及到专用硬件加速。这一块本文不涉及。

视频压缩性能衡量指标

  1. 有损/无损编码:
  2. 压缩比:实际输入数据量与输出数据量的比值
  3. 编解码时间(时延):编解码复杂度:
  4. 可变帧率(VFR)
  5. 兼容的封装格式

其他几个东西都比较好理解,那这个封装格式是一个什么东西呢?其实就是打包视频、音频、字幕等的方式。具体的我们会在下一章中讲到。

在视频中,由于数据量较大,所以相对于音频编解码算法,视频的编解码算法对于编解码时间还是比较关注的。真是因为这种编解码算法都是运算量极大的算法,因此一般核心音视频软件都是通过C/C++撰写的,同时还要关注其对于CPU资源的需求量,必要时通过GPU调优。

H264 编码

H.264是MPEG4的第十部分,是一个高级视频编码(AVC)标准。是一种面向块,基于运动补偿的编码算法。与旧标准(H.263)相比,它能够在更低带宽下提供优质视频,且复杂度适中,实现难度适中。因此,得到了广泛的发展。

H.264标准可以被看作一个“标准家族”,成员有下面描述的各种配置(profile)。一个特定的解码器至少支持一种,但不必支持所有的。解码器标准描述了它可以解码哪些配置。

更多细节可以参考Wiki百科:H.264标准

提到H264标准,就不得不提x264算法实现了。x264其实就是目前最流行的H264标准的算法实现库。而大名鼎鼎的FFmpeg对于H264的编码就是用的x264代码库。其中有一个特别显眼的注释: H.264 encoding using the x264 library

x264是H264标准的算法实现库:

x264 官方​www.videolan.org

所以H264、x264以及FFmpeg三者的关系可以概括为:H.264是标准(包含编码、解码),x264是标准的实现(只实现了编码),FFmpeg是一个框架,但是里面包含了H.264的解码实现,编码采用了x264。

H264 算法细节

英语标准原稿​read.pudn.com

首先,我们先看看编解码的整体结构,有个全局观。

好了,接下来放大招了:

ITU H264标准文档​www.itu.int

简直是一份全英文的数学公式,你别妄想着个把月能搞懂里面所有的东西(别问我怎么知道的),用的时候来查就好了,建议直接看Annex。接下来我们就进入正题了。

Profile和Level

H264定义了很多中的Profile来限定具体实现的H264算法的能力,然后通过Level来限定具体的图像信息的参数。然后适配现实环境中各种性能不同的硬件设备。因此你可以理解成,根据不同的Profile以及Level设定H264算法的参数,以实现不同的编解码标准。

Profile定义了总的参数限制,Level进一步限制了细节处的参数。

根据画质级别,目前H.264目前主要有四种Profile(更多的请参看文档):

1、Baseline Profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;

2、Extended profile:进阶画质。支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC;(用的少)

3、Main profile:主流画质。提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced), 也支持CAVLC 和CABAC 的支持;

4、High profile:高级画质。在main Profile 的基础上增加了8x8内部预测、自定义量化、 无损视频编码和更多的YUV 格式;

关于Level的话,请直接看表格吧。

ffmpeg如何控制profile&level

ffmpeg -i input.mp4 -profile:v baseline -level 3.0 output.mp4ffmpeg -i input.mp4 -profile:v main -level 4.2 output.mp4ffmpeg -i input.mp4 -profile:v high -level 5.1 output.mp4

一切从视频帧开始

首先,视频是由一帧一帧的图像组成的,因此图像的压缩算法,也是适用于视频的。但对于视频,由于它是动态的,因此,相比于图片,视频又多了帧于帧之间的冗余。

综上,视频的压缩主要有两个:帧内冗余信息的压缩,以及帧间冗余信息的压缩。

在H.264 中,句法元素共被组织成序列(PTS)、图像帧、片、宏块、子宏块五个层次(像素不算啦)。

H264默认是使用 16X16 大小的区域作为一个宏块(Block),也可以划分成 8X8 大小,H264对比较平坦的图像使用 16X16大小的宏块。但为了更高的压缩率,还可以在 16X16 的宏块上更划分出更小的子块。子块的大小可以是 8X16、16X8、 8X8、 4X8、 8X4、 4X4。

在H264中,最小的矩阵单位是4X4大小的block,因此一个MacroBlock中一般有16个小的Block。

对了有兴趣的小伙伴还可以自行了解下,视频图像的交织扫描(Interlaced)与全扫描(Progressive),其中交织扫描方式之后又有Top Field(1,2,5...)和Bottom Filed(2,4,6...)的概念。这两者可以结合运动与非运动的图像的特点进一步的压缩优化。

在视频中,场景可能是不断变化的,不可能每一帧都是可以参考之前的场景的。对于这种帧,我们只能采用帧内编码。相应的H264对于视频帧将他们进行分组分类,于是就出现了GOP分组以及I,P,B帧。

I帧:关键帧,采用帧内压缩技术。

P帧:向前参考帧,压缩时,只参考前面已经处理的帧。

B帧:双向参考帧,压缩时,它即参考前而的帧,又参考它后面的帧。

GOP:两个I帧之间是一个图像序列,在一个图像序列中只有一个I帧。

在H264中图像以GOP为单位进行组织,每个序列的第一个图像叫做 IDR 图像立即刷新图像),IDR 图像都是 I帧图像。H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会(视频之前的乱码不影响之后)。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。

一个序列就是一段内容差异不太大的图像编码后生成的一串数据流。当运动变化比较少时,一个序列可以很长,因为运动变化少就代表图像画面的内容变动很小,所以就可以编一个I帧,然后一直P帧、B帧了。当运动变化多时,可能一个序列就比较短了,比如就包含一个I帧和3、4个P帧。

而,关于变化大于不大,H264有自己的判断算法,有兴趣的自己去了解一下。

PTS和DTS

由于B帧是需要后向参考P帧的,所以在解码的时候,B帧的数据就必须在P帧之后到达,但是显示的时候它又需要在P帧之前显示。因此就有了PTS和DTS的概念。

DTS(Decoding Time Stamp):即解码时间戳,告诉播放器该在什么时候解码这一帧的数据。 PTS(Presentation Time Stamp):即显示时间戳,告诉播放器该在什么时候显示这一帧的数据。

我们在第一讲音视频同步的时候有涉及到这个概念,有兴趣的朋友可以回去看一看。

颜色空间

颜色,对于彩色电视来说是不可或缺的一部分。由于不同的颜色需要占据不同的数据通道(然后通过显示硬件显示),因此,视频压缩中不可避免的就要涉及颜色空间的知识。而一般彩色图像都是有三个通道存储的。

之前我们有提到过RGB颜色空间和YUV颜色空间的转换。除了这两者之外还有印刷用的减法色彩空间CMYK,以及HSV,HSL等其他领域关注的色彩空间。本质上色彩空间都是可以转换的,之所以换成各种不同的表示,是为了更好的适配具体的应用场景。比如,YUV颜色空间,考虑人眼对于亮度的敏感度高于色彩敏感度的特点,适合做数据的压缩。因此也是视频压缩算法关注的颜色空间。

为了更好的压缩率,对于亮度数据Y,H264采用全采样,而颜色空间采用部分或全部采样。形成了Yuv444,Yuv422,Yuv420等,目前使用的H264几乎都是采用Yuv420以获得更好的压缩率。

Yuv420并不是没有v变量的意思,而是,其没有每行都取U和V分量,而是一行只取U分量,接着一行就只取V分量,以此重复(即4:2:0, 4:0:2, 4:2:0, 4:0:2...)。从4x4矩阵列来看,每4个矩阵点Y区域中,只有一个U和V,所以它们的比值是4:1(参考上图中的Macroblock)。

采样好了数据,在存储YUV数据的时候,对于YUV不同的存储方式又有YUV420P(YV12)、YUV420SP(NV12)两种。

两者的区别仅在于最后对于UV变量存储是交替的,还是先后的,默认采用的是YUV420P。

讲到这里,我们就真正的把一份彩色视频帧,演化成了数值数据,注意是0-255(根据位深)的数值数据,而不是bit数据。

编码的细节

讲了,这么多结构上的问题,帧间编码与帧内编码到底怎么做呢?

对于视频数据主要有两类数据冗余,一类是时间上的数据冗余,另一类是空间上的数据冗余。其中时间上的数据冗余是最大的。

对于一组连续的且十分相似的图像帧数据,我们将第一帧编码为I帧,其余的编码为P帧和B帧形成一个GOP。

帧间预测压缩

对于帧间压缩算法,首先我们得估计出图像中前景(运动物体)得运动方向,称作运动矢量。然后将图像帧与参考帧相同的部分减去,获得运动补偿数据,该数据大大小于原始数据,在解码的时候更具运动补偿数据以及参考帧就能恢复原始数据了。

运动矢量与运动补偿技术就是H264的帧间预测算法的核心,它解决的是视频帧在时间上的数据冗余。

帧内预测压缩

人眼对图象都有一个识别度,对低频的亮度很敏感,对高频的亮度不太敏感。基于这种理论,可以将一幅图像中人眼不敏感的数据去除掉,以提高压缩率。因此帧内预测技术就孕育而生了。

之前我们讲到,在H264中,视频最后会被分成宏块。在H264标准中,对每个宏块可以进行 9 种模式的预测。通过算法找出与原图最接近的一种预测模式。然后,将原始图像与帧内预测后的图像相减得残差值。通过预测模式和残差值,我们就可以在解码时恢复原图了。

但是这里我们会发现,与原始的图像相比,通过预测模式以及残差图获得的预测图像有很多的噪点。回顾一开始的H264编解码整体框架图中,我们发现图像最后被重构展示之前还有一个Filter操作,而这个操作正是平滑这些噪点的关键操作!

Transform操作

这一步在H264中,主要是整数离散余弦变换(DCT)。

H264算法对于预测数据的残差图像不是直接保存的,而是再通过DCT压缩算法来进行压缩,进一步提高压缩率。关于这个算法,我打算后面专门做一章的讲解。

熵压缩算法

DCT压缩之后的数值数据,还需要更具熵压缩算法进行压缩,最后输出通过二进制表示的最终的计算机可识别的数据。

在H264中的熵压缩算法,主要有:

CABAC:基于上下文的二元算法编码,无损。

CAVLC:基于上下文的变长编码,复杂度低。

在给定的实验条件下得出CABAC的比特率比CAVLC节省5%~14%,并且随量化步长的增大,比特率节省增多。但是CABAC计算复杂度高,耗时比CAVLC长。

以上所描述的编码过程可以通过一幅图来概括

H.264码流结构

讲完了编码相关的内容,让我们把焦点放在NAL这,NAL是H264的一个抽象层,对于编码后的数据,统一表示成NAL Unit(NALU)数据,送往存储,或者通过网络传输。其与视频之间的关系大致如下:

以上这些,就叫做H264的码流结构,接下来让我们深入其中。

NALU数据分为,NALU头和HALU主体,其中NALU有很多的数据类型。

NALU类型:标识NAL单元中的RBSP数据类型,NAL包将其负载数据存储在 RBSP(Raw Byte Sequence Payload) 中,RBSP 是一系列的 SODB(String Of Data Bits)。其中,nal_unit_type为1, 2, 3, 4, 5及12的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL单元。 VCL代表视频编码层,VCL数据保存着被压缩编码后的视频数据序列。

H264码流的组织

一个原始的H.264 NALU 单元常由开始码,数据,序列结束符三部分组成。

其中开始码用于标示这是一个NALU 单元的开始,必须是0x000001和0x00000001。通过该标识定位到一个码流的开始位置,然后分离出NALU;然后再分析NALU的各个字段。

在H264码流中,解码器对于NALU的组织是有一定要求的。一般来说,编码器编出来的首帧数据是PPS,然后是SPS,接下来是I帧,P帧、B帧等。一个解码序列等于一个SPS + 1个PPS + 一个I帧 + 若干P帧 + 若干B帧,SEI数据是可选的。大致如图:

分割符就是一段H264码流数据中的开始码,即0x000001或0x00000001。

SPS/PPS/SEI

列举RBSP的几个主要类型(NALU TYPE):

NALU TYPE 5:IDR

NALU TYPE 6:SEI,Supplementary Enhancement Information补充增强信息

NALU TYPE 7:SPS,Sequence Parameter Set 序列参数集

NALU TYPE 8:PPS,Picture Parameter Set 图像参数集

SPS:中保存了一组视频编码序列(Codec Video Sequence)的全局参数,profile_idc和level_idc等信息。

PPS:对应的是一个序列中某一幅图像或者某几幅图像,序列中每一帧编码后的数据所依赖的参数。

SEI:主要起补充和增强的作用,SEI没有图像数据信息,只是对图像数据信息或者视频流的补充,有些内容可能对解码有帮助。典型的使用场景是附加版权等额外信息。

有兴趣的可以抓包看看这些数据。

视频编码h264怎么看_你所要知道的音视频--04相关推荐

  1. 视频编码h264怎么看_新手怎么上高速,视频拍给你看

    新手怎么上高速,视频拍给你看https://www.zhihu.com/video/1078283038936395776 ​ 其实高速开车并不比市区难的,心态放松一点,掌握一些简单的行车技巧,也不难 ...

  2. 视频编码h264怎么看_怎么用短视频带货最有效?看这一篇就够了

    原标题:怎么用短视频带货最有效?看这一篇就够了 在抖音.快手等平台上做"短视频带货",在当下已经不是一个新鲜事儿了.越来越多的品牌方深刻认识到把短视频作为战略级布局,是企业没得选的 ...

  3. 音视频开发(29)---深入浅出理解视频编码H264结构

    深入浅出理解视频编码H264结构 编码流程: 那么 H.264 其编解码流程是怎么样的呢?其实可以主要分为 5 部分: 帧间和帧内预测(Estimation).变换(Transform)和反变换.量化 ...

  4. Android视频编码--H264编码

    Android视频编码–H264编码 Android中的H264编码有两种编码方式: 硬编码 软编码 1.硬编码 Android中的H264硬编码主要是通过自身提供的API,调用底层的硬件模块实现编码 ...

  5. 短视频用户更倾向于看哪些内容?干净利落的短视频更容易引起好感

    短视频用户更倾向于看哪些内容?干净利落的短视频更容易引起好感 短视频如果想要获得更多用户的喜爱,得到粉丝的关注,那么还应该弄明白一个问题,那就是"短视频用户更倾向于看哪种内容",只 ...

  6. 一名合格的音视频开发人员,需要掌握哪些技能呢?音视频技术该怎么学?

    在线教育.音视频会议.即时通讯等产品都是基于音视频技术开发,如今越来越多的App中都大量加入了音频.视频元素,比如说注册与登陆的扫脸验证,dou音.wei视的音视频变速.变调录制.实时滤镜.人脸识别特 ...

  7. 阿里云视频云低代码音视频工厂正式上线,以vPaaS全新定义企业级音视频应用开发

    1月5日,阿里云视频云"低代码音视频工厂vPaaS"正式上线,极大程度降低音视频开发门槛,打破传统音视频技术壁垒,全新定义企业级的音视频应用开发. 低代码音视频工厂基于云原生.音视 ...

  8. 电脑位数怎么看_怎么用电脑播放4K视频?怎么用电脑看4K电影? 附带详细教程...

    怎么用电脑播放4KUHD超清视频?教你怎么用电脑看4K电影 附带详细教程 电脑播放HDR视频教程,教你怎么在电脑上播放HDR 4k超清视频: HDR这字眼当下火热,心里痒痒的是吗?手中也下载积聚了一些 ...

  9. rpgmvp图片怎么看_拼多多商城图片和视频下载不了怎么办,看这里。。。。

    最近拼多多商城规则变动,很多软件都不能下载拼多多商城图片和视频.小编今天试了一种新的方法可以同时下载商城里的图片和视频.现在一起来看看是如何操作的吧. 准备软件:下图高手高级版软件 实例操作步骤 1. ...

最新文章

  1. android端使用http2.0,android Retrofit2+okHttp3使用总结
  2. mysql 非交互查询 存入execl
  3. html5发展前景-兄弟连,IT兄弟连 HTML5教程 HTML5的曲折发展过程 HTML5的诞生
  4. 【Python】青少年蓝桥杯_每日一题_5.21_画扇子
  5. java中的进制转换
  6. php函数get和set,php中外部类调用_get函数和_set函数的方法
  7. Python简介-01-Python的起源
  8. GlobalAlloc全局内存的使用
  9. 垂直串联六关节机器人调试手册_工业机器人有哪些应用你知道吗?
  10. 巨杉mysql支持临时表_sql server用变量动态命名临时表表名
  11. SQL—— Create table as select 与 使用select查询结果创建新表
  12. 2018-2019-2 《网络对抗技术》Kali安装 Week1 20165212
  13. STL 算法接口及用法说明 (二)
  14. 玩音响发烧友必看的博客
  15. 城市三字码,机场三字码(CITY / AIRPORT 3 LETTERS CODE)
  16. DirectShow 开启摄像头
  17. Android studio基础练习02【监听器实现下拉菜单】
  18. Flutter HotRealod详解
  19. 黑色家具家居茶几沙发网站源码 织梦dedecms模板 [带手机版数据同步]
  20. Zeppelin安装(Docker版)

热门文章

  1. 一个马虎导致以文件输出快速排序结果耗时巨长
  2. C语言—选择控制结构 已知银行整存整取存款不同期限的年息利率 要求输入存钱的期限和本金,求到期时能从银行得到的本金和复利的合计。
  3. 异型窗体制作(两种方法)
  4. c语言批量修改文件名称,C语言实现批量文档名修改
  5. Java面试错题集1
  6. aden -接球游戏 2.0
  7. 职场技巧:如何跟老板谈涨工资?
  8. 什么是CDN什么是高防CDN
  9. matlab 饼状图 纹理,Matlab小波下纹理特征
  10. mysql安装后目录介绍,MySQL安装后的目录结构及配置文件详解