音视频--视频入门

2,609 阅读11分钟

H264

单纯传输视频画面,视频量非常大,对现有的网络和存储来说是不可接受的。

为了能够使视频便于传输和存储,人们发现视频有大量重复的信息,如果将重复信息在发送端去掉,在接收端恢复出来,这样就大大减少了视频数据的文件,因此有了H.264视频压缩标准。

I帧

又称为关键帧或者帧内编码帧,采用帧内压缩技术。

是一种自带全部信息的独立帧,无需参考其他图像便可独立进行解码,可以简单理解为一张静态画面。视频序列中的第一个帧始终都是I帧,因为它是关键帧。

P帧

又称为向前参考帧帧间预测编码帧,采用帧间压缩技术。

除了I帧之外的所有帧,全部向前依赖。

所有帧都只保存与前一帧的差异,以达到高压缩率的效果。

解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。

B帧

又称为刷双向参考帧,属于帧间压缩技术。

即参考前一帧,也参考后一帧。以达到比P帧更高的压缩效果。

也就是说要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。对于直播业务,B帧比P帧永远要慢一点。

B帧压缩率高,但是对解码性能要求较高。

比较

  • I帧只需考虑本帧

  • P帧记录的是与前一帧的差别

  • B帧记录的是前一帧及后一帧的差别

      能节约更多的空间,视频文件小了,但相对来说解码的时候就比较麻烦。
      因为在解码时,不仅要用之前缓存的画面,而且要知道下一个I或者P的画面,对于不支持B帧解码的播放器容易卡顿。
    

视频监控系统中预览的视频画面是实时的,对画面的流畅性要求较高。采用I帧、P帧进行视频传输可以提高网络的适应能力,且能降低解码成本所以现阶段的视频解码都只采用I帧和P帧进行传输。


GOP

Group of Pictures 一组帧

相似画面的一组帧

如下图所示,两个I帧之间的所有帧,叫做一组帧。

具体的划分细节,在下面《帧分组》的部分会提到

SPS

序列参数集 Sequence Parameter Set

包含一组帧中:存放帧数、参考帧数目、解码图像尺寸、帧场编码模式选择标识等

PPS

图像参数集 Picture Parameter Set

包含一组帧中:存放熵编码选择模式标识、片组数目、初始量化参数和去方块过滤波系数调整标识等

在一组帧中,SPS与PPS也属于I帧。


视频出现花屏、卡顿的原因

  • 丢帧造成花屏

    当一组帧中丢失了某一帧,就会造成某个部分没有完成更新。造成花屏。

  • 丢GOP造成卡顿

    为了避免花屏的问题,当发现I帧或P帧丢失,则不现实本GOP中所有的内容。知道下一个I帧到达后重新刷新图像。


视频编解码器

  • x264/x265

x264是目前使用最广泛的H264编解码器(主要用来编码,解码用ffmpeg)。 x265的压缩率比x264更高,性能的消耗也更大。

  • openH264

相对x264性能较低,但支持SVC技术。

SVC可以将视频分层传输:

可以对用户带宽进行不同策略的定制方案:将一帧数据分为小、中、大三个部分,根据对方网络情况分别追加发送。

接收到的部分越多,最后组合起来的视频就越清晰。

但由于很多手机不支持SVC编码,所以需要使用软编处理,会对CPU产生损耗。

  • vp8/vp9

Google出品,分别对应x264/x265


H264压缩技术

这部分最后发现李超老师自己已经写过博客了,建议去看原文

帧内预测压缩

解决空域数据的冗余问题

空域数据,类似音频中的超声波段,不容易甚至不会被人类注意识别。

帧间预测压缩(运动估计与补偿)

解决时域数据的冗余问题

时域数据,对于监控之类静止不动的画面,对帧与帧之间重复的数据进行计算压缩。

整数离散余弦变换(DCT)

将空间上的相关性变为频域上无关的数据然后进行量化

CABAC压缩(无损压缩)

类似哈夫曼无损编码

宏块划分

对于一段视频,首先会被送到 H264 编码器的缓冲区中,并为每一帧图片进行宏块的划分

  • 划分宏块

    H264默认是使用 16X16 大小的区域作为一个宏块,也可以划分成 8X8 大小。

  • 计算宏块的象素值

    对宏块中的每一个像素点进行计算

    最终一幅图会变成这个样子

  • 划分子块

    对于复杂的图片或局部,H264可以对宏块进行更细致的划分以达到更高的压缩率,比如8X16、 16X8、 8X8、 4X8、 8X4、 4X4

    这样对于小局部像素颜色相同的子块,就可以用很少的信息进行表示

帧分组

宏块划分好后,还需要对编码器缓存中所有的图片进行分组(GOP)

帧间预测压缩主要在这里解决时域数据的冗余问题:

对于某些关联特别密切的帧,其实我们只需要保存一帧的数据,其它帧都可以通过这一帧再按某种规则预测出来,所以说视频数据在时间上的冗余是最多的。

如何判定两帧处在一个GOP中?以一个的台球桌的视频为例:

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

通过宏块扫描与宏块搜索可以发现这两个帧的关联度是非常高的。进而发现这一组帧的关联度都是非常高的。因此,上面这几帧就可以划分为一组。

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

帧间压缩技术(运动估计与补偿)

也叫运动估计与补偿,用于压缩时间层面的冗余,清除相同数据。

对于一组帧,需要计算运动物体的运动矢量:

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

下面这幅图就是搜索后的台球移动的位置

H264依次把每一帧中球移动的距离和方向都记录下来就成了下面的样子

运动矢量计算出来后,将相同部分(也就是绿色部分)减去,就得到了补偿数据。我们最终只需要将补偿数据进行压缩保存,以后在解码时就可以恢复原图了。压缩补偿后的数据只需要记录很少的一点数据。如下所示

帧内压缩技术

人眼对图象都有一个识别度,对低频的亮度很敏感,对高频的亮度不太敏感。所以基于一些研究,可以将一幅图像中人眼不敏感的数据去除掉。这样就提出了帧内预测技术。

H264的帧内压缩与JPEG很相似。一幅图像被划分好宏块后,对每个宏块可以进行 9 种预测模式。找出与原图最接近的一种预测模式。帧内预测后的图像与原始图像的对比如下:

将预测图像与原图像对比得到残差值,解码时根据记录下来的预测模式残差值,即可还原出原本的图像。

DCT压缩

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

比如:

压缩后变成

VLC与CABAC(无损压缩)

根据信息出现的频率,对整体进行压缩

参考哈夫曼编码:对高频信息使用短码,而低频信息使用长码进行压缩。

MPEG-2中使用的VLC就是这种算法

而在H264中,使用CABAC进行压缩,不只对频率进行压缩,还根据上下文进行进一步压缩

对于视频帧,在有了上下文之后,剩下的帧会进一步压缩


H264结构与码流

H264结构

从大到小,H264的视频结构如下所示 视频流 => N个视频帧 => N个切片 => 切片头+N个宏块 => N个子块

H264编码分层

  • NAL层

网络抽象层 以太网单个数据包限制为1500字节,NAL可以将单帧数据进行拆包与组包处理,以进行传输。

  • VCL层

视频编码层 对视频的原始数据进行压缩

H264码流

  • SODB(String Of Data Bits)

原始数据比特流由NAL层产生。长度不一定是8字节的倍数

  • RBSP(Raw Byte Sequence Packet)

SODB末尾补1,然后补零成8位。

  • EBSP(Encapsulate byte sequence payload)

起始标记的格式化

  • NALU(NAL Unit)

EBSP前加一个1B的网络头


NALU

NALU HEADER

NALU 头部信息,由三部分构成

对于Type(nal_unit_type):

1, 2, 3, 4, 5及12的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL单元。

0:未规定
1:非IDR图像中不采用数据划分的片段
2:非IDR图像中A类数据划分片段
3:非IDR图像中B类数据划分片段
4:非IDR图像中C类数据划分片段
5:IDR图像的片段
    IDR帧属于I帧,此位置代表关键帧的一部分
6:补充增强信息 (SEI)
7:序列参数集/SPS
8:集图像参数/PPS
    SPS和PPS都是特殊的NALU。一个MP4文件只有一个SPS,但是有很多PPS,SPS必须在所有NALU的最开头。
9:分割符
10:序列结束符
11:流结束符
12:填充数据
13 – 23:保留
24 – 31:未规定 (27、28表示为分片NALU)

NAL

单一类型

一个RTP数据包中只包含一个NALU(切片)

很多P帧、B帧都是单一类型

组合类型

一个RTP数据包中包含多个NALU

比如SPS、PPS通常就会放在同一个RTP数据包内进行发送

分片类型

一个NALU被分片成多个RTP数据包发送


图像的存储格式

RGB

红、绿、蓝。每个元素1字节,共24位

YUV

从电视系统中衍生出来的一套颜色编码方式

  • Y

明亮度(灰阶值)。基础信号,非黑即白

  • U&&V

色彩和饱和度。用于指定像素颜色

  • YUV的格式

YUV常见格式可以参阅:YUV格式介绍

其中最常见的是YUV 4:2:0,相对RGB 8:8:8的格式,节省了很多空间。

YUV 4:2:0并不意味着没有V分量,而是只在相邻的分行扫描中一行采用YUV 4:2:0,下一行采用YUV 4:0:2这种抽样存储。

  • YUV的存储格式

可以参阅视频存储格式YUV420 NV12 NV21 i420 YV12


参考资料

视频编码之I帧 、P帧、B帧

H264基本原理

一些关于H.264的术语

H264中的NALU概念解析

TCP、UDP、RTP(RTCP)异同与区别