视频编码基础

文章目录

  • 为什么需要视频编码?
  • YUV
  • 帧率
  • 码率
  • QP量化参数
  • 视频编码
    • I帧、P帧、B帧
    • DTS、PTS
  • H.264编码
    • IDR帧和SP帧/SI帧
    • H.264整体框架
    • H.264结构
  • RTP协议
  • H.264载荷RTP码流
    • RTP头
    • RTP载荷
    • 单一NALU

为什么需要视频编码?

以一个分辨率1920×1080,帧率30,RGB888像素24bit的视频为例:
1920×1080=2,073,600(Pixels 像素)
2073600×24=49,766,400 bit
49766400bit = 6220800Byte = 5.93MB
一帧图像5.93MB,30的帧率,一秒的视频就177.9MB,一分钟视频就大约1G,90分钟视频就90G。传输和存储都是问题,所以就需要对视频进行编码。

YUV

RGB信号不利于压缩。在YUV这种方式里面,加入了亮度这一概念。人眼对色度的敏感程度要低于对亮度的敏感程度。所以在视频存储中,没有必要存储全部颜色信号。可以把更多带宽留给黑—白信号(被称作“亮度”),将稍少的带宽留给彩色信号(被称作“色度”)。于是,就有了YUV。YUV里面的Y就是亮度(Luma),U和V则是色度(Chroma)。
视频编码基础_第1张图片
YUV在模拟分量为YPbPr,在数字分量为YCbCr,编码都是对数字信号编码,下面的说YUV都是YCbCr。
常用的YUV有如下三种格式:
YUV 4:4:4采样,每一个Y对应一组UV分量,一个YUV占8+8+8 = 24bits 3个字节。
YUV 4:2:2采样,每两个Y共用一组UV分量,一个YUV占8+4+4 = 16bits 2个字节。
YUV 4:2:0采样,每四个Y共用一组UV分量,一个YUV占8+2+2 = 12bits 1.5个字节。

我们最常见的YUV420P和YUV420SP都是基于4:2:0采样的,存储格式又分为I420(YU12),YV12,NV12,NV21

YUV420P(YU12和YV12)格式
YUV420P又叫plane平面模式,Y , U , V分别在不同平面,也就是有三个平面,它是YUV标准格式4:2:0,主要分为:YU12和YV12,格式如下:
I420: YYYYYYYY UU VV =>YUV420P
YV12: YYYYYYYY VV UU =>YUV420P

YUV420SP(NV12和NV21格式)
YUV420SP格式的图像阵列,首先是所有Y值,然后是UV或者VU交替存储,NV12和NV21属于YUV420SP格式,UV(CbCr)为交错存储,格式如下:
NV12: YYYYYYYY UVUV =>YUV420SP
NV21: YYYYYYYY VUVU =>YUV420SP

帧率

帧率与画面流畅度成正比:帧率越大,画面越流畅;帧率越小,画面越有跳动感。人眼如果所看画面之帧率高于16的时候,就会认为是连贯的。如果码率为变量,则帧率也会影响体积,帧率越高,每秒钟经过的画面越多,需要的码率也越高,体积也越大。帧率就是在1秒钟时间里传输的图片的帧数。

码率

视频码率就是数据传输时单位时间传送的数据位数,一般我们用的单位是kbps即千位每秒。通俗一点的理解就是取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件。
但是文件体积与取样率是成正比的,所以几乎所有的编码格式重视的都是如何用最低的码率达到最少的失真,围绕这个核心衍生出来的cbr(固定码率)与vbr(可变码率)

CBR固定码率(constant bitrate):
以恒定比特率方式进行编码,有运动发生时,由于码率恒定,只能通过增大QP来减少码字大小,图像质量变差,当场景静止时,图像质量又变好,因此图像质量不稳定。这种算法优先考虑码率(带宽)。适合在流式播放中应用。CBR编码的缺点在于编码内容的质量不稳定

ABR平均码率(average bitrate):

平均比特率,是在CBR和VBR两者之间的一种权衡,即设定一段时间的平均码率,在此时间内,对简单,静态的图像分配低于平均码率的码率,对于复杂的,大量运动的图像分配高于平均码率的码流;适合网络传输;

VBR可变码率(variable bitrate):

以可变的比特方式进行编码,比特分配根据图像内容的复杂度进行。如果图像细节较丰富或者含有大量的运动,则给其分配大一点的码流,若图像比较平坦,就给其分配较少的码流,这样既保证了质量,又兼顾带宽限制。这种算法适合图像内容变化幅度较大的情况适合的应用场景是媒体存储,不适合网络传输;

QP量化参数

现有的 码率控制 算法主要是通过调整离散余弦变换的 量化参数 大小输出目标码率。实际上,量化参数( QP )反映了空间细节压缩情况,如 QP 小,大部分的细节都会被保留; QP 增大,一些细节丢失,码率降低,但图像失真加强和质量下降。也就是说, QP 和比特率成反比的关系,而且随着视频源复杂度的提高,这种反比关系会更明显。
好的画质是分辨率、帧率和码率三者之间的平衡

视频编码

视频编码基础_第2张图片
如果一幅图,所有像素都是一个颜色,那么就可以只发一个像素并告诉对方有多大范围这样的像素即可,如果一段视频,有80%图像都是不动的,那么这块存储开销也可以节省下来,这些能节省内容就是视频中的冗余信息。
视频编码就是为了压缩。要实现压缩,就要设计各种算法,将视频数据中的冗余信息去除。

种类 内容 压缩方法
空间冗余 像素间的相关性 变换编码,预测编码
时间冗余 时间方向上的相关性 帧间预测,运动补偿
图像构造冗余 图像本身的构造 轮廓编码,区域分割
知识冗余 收发两端对图像的共有认识 基于知识的编码
视觉冗余 人的视觉特性 非线性量化,位分配
其他 不确定行因素

视频编码技术优先消除的目标,就是空间冗余和时间冗余。

I帧、P帧、B帧

I帧:I帧采用帧内编码方式,是自带全部信息的独立帧,是最完整的画面(占用的空间最大),无需参考其它图像便可独立进行解码。视频序列中的第一个帧,始终都是I帧。
I帧的特点:
它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输;
解码时仅用I帧的数据就可重构完整图像;
I帧描述了图像背景和运动主体的详情;
I帧不需要参考其他画面而生成;
I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);
I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧;
I帧不需要考虑运动矢量;
I帧所占数据的信息量比较大。

P帧:“帧间预测编码帧”,需要参考前面的I帧和/或P帧的不同部分,才能进行编码。P帧对前面的P和I参考帧有依赖性。但是,P帧压缩率比较高,占用的空间较小。
P帧的特点
P帧是I帧后面相隔1~2帧的编码帧;
P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差);
解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;
P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;
P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;
由于P帧是参考帧,它可能造成解码错误的扩散;
由于是差值传送,P帧的压缩比较高。

B帧:“双向预测编码帧”,以前帧后帧作为参考帧。不仅参考前面,还参考后面的帧,所以,它的压缩率最高。
B帧的特点
B帧是由前面的I或P帧和后面的P帧来进行预测的;
B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量;
B帧是双向预测编码帧;
B帧压缩比最高,因为它只反映丙参考帧间运动主体的变化情况,预测比较准确;
B帧不是参考帧,不会造成解码错误的扩散。
视频编码基础_第3张图片

DTS、PTS

DTS(解码时间戳),PTS(显示时间戳),为什么要有这两个东西呢?前面说过B帧是双向预测帧,需要依赖前面的I帧或P帧以及后面的P帧才能生成B帧,如果B帧后边还不是P帧怎么办,只能等到后面的P帧生成,举个例子吧,假设视频帧如下:

1 2 3 4 5 6 7
I帧 B帧 B帧 P帧 B帧 B帧 P帧

B帧只能依靠后边的P帧才能生成,所以编码顺序是如下的:

1 4 2 3 7 5 6
I帧 P帧 B帧 B帧 P帧 B帧 B帧

传输顺序与解码顺序DTS也相同的

1 4 2 3 7 5 6
I帧 P帧 B帧 B帧 P帧 B帧 B帧

最后显示顺序一看不对,按PTS调整回来

1 2 3 4 5 6 7
I帧 B帧 B帧 P帧 B帧 B帧 P帧

H.264编码

这里也只是介绍H.264编码的格式,并没有H.264的原理和算法。

IDR帧和SP帧/SI帧

IDR帧:
IDR(Instantaneous Decoding Refresh)–即时解码刷新:
在H.264中引入IDR帧的概念,IDR帧一定是I帧,但I帧不一定是IDR帧。对于IDR帧来说,在IDR帧之后的所有帧都不能引用任何IDR帧之前的帧的内容。
SP帧/SI帧
SP和SI是H264中引入的新技术,主要是为了适应视频流的带宽自适应和抗误码性能的要求,主要应用于流媒体服务。
SP帧就是指能够参考不同的参考帧重构出相同的图像帧。(SP和SI不同在于SI是基于帧内预测,SP是基于帧间预测),在某些场景,SP帧可以替代I帧,主要用于多码流之间的切换、图像和视频的拼接,SP帧效率低于P帧,高于I帧,在复杂的多码流,弱网的情况下,提高了适应能力和抗干扰能力。
  流媒体服务自身有一些特征,网络状况是一直变化的,有时候比较繁忙,有时候则比较空闲。针对不同的网络条件,服务器可能提供几种不同质量的数据服务,当网络比较差时,提供比较差但是码率低的服务,当网络好时候,提供比较好码率高的服务。由于视频的编码是参考帧预测的基础上,在不同的条件下切换时很可能会出现丢帧的现象,这种时候SP帧和SI帧就派上用场了。

H.264整体框架

H.264整体框架
视频编码基础_第4张图片
H264可以分为2层:视频编码层『VCL』和网络提取层『NAL』。
 VCL(Video Coding Layer)是管理H264视频数据层,VCL主要做了以下事情。
1、压缩:预测(帧内预测和帧间预测)-> DCT变化和量化 -> 比特流编码;
2、切分数据,切片(slice)、宏块(macroblock)都是VCL一层的。
3、包装成NAL。
 NAL(Network Abstraction Layer)旨在提供网络友好性,以便为各种系统简单有效地定制VCL的使用。 NAL有助于将VCL数据映射到传输层,例如:RTP 实时传输。 用于广播服务等的MPEG-2系统。

VCL(Video Coding Layer),视频编码层,H264编码/压缩的核心,主要负责将视频数据编码/压缩,再切分。NAL(Network Abstraction Layer),网络抽象层,负责将VCL的数据组织打包。

H.264结构

H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16x16的yuv数据组成。宏块作为H264编码的基本单位。如下所示:
视频编码基础_第5张图片
NAL将VCL编码处理后的数据,
映射或封装进 NAL 单元(以下简称 NALU,Nal Unit) 中。每个 NALU 包括一个原始字节序列负荷(RBSP, Raw Byte Sequence Payload)、一组对应于视频编码的 NALU 头部信息。H264帧由多个NALU和起始码(start code)组成,格式如下:
视频编码基础_第6张图片
NAL头(NAL header)用于标识NAL单元中的RBSP数据类型,|- F -|- NRI -|- Type -|长度一字节,F禁止位在编码中默认值为0出错可设置为1;NRI重要程度;Type类型中,nal_unit_type为1, 2, 3, 4, 5的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL单元,类型如下:。
视频编码基础_第7张图片

  • A、B和C类数据分割组成Slice的Coded Data被存放在三种数据分割中,A、B和C类数据分割。每种分割包含Coded Slice的一个子集。每种分割被单独的存放在一个NAL单元中,因此可以被单独传输。
    A类数据分割:包含Slice的头和每个宏块的头;
    B类数据分割:包含Intra和SI Slice宏块的被编码的Residual数据;
    C类数据分割:包含P、B和SP Slice宏块的被编码的Residual数据。
    如果A类数据分割丢失,很难甚至不可能重构其所在的Slice。三类数据分割在对错误的容忍度方面相比,A最不能容忍错误的出现,而C的容错能力最强。在一个容易出错的环境,提高性能的策略包括:对这三种数据分割应用非均匀错误保护。例如,对A类数据分割使用向前纠错,通过不同的通道传输不同类型的数据分割,或者给A类数据分割选择一个最可靠的通道。

  • PPS是携带解码参数的NAL Units。发送这些参数采用独立于Coded Slices的方式能够提高效率,因为共用的参数仅仅需要传输一次。Parameter Sets(PPS)对于正确的解码是非常重要的。在一个有损耗的传输场景,在传输过程中比特流或包可能丢失或损坏。在这种网络环境中,Parameter Sets可以通过高质量的服务来发送,比如向前纠错机制或优先级机制。

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

  • SPS(Sequence Parameter Set)包含一些通用的参数,比如Profile和Level,比如视频帧的尺寸,参考帧的最大数量等,这些参数对整个Video Sequence或者Programme都是通用的。PPS(Picture Parameter Set)包含一些通用的参数,比如熵编码类型,有效的参考图像的数目和初始化参数等,这些参数可以应用到一个Video Sequence或者一部分编码帧。
    典型的H.264视频序列如下:

RTP协议

RTP实时传输协议(Real-time Transport Protocol)。是IETF提出的一个标准,对应的RFC文档为RFC3550(RFC1889为其过期版本)。RFC3550不仅定义了RTP,而且定义了配套的相关协议RTCP(Real-time Transport Control Protocol,即实时传输控制协议)。RTP用来为IP网上的语音、图像、传真等多种需要实时传输的多媒体数据提供端到端的实时传输服务。RTP为Internet上端到端的实时传输提供时间信息和流同步,但并不保证服务质量,服务质量由RTCP来提供。

H.264载荷RTP码流

RFC3984是H.264的baseline码流在RTP方式下传输如下:
视频编码基础_第8张图片
NALU打包到RTP码流格式如下:
视频编码基础_第9张图片

RTP头

RTP头的格式如下:
视频编码基础_第10张图片

  1. V:RTP协议的版本号,占2位,当前协议版本号为2
  2. P:填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
  3. X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头
  4. CC:CSRC计数器,占4位,指示CSRC 标识符的个数
  5. M: 标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。
  6. PT(payload type): 有效荷载类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等,在流媒体中大部分是用来区分音频流和视频流的,这样便于客户端进行解析。
  7. 序列号:占16位,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。这个字段当下层的承载协议用UDP的时候,网络状况不好的时候可以用来检查丢包。当出现网络抖动的情况可以用来对数据进行重新排序。序列号的初始值是随机的,同时音频包和视频包的sequence 是分别记数的。
  8. 时戳(Timestamp):占32位,必须使用90 kHz 时钟频率(程序中的90000)。时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。可以根据RTP包的时间戳来获得数据包的时序。
  9. 同步信源(SSRC)标识符:占32位,用于标识同步信源。同步信源是指产生媒体流的信源,它通过RTP报头中的一个32位数字SSRC标识符来标识,而不依赖于网络地址,接收者将根据SSRC标识符来区分不同的信源,进行RTP报文的分组。该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。此标识不是随机选择的,目的在于使同一RTP包连接中没有两个同步源有相同的SSRC标识。尽管多个源选择同一个标识的概率很低,所有RTP实现都必须探测并解决冲突。如源改变源传输地址,也必须选择一个新SSRC标识以避免插入成环行源。
  10. 提供信源(CSRC)标识符:每个CSRC标识符占32位,可以有0~15个CSRC。每个CSRC标识了包含在该RTP报文有效载荷中的所有提供信源。提供信源用来标志对一个RTP混合器产生的新包有贡献的所有RTP包的源。是指当混合器接收到一个或多个同步信源的RTP报文后,经过混合处理产生一个新的组合RTP报文,并把混合器作为组合RTP报文的SSRC,而将原来所有的SSRC都作为CSRC传送给接收者,使接收者知道组成组合报文的各个SSRC。

RTP载荷

RTP载荷第一个字节格式跟NALU头一样:

|- F -|- NRI -|- Type -|

F和NRI也跟NALU头一样,只有Type有些不一样:

Type 定义 描述
1-23 NAL单元 单个 NAL 单元包
24 STAP-A 单一时间的组合包
25 STAP-B 单一时间的组合包
26 MTAP16 多个时间的组合包
27 MTAP24 多个时间的组合包
28 FU-A 分片的单元
29 FU-B 分片的单元
30-31 没有定义

可以看到NALU类型23往后未定义的部分就留给了RTP额外的类型,载荷格式定义三个不同的基本荷载结构,接收者可以通过RTP荷载的第一个字节后5位(Type)识别荷载结构:

  1. 单个NAL单元包:荷载中只包含一个NAL单元。NAL头类型域等于原始 NAL单元(NALU)类型,即Type在范围1到23之间。
  2. 聚合包(组合包):NALU长度过于小把多个NALU装到一个RTP载荷里,本类型用于聚合多个NAL单元到单个RTP荷载中。本包有四种版本,单时间聚合包类型A (STAP-A),单时间聚合包类型B (STAP-B),多时间聚合包类型(MTAP)16位位移(MTAP16), 多时间聚合包类型(MTAP)24位位移(MTAP24)。赋予STAP-A, STAP-B, MTAP16, MTAP24的NAL单元类型号(Type)分别是 24,25, 26, 27
  3. 分片包:NALU长度过于长,大于MTU的采用分片包,用于分片单个NAL单元到多个RTP包。现存两个版本FU-A,FU-B,用NAL单元类型 (Type)28,29标识。常用的打包时的分包规则是:如果小于MTU采用单个NAL单元包,如果大于MTU就采用FUs分片方式。

单一NALU

单一NALU载荷如下:
视频编码基础_第11张图片
NAL单元的第一字节和RTP荷载头第一个字节重合。RTP打包时去除起始码 “00 00 01” 或 “00 00 00 01” , 把其他数据封装成 RTP 包即可。
分块结构和组合结构就不详细介绍了,感兴趣看看下面两篇博客https://blog.csdn.net/bytxl/article/details/50395427和https://blog.csdn.net/chen495810242/article/details/39207305。

参考:https://www.jianshu.com/p/0c296b05ef2ahttps://www.jianshu.com/p/0ecb499ebc65
https://blog.csdn.net/u010178611/article/details/82592393
https://blog.csdn.net/chen495810242/article/details/39207305

你可能感兴趣的:(视频编码)