0.引言
本文主要介绍一种帧内刷新算法,解决I帧太大带来的延迟问题,可以在调优时,值得借鉴。
帧内刷新技术避免 I 帧尖峰带来的带宽压力,可以有效地降低视频通信中的缓冲区延迟。帧内刷新算法是一种视频错误恢复的方法,通过对部分宏块或者整帧采用强制帧内编码的模式,从而断开连续的帧间预测,所以之后的视频帧不会再依赖之前的帧信息执行解码操作,达到替代关键帧实现错误恢复的目的。
1.帧内刷新介绍
帧内刷新方法主要有随机帧内刷新、自适应帧内刷新以及周期性帧内刷新技术。随机帧内刷新在 P 帧中随机选择一部分 CTU 块进行帧内编码,因为该算法对帧内刷新块的选择是随机的,所以效率较为低下,该方法虽然降低了编码效率,但是对错误恢复能力的增加却非常有限。自适应的帧内刷新技术主要是通过算法挑选感兴趣区域的 CTU 块进行强制帧内编码,虽然该方法可以取得不错的效果,但是现有的算法都比较复杂(如果能够有这种计算力,实际也是可以使用),不利于实时视频通信系统的实现。
周期性帧内刷新算法由于其简单性和实用性被许多优秀的开源编码器(如x264,x265等采用。在进行低延迟编码时,视频帧在 PIR 指定的刷新周期内被完全刷新,同样对于每一帧,都有固定的宏块进行帧内编码,从而获得比插入关键帧更平稳的比特率。在多媒体传输过程中,该方法并不使用关键帧来恢复传输中发生的错误,因此可以在提供低延迟特性的条件下又具备较好的容错性,相比随机帧内刷新更加有效。
周期性帧内刷新算法是通过将帧内编码的columns 按照顺序依次插入到每个P帧中来完成的。在该刷新方案中,首先根据给定的刷新周期大小 N 将整个帧划分成 N 个区域。在
后面的编码过程中,这些区域依次使用强制帧内编码模式进行编码。已经采用帧内编码的区域称为清洁区域(clean region),而正在进行帧内编码(下图中的 intra coded region)和尚未进行帧内编码的区域都属于脏区域(dirty region)。在编码模式的判决过程中,编码器首先需要判断待编码块是否位于需要采用帧内编码的区域,然后决定是否进行强制帧内编码。整个视频帧在一个刷新周期中可以被完全刷新,从而具备错误恢复的能力,可以有效地避免错误的传播。例如,如果第一帧的第二列发生错误,则在第二帧中,第二列将使用帧内编码模式进行编码,因此可以立即消除错误。周期性帧内刷新算法如下图:
但是只是采取上述刷新策略并不能完全恢复错误。在上图中,当第一帧的第二列发生错误时,第二帧中的第二列使用帧内编码模式进行编码可以消除错误。但是当第二帧第一列中边界附近的宏块参考了第一帧第二列的数据时,则该错误仍然会在随后的帧中传播。当视频的运动方向与帧内刷新方向相反时,这种情况会频繁发生。因此为了保护清洁区域,在 PIR 方法中,除了上述对 columns 进行依次刷新的操作之外,还需要对已刷新区域进行搜索范围的限制。也就是说,清洁区域不能参考脏区做运动估计,但是脏区可以使用先前帧的任何位置作为参考。帧内刷新方向如下图:
虽然 PIR 方法简单,适合实时通信的场景,但是该方法仍然存在一些不足之处,由于该方法对已刷新区域的搜索范围的限制,当视频运动方向与帧内刷新方向相反时,编码性能将显著降低。如上图中,视频的全局运动方向为从左向右,即左图中处于灰色区域的编码块正常的进行运动估计时应当参考脏区的编码块,但由于 PIR 保护清洁区域的策略,使得处于清洁区的块不能从脏区获得预测,而必须从清洁区获得参考块,这样会导致编码中用到的运动矢量和实际的运动矢量不一致甚至相反,从而导致编码性能的大幅度下降。针对这种问题,本文提出了一种基于 PIR 方法改进的运动自适应帧内刷新方法,该方案可以根据视频运动方向自适应地选择最佳刷新方向,可以有效地减少当视频运动方向和刷新方向不一致时所带来的率失真性能的下降。本文方案中的刷新周期的大小可以改变,并且不需要使用标准的 IP 编码模式来获得运动矢量信息,更加容易实现,同时这种方式能够显著地提升编码的率的失真性能。
2.运动自适应帧内刷新算法
当视频内容具有运动性,尤其是高速运动时,传统的 PIR 方法无法获得最优的编码性能。为了防止错误传播到清洁区域,当清洁区域的运动矢量(Motion Vector,MV)指向脏区域时,需要限制清洁区域的 MV,因此在这种情况下,清洁区域无法使用最优的 MV,如果运动矢量逆向的情况频繁发生,就会导致视频编码性能的大幅下降。为了尽可能的避免这种情况发生,本文介绍一种运动自适应的帧内刷新算法如下图:
首先,随着近些年来视频技术的发展,高清、超高清和 4K 及以上分辨率的视频应用日益增多,因此对大分辨率视频来说,视频帧的不同区域可能具有不同的运动矢量,在本文的刷新方案中视频帧被横向划分为四个矩形条带(band),就像上图所示,同时根据预先设定的刷新周期大小值 M,将每个 band 划分为 M个区域(上图中M=4)。在编码过程中,每个 band 独立地根据该 band的平均运动矢量信息计算两种刷新方向带来的运动矢量逆向成本(cost),完成 cost 的计算后,各个 band 可以根据本周期的计算信息自适应地选择成本较低的刷新策略(从左到右或从右到左),并将选取的刷新策略应用于下一个刷新周期中。
3.运动矢量逆向成本
从下图中可以看出该 band 的平均运动矢量为(x,y)=(3,0),示例中的刷新策略是从左向右。如上文所述,当清洁区域的 MV 指向脏区域时,其用于运动估计的 MV 将会受到限制,也可以理解为边界保护,也就导致编码性能的下降。在这种情况下,本文将性能的下降对应为产生的运动矢量逆向的成本,改进的算法需要选择具有最小成本的策略作为每个 band 的刷新方向。
在下图中,对于 Frame 1,Region 1 采用帧内编码,因此 cost 为 0。对于 Frame 2,Region 1 属于清洁区域,其 MV 指向脏区域(Region 2)。所以有必要防止 Region 1 从 Region 2 获得参考信息,因此需要限制这个 MV,此时产生的 cost 为 3。对于Frame 3,Region 1 属于清洁区域,但是其 MV 指向清洁区域(Region 2),Region 1 产生的 cost 为 0,同时 Region 2 属于清洁区域,其 MV 指向脏区域(Region 3),Region 2 产生的 cost 为 3。而 Frame 4 中,只有 Region 3 会产生值为 3 的 cost,其他几个区域的 cost 均为 0。如表 3-1 所示,在一个刷新周期中,该示例中所有帧的累计 cost 为 9。容易验证,对此示例来说,最佳的帧内刷新方向是从右向左,这种刷新方式产生的累计 cost 为 0,可以避免率失真性能的下降。成本估算示例如下图所示。所有区域的平均运动矢量(x,y)=(3,0),刷新方向是从左向右。
有些算法做法就是,在使用运动自适应的帧内刷新编码之前,首先需要对相同视频采用标准 IPPP 编码得到运动矢量信息,然后才能根据得到的信息来决定合适的刷新策略。但是,这种方法显然无法用于实际的低延迟视频场景。本文介绍的方法是,在前一个刷新周期的运动矢量信息会被统计用于成本估算,根据成本计算的结果可以决定出下一刷新周期的刷新策略,这种方法是简单而有效的。一个帧内刷新周期累计产生的cost 需要统计该周期中各帧、各区域的 MV 信息,如第 n 帧中的第 m(在本文中m=1,2,3,4)个 band 的 cost 函数定义如下:
Region i 和 Region j 是 band m 中的相邻区域,如果 Region i 属于清洁区域而Region j 是脏区域,并且 Region i 的运动矢量指向 Region j,其中MV xi是 Region i 的水平分量则产生的 cost 为:
对于其它情况:
运动矢量逆向成本可以用来衡量编码效率的成本。因为运动矢量越大,也就意味着视频的运动更为剧烈,所以在上一个帧内刷新周期内某区域发生运动矢量逆向,如果该区域的 MV 越大,则在新的帧内刷新周期中就越容易发生运动矢量逆向的情况,而且逆向发生时与原物体的距离越远。
基于此,通过计算并累计一个刷新周期内所有帧产生的 cost,就可以获得一个刷新周期内的总的运动矢量逆向成本,具体公式如下:
由于视频数据在内容上具有时间上的连续性,因此可以将当前刷新周期的运动矢量逆向成本作为下一个刷新周期的运动矢量逆向成本的估计。在具体编码时,通过上面公式分别计算两个刷新策略(从左到右,从右到左)的 cost,然后在下一个刷新周期中为各个 band 选择 cost 较小的刷新方向。运动自适应帧内刷新算法步骤如下:
(1)将视频帧划分为 4个band 并进行编码,统计各个 band 的运动矢量信息。
(2)分别计算两种刷新策略的 cost
本轮刷新未完成,跳到步骤(1)。
Region i 为清洁区域,Region j 为脏区, Region i 的 MV 指向 Region j:
否则
别计算本周期内两种刷新方向的累计 cost:
(3)确定下一刷新周期的刷新策略。
分别为各个 b and 选取 cost 最小的刷新方向作为下一周期的刷新策略。
四个 b and 方向一致,跳转到步骤1。
(4)检验竖直方向
选择具有最大 cost 的 band 作为基准区域。相邻区域(未曾比较的)的刷新方向与基准区域不一致,同时满足:
则改变相邻区域刷新方向,同时将该区域记为已比较。
所有区域均已比较,跳转到步骤(1)中。
将相邻区域设置为基准区域,跳转到上面的计算公式:
当每个 band 的刷新方向相同时,可以直接进入下一个刷新周期进行编码。但是,如果两个相邻 band 的刷新方向不一致时,则意味着这两个 band 不能互相参考,可能在竖直方向也出现运动矢量逆向的情况。因此,当方向不一致时,有必要考察两个相邻 band 的相关性,以便为下一周期选择最佳的刷新方向。
当两个相邻 band 刷新方向不一致时,本文采用如下策略确定两个 band 的最终刷新方向:
(1)选择成本较高的 band 作为基准。这是因为当成本较大时,更改刷新方向会导致编码性能下降的更多,因此需要尽可能保持成本大的 band 不改变刷新方向。
(2)需要计算两个相邻 band 的平均运动矢量,以确定非基准 band 的刷新方向是否需要改变。假设 band i 和 band j 是具有不同刷新方向的两个相邻 band,同时 band i 是基准,如果它们的 MV 信息满足以下公式中的条件,band j 的刷新方向则需要调整同 band i 一致:
其中MVyi 是 band i 指向 band j 的竖直分量,MVyj 是 band j 指向 band i 的竖直分量,MVxj 是 band j 的水平分量,本文所提的运动自适应帧内刷新算法的具体描述如上表所示。
4.首帧处理策略
本文的方案使用的是适用于低延迟场景的编码结构,即编码过程中只有第一帧是 I 帧,后续均为 P 帧。由于第一帧中的所有 CTU 块都是采用帧内编码模式,因此第一帧的码率要比后续的 P 帧高很多。当第一帧通过固定速率信道时,传输时间将会更长,导致更大的视频延迟,在互联网场景下带来的延迟更为明显,会导致更大的延迟和网络抖动。为了减少视频传输延迟,第一帧(I 帧)的比特率必须降低。所以本文对第一个 I 帧做了如下处理。
在开启码控模式对 I 帧进行编码时,可以通过减少给 I 帧分配的比特数来减少I 帧的数据量,从而避免 I 帧过高的码率,减少缓冲区延迟。同时不可避免的是,I 帧比特数的降低会导致第一帧图像质量的下降,因此在视频开始时,视频质量较低。但是在实时通信的场景中,第一帧的质量下降是可以接受的。更重要的是,采用帧内编码的 columns 会陆续嵌入到后续的 P 帧中,从而可以在一个刷新周期内慢慢恢复视频的质量。
本文采用 PSNR以及 SSIM 作为评价指标。实验平台为 HM16.14,编码的配置采用 HM 提供的 low delay P 编码结构,该配置文件编码出的视频码流只有一个 I 帧,是适用于低延迟视频应用的。CTU 的划分使用默认的配置文件,CTU 大小为 64x64,最大可划分深度为 4。
5.缓冲区充盈度分析
保持缓冲区不发生上溢和下溢的能力是衡量低延迟效果的关键指标之一。如果缓冲区累积的数据量过大,则编码器必须跳过一些帧才能减少缓冲区延迟并防止发生缓冲区溢出的情况。相反,如果编码器输出比特率低于网络带宽,则会发生缓冲区下溢并导致带宽浪费。为了适应传输信道的要求,实际场景要求视频码率的波动比较小。对相同的 P 帧而言,帧比特的抖动越小,码流也就越平稳,越能适应较小的编码缓冲区。对于恒定码率编码模式来说,只需要对一个 GOP 或者一段时间内编码器输出的码流进行控制,保持一段时间内的码率平稳,而在低延迟场景下,对于 IPPP 的编码结构,需要连续的几个 P 帧的比特数接近,不产生较大的震荡,才能够适应对延迟比较苛刻的实时通信场景。下面公式中描述了编码缓冲区大小与延迟和码率之间的关系:
其中DelayT 是实时视频码流的延迟时间,TargetR 是编码的目标码率。为了考察两种方法的低延迟效果,DelayT 在实验中设定为两帧,例如,对于帧率为 25FPS 的视频来说,两帧的延迟为 80ms。
PIR 方法和本章所提算法实际编码的效果如下图所示,需要说明的是,PIR方法的导致的性能损失主要是由于边界块(在图中用红色方框标记)的运动估计搜索范围是被限制的。传统方法帧内刷新的刷新方向是从左到右,此时,运动矢量逆向的情况频繁发生,边界块较多的采用帧内编码模式,导致编码性能有较大损失。第一个 band 的刷新方向与 PIR 方法一致,也是从左向右,而后三个 band 的刷新方向是从右向左。可以看出,所提方案避免了频繁帧内编码的情况,因此与 PIR 方法相比具有更好的效果,可以获得性能的提升。
6.总结
该方案通过统计编码数据的运动矢量信息,通过计算一个周期内不同刷新方向的运动矢量逆向成本,从而决定出下一刷新周期最合适的刷新策略,根据视频运动方向自适应地选择最优刷新策略。相同水平的低延迟效果的情况下,可以获得更优的率失真性能,尽可能的避免了运动矢量逆向情况的出现,对于运动显著的序列可以获得更高的率失真增益。本文方案算法的时间复杂度与周期性帧内刷新方法相当,额外增加的成本估算部分对整体编码时间的影响较小。欢迎关注,收藏,转发,分享。
后期关于项目知识,也会更新在微信公众号“记录世界 from antonio”,欢迎关注