视频技术

2023312145123

视频基础

色彩格式

GRAY

YUV图像示例

yuv420格式表示宽度为 6、高度为 4的图像

2022111195211

色相(H)是色彩的基本属性,就是颜色名称,如红色、黄色等;饱和度(S)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取 0~100% 的数值;明度(V)和亮度(L),同样取 0~100% 的数值

2022111195421

色彩空间

也叫色域,指某种表色模式用所能表达的颜色构成的范围区域

帧率

一秒钟刷新的视频图像帧数

码率

指视频在单位时间内的数据量的大小,一般是 1 秒钟内的数据量,其单位一般是 Kb/s 或者 Mb/s

分辨率

分辨率通常由宽、高与像素点占用的位数组成,计算方式为图像的宽乘以高

Stride

指的是图像存储时内存中每行像素所占用的空间,为了能够快速读取一行像素,我们一般会对内存中的图像实现内存对齐,比如 16 字节对齐

2023312145940

如果读取时没有跳过这些填充的区域,那么渲染出来的图像就完全错了,产生花屏

缩放算法

目前绝大多数图像的缩放还是通过插值算法:都是使用周围已有的像素值通过一定的加权运算得到“插值像素值”

2023312152254

插值算法:

2023312152848

视频编码

原理

视频由一帧帧图象个构成,而对于每一帧图像,又是划分成一个个块来进行编码

图像一般都是有数据冗余:

帧内预测

在当前编码图像内部已经编码完成的块中找到与将要编码的块相邻的块,再用编码块减去每一个预测块得到一个个残差块。最后,我们取这些算法得到的残差块中像素的绝对值加起来最小的块为预测块

帧又是由一块块数据组成的,对于块有如下规则:

在实际帧内预测的时候就会分为:4 x 4 亮度块的预测、16 x 16 亮度块的预测、8 x 8 色度块的预测

4 x 4 亮度块的 9 种预测模式:

  1. Vertical 模式:当前编码亮度块的每一列的像素值,都是复制上边已经编码块的最下面那一行的对应位置的像素值
  2. Horizontal 模式:当前编码亮度块的每一行的像素值,都是复制左边已经编码块的最右边那一列的对应位置的像素值
  3. DC 模式:当前编码亮度块的每一个像素值,是上边已经编码块的最下面那一行和左边已编码块右边最后一列的所有像素值的平均值
  4. Diagonal Down-Left 模式:上边块和右上块的像素通过插值得到
  5. Diagonal Down-Right 模式:过上边块、左边块和左上角对角的像素通过插值得到。如果这三个有一个不存在则该模式无效
  6. Vertical-Right 模式:通过上边块、左边块以及左上角对角的像素插值得到的。必须要这三个都有效才能使用,否则该模式无效
  7. Horizontal-Down 模式:通过上边块、左边块以及左上角对角的像素插值得到。必须要这三个都有效才能使用,否则该模式无效
  8. Vertical-Left 模式:通过上边块和右上块最下面一行的像素通过插值得到
  9. Horizontal-Up 模式:通过左边块的像素通过插值得到的。如果左边块不存在,则该模式不可用

16 x 16 亮度块总共有4种预测模式。它们分别是Vertical模式,Horizontal模式、DC 模式和Plane 模式

8 x 8 色度块的帧内预测模式:DC 模式、Vertical 模式,Horizontal 模式、Plane 模式

帧间预测

帧间预测的块划分类型要多很多。宏块大小 16 x 16,可以划分为 16 x 8,8 x 16, 8 x 8 三种,其中 8 x 8 可以继续划分成 8 x 4,4 x 8 和 4 x 4

通常在 RTC 场景中,P 帧中的所有块都参考同一个参考帧。并且一般会选择当前编码帧的前一帧来作为参考帧,这是由图像运动的局部性原理导致的:自然界的运动一般是连续的,同时在短时间之内的变化相对比较小,在这种参考里,会使用运动矢量来表示参考块在上一帧以及当前帧的相对位置

为了找到参考块,就必须遍历参考帧中的每块图像块,找到残差块值最小的那块图像作为参考块,为了提高搜索参考块的效率,有钻石搜索算法、六边形搜索算法提高搜索效率,这些算法的基本原理还是利用了运动的局部性原理,就是在编码块的附近进行搜索,结果可能是局部最优,而非全局最优,但相比全搜索算法拥有很高的时间效率

钻石搜索算法

六边形搜索算法

由于图像块移动的便宜可能跟图像块大小匹配不上,所以需要通过插值的方式计算这种移动一半的图像,计算方式称之为亚像素插值,插值完成之后就可以继续进行运动搜索了

图像块的运动矢量并不是直接编码到视频流中,而是通过周围相邻块的运动矢量预测一个预测运动矢量,称为 MVP。将当前运动矢量与 MVP 的残差称之为 MVD,然后编码到码流中去,MVP+MVD 就是运动矢量

如果参考块与编码块直接没有移动,那就是一种帧间模式,称为 SKIP 模式,这种模式非常省码率,且压缩效率非常高

变换量化

分离图像块的高频和低频信息:DCT变换使得高频信息在量化的过程中能够比较容易被减少

去除掉大部分高频信息:量化,其实就是一个除法操作。通过除法操作就可以将幅值变小,而高频信息幅值比较小,就比较容易被量化成 0,起到压缩的目的

20230319144706

20230319144742

编解码器

编码标准 块大小和划份方式 帧内编码 帧间编码 变换 熵编码 滤波和后处理
H264 最大16x16,可划分成8X16、16X8、8X8、4X8、8X4、4X4 8个方向模式+planar+DC模式 中值MVP DCT 4X4/8X8 CAVLC、CABAC 去块滤波
H265 最大支持64x64,四叉树划分 33个方向模式+planar+DC模式 Merget模式,AMVP模式 DCT 4X4/8X8/16X16/32X32,DST 4X4 CABAC 去块滤波,SAO滤波
AV1 最大支持128x128,四叉树划分 56个方向模式+3个平滑模式+递归Filterlntra模式+色度CFL模式+调色板模式+帧内块拷贝模式 OBMC+扭曲运动补偿+高级复合预测+复合帧内预测 4x4-64x64正方形+1:2/2:1+1:4/4:1矩形DCT/ADST/flipADST/IDTX 多符号算术编码 去块滤波,CDEF,LR滤波,Frame超分,Film Grain

H264 和 H265 是需要专利费的,而 VP8 和 VP9 完全免费

在软件编码下的情况下,相同码率下,AV1 清晰度稍好于 H265,而 H264 最差,但是编码耗时则相反,AV1 最高,H265 次之,H264 速度最快

h264

如果范围内帧大部分都是相同的,那刷新第一帧图像后,从第二帧开始,我们只要刷新正中心字母区域的内容即可。这个叫局部更新

2022111202335

H264 编码标准中规定,IDR 帧之后的帧不能再参考 IDR 帧之前的帧

压缩后的视频码率也就变得比常规图像更高一些,这个码率的波动通常时高时低,具有可变性,我们一般称之为可变码率(VBR)

封装

容器格式:在容器格式的内部会同时存储音频、视频的数据

GOP

GOP(图像组):从一个 IDR 帧开始到下一个 IDR 帧的前一帧为止,这个间隔叫做关键帧间隔

20230315205104

GOP 太大,也会导致 IDR 帧距离太大,点播场景时进行视频的 seek 操作就会不方便

Slice

为了并行编码设计的,可以将一帧图像划分成几个 Slice,Slice 之间相互独立,就可以多线程并行对多个 Slice 进行编码

码流结构

Annexb格式:

使用起始码来表示一个编码数据的开始,一种是 4 字节的“00 00 00 01”,一种是 3 字节的“00 00 01”,为了避免编码的数据中有跟起始码一样,需要做一下替换

20230315205950

MP4 格式没有起始码,而是在图像编码数据的开始使用了 4 个字节作为长度标识

20230315210250

帧在码流中实际上是以 Slice 的形式呈现的,H264 的码流主要是由 SPS、PPS、I Slice、P Slice和B Slice 组成的

为了区分这几种数据,使用一个名为NALU的结构来封装数据

20230315210752

视频传输

RTP&RTCP

视频码流被打包成一个个 RTP 包进行发送,同时这个协议还能实现告知当前视频码流是哪种视频编码标准,按照什么速度播放视频等额外的信息

RTP包头部

宇段 占用位数 含义
V 2 RTP版本号。当前版本号必须是2
P 1 填充标志位。当为1时,表示在RTP包的最后面有若干个填充宇节。注意填充字节只用于字节对齐填充,不是视频数据
X 1 扩展标志位。当为1时,表示在RTP默认头部后面会有一个用于自定义的扩展头部
СС 4 CSRC个数。表示CSRC标识符个数。
M 1 Marker位。对于不同的有效载荷Marker位含义不同。对于视频,表示当前RTP包是一帧的最后一个包。
Payload Type 7 有效载荷类型。用于说明RTP报文中有效载荷的类型,比如说可以是H264、VP8等,用于接收端进行解析RTP的有效载荷
Sequence Number 16 序列号。用于表示当前RTP包的序号,每发送一个RTP包,序 列号加1。它是RTP包的标识。接收端可以使用它来告诉发送端RTP包丢失了,要求发送端重传。序列号的初始值是随机的
Timestamp 32 时间戳。时问戳反映了该RTP包所属视频帧的采样时间。接收 端使用时间戳来控制播放速度和音视频同步。使用90000Hz的时间基(就是说时间戳的单位是1/90000秒)
SSRC 32 同步信源。比如说当前RTP用于传输H264视频数据和OPUS音频数据。H264的RTP包使用同一个SSRC,OPUS的RTP包使用同一个SSRC。接收端根据SSRC标识符来区分当前RTP包是H264RTP包还是OPUSRTP包
CSRCs 每一个占用32位,数量由CC指定 提供信源,可以有0~15个CSRC。每个CSRC标识了包含在RTP 包有效载荷中的所有提供信源。主要用在混合器中

RTCP则是用来辅助 RTP 协议使用的,RTCP 报文有很多种,分别负责不同的功能。常用的报文有发送端报告(SR)、接收端报告(RR)、RTP 反馈报告(RTPFB)等

H264 RTP 打包:

单 NALU 封包方式

组合封包方式

分片封包方式

使用不同打包方式取决于打包完成之后的RTP包是否超过1500字节,这个主要跟UDP的MTU有关

带宽预测

基于延迟预测

通过计算一组 RTP 包它们的发送时长和接收时长,来判断当前延时的变化趋势,并根据当前的延时变化趋势来调整更新预测的带宽值

计算延迟:

发送端与接受端分别记录包的发送时间与接受时间,来计算出前后两组包之间的发送时长和接收时长,接受端再通过Transport-CC 报文把统计信息发送给发送端

为了过滤掉噪声,引入一个叫做 Trendline Filter 的滤波器,它保存了 20 个最近的延时数据,通过线性回归的方式平滑掉延迟,避免偶发的噪声导致尖刺得到一个延迟趋势k

网络状态判断:

将延时趋势 k 乘以一个固定增益 4 和包组的数量(包组数量最大是 60)作为当前的修改后延时值。将当前的修改后延时值跟延时阈值进行比较,然后根据比较的结果来判断网络状态(过载、正常、欠载)

带宽调整更新:

通过一个状态机,有三个状态,分别是上升、保持和下降状态。当处于上升状态时,速率控制器需要提升带宽值;当处于下降状态时,需要降低带宽值;当处于保持状态时,则不更新带宽值,如果之前状态机处于下降状态,则更改为保持状态;如果状态机之前处于保持状态,则更改为上升状态;如果是上升状态那就不用变化,基本原理就是要不断逼近极限

基于丢包预测

根据 Transport-CC 报文反馈的信息计算丢包率,然后再根据丢包率的多少直接进行带宽调整更新

在网络变差的时候,预估带宽会快速的被下调,但是网络变好的时候预估带宽会比较缓慢的上升,这点跟TCP的慢启动原理是一样的

最大带宽探测

在程序刚开始启动的时候使用并在程序运行的过程中进行周期性的探测,基本原理是通过发送探测包与Transport-CC包记录发送时长得到发送端与接受端的最大带宽取最小值

码控算法

用算法来控制编码器输出码流的大小,码控就是为每一帧编码图像选择一个合适的 QP 值的过程

VBR

画面复杂码率就高点,简单码率就低点,比较适合视频点播和短视频场景

CQP

从头到尾每一个画面都是用同一个 QP 值去编码

CRF

画面运动大的时候,它会根据具体算法提高 QP 值;在画面运动小的时候,它会降低 QP 值

CBR

需要设置一个目标码率值给编码器。编码器在编码的时候不管图像画面复杂或简单、运动多或运动少的时候,都尽量使得输出的码率接近设置的目标码率,这种算法适合RTC场景下的视频传输

SVC

指一个码流当中,将数据包分为多层,低层数据包质量较低,高层的数据包解码要依赖低层的数据包,这样针对不同的网络状况,就可以自适应解码不同质量的视频

时域SVC:

通过调整参考帧结构就能实现分层编码。低层的帧不会参考高层的帧,质量低的表现就是帧率低

层0是I帧不需要参考,层1是P帧,参考层0

空域SVC:在一个码流当中分出多个码流出来,第 0 层是一个可以独立解码的码流,只是分辨率是 360P。第 1 层依赖于第 0 层,两个层次加起来是 720P 分辨率的码流...绝大多数的解码器都不支持空域 SVC

卡顿与花屏

卡顿可能的原因:

花屏可能的原因:

20230321205606

20230321205626

封装

将一帧帧视频和音频数据按照对应封装的标准有组织地存放在一个文件里面,并且再存放一些额外的基础信息,比如说分辨率、采样率等信息

FLV

FLV 的总体结构

各部分具体内容

播放的速度还有音视频同步都需要依赖时间戳的值,这个时间戳的单位是 ms。而 RTP 的时间戳单位是 1/90000 秒

有三种类型的 Tag Data 数据:

MP4

视频的一帧和音频的一段编码数据称为一个 sample。连续的几个 sample 称之为 chunk,而视频的所有 sample 称为一个视频 track,同样音频的所有 sample 也称为一个音频 track

MP4 主要由最外层的三个 box组成,分别是 File Type box(ftyp box)、Movie box(moov box)和 Media Data box(mdat box),moov box 里面存放了音视频的基本信息和每一个音视频数据的具体位置

整体结构

音画同步

PTS 表示的是视频帧的显示时间,DTS 表示的是视频帧的解码时间。对于同一帧来说,DTS 和 PTS 可能是不一样的,主要是因为 B 帧可以同时参考前后的帧造成的

20230326133222

视频同步到音频

这种方式最常用。

音频是指音频按照自己的节奏播放,不需要调节。如果视频相对音频快了的话,就延长当前播放视频帧的时间,以此来减慢视频帧的播放速度。如果视频相对音频慢了的话,就加快视频帧的播放速度,甚至通过丢帧的方式来快速赶上音频

音频同步到视频

视频按照自己的节奏播放,主要是调节音频的速度,但由于音频调整会导致音调变化,这点人耳是很敏感的,所以不太会使用

音频和视频都做调整同步

音频快了就将音频的速度调低一些或者将视频的速度调高一些,视频快了就将视频的速度调低一些或者将音频的速度调高一些。这种一般在非 RTC 场景不怎么使用