在流媒体的平台搭建过程中,编码是无法避免的一个话题,为什么要编码?熟悉流媒体的朋友都知道,编码是为了压缩原有输入源的大小,使其更好的适应网络带宽,特别是在网络带宽不是很好的情况,所以学习流媒体,编码技术的理解和学习显得很重要,首先我们就来讲讲编码的基础知识。这里以H264为例子来讲解。
H264是什么?
H264是市面上常见的编码算法,其中编码后的文件,能够高效的在网络实现传输,在当前的视频直播、安防、教育等领域应用十分广泛,具有重要的应用价值。与MPEG-4不同,H264重点考虑了压缩的高效率和高可靠的网络传输。H264有三个不同档次,分别是"baseline"、"profile"、"main",分别都应用在不同实际的场景。
![805368b1ff773005165b38ee433ab403.png](https://i-blog.csdnimg.cn/blog_migrate/da27e4583940c8b5954a107a92e6ac9f.jpeg)
h264编码器
![2c0ebf2644f82c55d18cd166438aa6b2.png](https://i-blog.csdnimg.cn/blog_migrate/b6a4d25463fe7f92c124591cde8bddb4.jpeg)
编码基本流程
一般编码的基本流程分为宏块切割,时域变换频域,量化,熵编码等步骤。常用的变换,比如DCT变换,DCT变换可以减少计算量,降低解码时的预测漂移。量化过程在目的是减少图像编码长度,减少冗余信息,这些冗余信息都是视觉中难以察觉的信息。熵编码的基本原理是无损压缩编码方法,生成的码流可以在解码端,无失真的恢复出原数据。熵编码算法一般分为CAVLC和CABAC。下面简单分析下,这两种算法的原理。
CAVLC(基于上下文可变长编码)
主要用于亮度和色度残差数据编码,由于在量化后,非零系数主要在低频部分,高频大部分是0,量化后的数据经过 zig-zag 扫描,DC 系数附近的非零系数值较大,而高频位置上的非零系数值大部分是+1 和-1,CAVLC充分利用残差经过整数变换,量化后数据的特性进行压缩,减少冗余信息。
CABAC(基于上下文自适应二进制)
主要在复杂度和效率之间折中,基于一个查表概率模型。这是一种由大量实验统计而得到的概率模型。在编码时,需要动态选择概率模型进行编码,及时更新响应的概率模型。
H264在复杂的场景中,压缩和编码算法的性能非常优异,当在弱网的场景下,损耗比较小,这是由信道畸变带来的自适应方法比较好。
由上图知道,编码都是以宏块为单位进行的,首先按帧内或帧间预测编码进行处理,其中帧内主要是针对I帧进行,I帧一般是没有压缩或者压缩很低的,因为I帧是一组GOP的参考帧,如果没有了I帧,后面的P帧、B帧也无法解码出来,就会出现马赛克或者解码错误的情况。帧间编码主要是在B帧、P帧的情况。为了充分利用参考帧,H264使用"残差"编码,编码器要想重建图像,就必须使得残差经过反量化,为了去除噪声,提高图像的质量,往往还需要有Fliter,这种方式结构在大量的编码器中有应用,比如经典的FFmpeg,后面的文章我会详细的分析。
- 宏块(block)、slice
在视频的编码中,一副图像可以是一帧或者一场,一帧由奇数场和偶数场构成,有些应用场景就是用场来实现编码。一帧图像通常由很多个宏块组成,比如8X8的彩色像素块,多个宏块又会组成Slice的形式,I片只包含I宏块,P和B片可以由I宏块、P宏块或者B宏块。
![f154e515503b0fd23c1bbba4ff17a17d.png](https://i-blog.csdnimg.cn/blog_migrate/0bc85f7a070cbed11894327a300f1fea.jpeg)
场与帧
![90922dca8e11155c81857dd449f589ce.png](https://i-blog.csdnimg.cn/blog_migrate/a865edc9e4e3fa0d8718d96482b7eb61.jpeg)
帧模式
![45dc6b55782ea39f8119ee8bcd420122.png](https://i-blog.csdnimg.cn/blog_migrate/20f24024c10ec00b5f68a0d433791e34.jpeg)
场模式
2.档次
basline:使用I帧、P帧编码,使用自适应的变长编码的熵编码(CAVLC)。
main:使用B帧,支持基于上下文的算术编码(CABAC)
Extended profile:支持多路码流间的有效切换,比如在码流发生变化时,SP与SI的信息切换,改变误码性能等
由于每个档次设置不同参数,如码率,采样率等,就可以得到不同的级别。
3.H264编码格式
H264主要分为2层,VCL(视频编码层)和NAL(网络提取层),VCL实际就是编码器的输出,然后把编码器的序列封装在NAL里面,形成一个个NAL单元,适应不同网络带宽,每个NAL单元包括一个RBSP和NAL头信息。
![d47361474dea99c479f8e9f76826f2f3.png](https://i-blog.csdnimg.cn/blog_migrate/b3b71c877f02c21b2773883ca1b7a38f.jpeg)
NAL单元序列
![18214d538cce543627268f0b636c357a.png](https://i-blog.csdnimg.cn/blog_migrate/15335c4335b31ba19642ee1b066a3a06.jpeg)
RBSP描述
什么叫参数集?参数集就是记录了编码序列的特征信息。如sps记录了帧数,I帧数目,图像size等信息。PPS记录了一个序列中编码模式选择,slice group数目,Fliter信息等。SPS和PPS在编码前会被写入头部,与实际的数据隔离。
4.Slice和Slice group
一副视频图像是由一个或者多个slice组成,每个slice包含一个或者若干个宏块,Slice可以帮助编码器实现误码的扩散和传输,相互间独立的,一片的预测不能以其它片中的宏块为参考图像,某一片的预测误差就不会影响到其它片中。
slice共有5种不同类型,I、P、B、SP、SI,这些类型有不同的片头,包含了不同的block,以下是一个大概图示说明,他们之间的关系。
![8c735264f3853b3c3525d667f2d7e8fb.png](https://i-blog.csdnimg.cn/blog_migrate/19a84f9004bbf22162314e956a1e3d02.jpeg)
slice语法结构
slice group可以包含多个slice,如下所示:
![d7c5d6ab626f0168172ca3e4ee8f73e5.png](https://i-blog.csdnimg.cn/blog_migrate/89fc3749dcc433726cb0d3ab44074d75.jpeg)
slice group
5.帧内预测
帧内预测是基于内部像素数据进行重建,P块用于4x4或16x16的相关操作,其中4x4有9种可选预测模式,16x16预测有4种预测模式。如下图的图标所示:
![2ce698c05d4fa2f4258bcd73dc85b40d.png](https://i-blog.csdnimg.cn/blog_migrate/b061937cfd9d050d98de70f9198dbe84.jpeg)
4x4预测模式
![707023c0c1b11770618d8f802ea3a808.png](https://i-blog.csdnimg.cn/blog_migrate/e581cd969a1df975ece9b6b1838b4afb.jpeg)
预测模式简介
![2f94f5db708f668bff01a2c3965b77d8.png](https://i-blog.csdnimg.cn/blog_migrate/3e8fea39e1a9b73835c6ff049e8d0bbd.jpeg)
预测块简介
16x16预测模式分为整体预测,有4种预测模式,如下所示。
![40a28f2814ef3e53b2dd3118bf448051.png](https://i-blog.csdnimg.cn/blog_migrate/4535ece440bd7f3e2b5f6d934e94bccb.jpeg)
16x16预测模式
![1685d0711996b4a332f39a522e4fbc70.png](https://i-blog.csdnimg.cn/blog_migrate/a711dac2342aa0e196b10a41ba20a7ae.jpeg)
16x16预测块
6.帧间预测
H264的帧间预测是基于运动补偿的预测模式,比如有各种类型的运动补偿,比如树状运动补偿。
7.H264的SP和SI
SP和SI帧基于帧间预测的运动补偿预测编码,SP的功能主要是使用不同的参考帧构建出相同图像帧,在某些场景下,SP帧可以替代I帧,主要用于多码流之间切换,图像和视频的拼接,SEEK等操作。SP帧编码效率低于P帧,高于I帧,这样在复杂的多码流,弱网的情况下,提高了适应能力和抗干扰能力。
![80a5a4c555c243df3aa015b1361b571c.png](https://i-blog.csdnimg.cn/blog_migrate/26838bcdbc3292f8b5c00a9db447d881.jpeg)
SP帧流间切换
![bdc86ce744e06c7a829c2aa2a7e94e56.png](https://i-blog.csdnimg.cn/blog_migrate/075cd469fbcb46e955d51d2886632634.jpeg)
画面拼接
![81c38ef77c7ccd40f474843d8c47bff8.png](https://i-blog.csdnimg.cn/blog_migrate/ab21ad5cbc1ccd6b5bb9640bc1619573.jpeg)
SP帧错误恢复
8.Fliter
如果反量化后出现马赛克效应,产生的原因有2个,最重要的是残差的DCT变换和量化。反量化过程中,变换系数有误差,会造成视觉不连续。解决这种问题,就需要有后置滤波器和环路滤波器。这两种滤波器也应用在不同场景中,
上面只是介绍了编解码的基本知识,偏重理论,虽然有些朋友觉得枯燥乏味,但是学好了理论,才能指导实践,后面的文章也会结合不同的平台,结合代码来讲解流媒体的相关技术。由于篇幅和时间的限制,不能把整个编码的基础知识全部讲完,后面会有详细的补充。欢迎各位朋友阅读和交流。