1.视频压缩概述

近几年来是由4k分辨率到8k分辨率过渡的时期,hdmi2.1协议规定了frl模式,使带宽从原来的tmds下的18G提升到48G(12G4l),但是对于超高分辨率如4k144 yuv444 12bit或者8k60,48G的带宽依旧可能不够用。原有的物理传输层不足以满足如此之高的带宽需求。将视频进行高效的压缩以减少数据传输所需要的带宽是一种可行的方式。dsc压缩算法是其中一种,本文详细介绍其算法原理。
影像压缩传输(Display Stream Compression)简称DSC,是将影像数据压缩后进行传输,达成低带宽就可输出高分辨率内容,并且经压缩后画面表现上视觉无失真、低延迟的技术。
在介绍hdmi的DSC之前,先简略介绍DSC的运作原理。一个完整的DSC系统需要一个编码器及译码器。编码器配置在传送端,传输影像数据前将影像压缩; 译码器则配置在接收端,将接收到的影像数据解压缩、还原并显示。由此可知,传送端及接收端两者都必须要支持DSC方可启用。

2.dsc压缩算法的c model的使用

本文不想一上来就长篇大论介绍一堆dsc压缩算法的原理,笔者查阅了很多dsc相关的资料,dsc协议是英文的,国内的一些文献仅仅是简单翻译了一下,一堆比较难懂的概念,不是工作压力,项目驱动,没有具体的例子和环境跑起来,很难对算法进行深入的研究。这里先演示下由官方给出的开源c model 是如何跑起来的。
c model文件如下图所示:
在这里插入图片描述
除代码实现的.c和.h文件外,还有makefile文件,cfg文件,list文件,输入文件
makefile就是用来编译生成可执行文件的,dsc是生成的可执行文件。
cfg文件是配置文件,内容如下:
在这里插入图片描述
dsc模型的输入文件是dpx图像文件,可以用jpg转dpx转换。list文件指定输入文件,内容如下:
在这里插入图片描述
找了一张dpx格式的图像文件,用dpx文件查看工具看下图像内容
在这里插入图片描述
这里我们把cfg中的func字段配成1,只编码
在这里插入图片描述
执行完后,在当前目录下生成.ref文件和.dsc文件
在这里插入图片描述
可以看到,经过dsc算法压缩后的图像文件,大小约为原来的二分之一。符合预期,dsc算法硬件实现后在IP上运行,带宽约为原来的一半,hactive是原来的一半。
.dsc文件无法查看,在IP上强行把这些数据送显,图像内容基本看不出来,需要解码,此时我们把func字段配成2,list文件名改成dsc文件,只解码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到,生成了一个.out的文件,格式为dpx,我们用dpx图像工具看下内容。

在这里插入图片描述
可以看出,解码后的文件对比原文件,视觉上看不出差异,dsc是视觉无损的算法,传输时的带宽约降低了一半。

3.dsc算法流程和c model代码分析

有了上面的c model正常运行,我们就可以进一步的对算法的流程进行研究了,配合dsc协议和相关的论文来阅读代码,图像处理无非是输入->算法处理->输出,可以在代码中添加一些打印,打印一些关键参数,这样便于我们去理解代码的算法流程。

在介绍算法流程之前,先科普一些基本概念
在这里插入图片描述
如上图所示,图片层就是一帧图像,为加速编码的过程,并且减少经过压缩的失真,DSC技术导入截面(Slice),将每一帧的画面加以切割,切割出的截面同时进行编码。就是上图看到的slice。
dsc算法处理的基本单位就是slice,那么,在硬件实现的时候,我们就可以就把硬件设计成多个slice并行的了以加快编解码的速度。一个slice由多个组(group)组成,一个组包含3到4个pixel(像素),一个像素一般由3个component组成,component有depth的概念,是8bit编码还是10bit编码即R,G,B或者Y,U,V。一个组(group)包含3个unit。
第2节示例中的输入文件是一个520*520的文件,cfg文件中配置的slice的高是108在这里插入图片描述
宽cfg文件没有配,那么,在dsc处理的时候,分成了几个slice进行处理的呢?
答案是 (a + b - 1) / b,a表示输入文件的高,b表示slice的高,这个公式表示a/b向上取整,即
高度方向上分的slice是 (520 + 108 - 1) / 108 = 5,宽我们没有分,所以分成了5个slice。运行过程加了些log,可以看确实是5个slice
在这里插入图片描述
代码中也是这么算的
在这里插入图片描述
下面分步骤介绍算法流程
算法主要分一下几个步骤
色彩空间转换
预测和量化
比特流重构
速率控制
平坦度检测和速率控制研究不深,不详细展开,可以自行研究c model。

3.1.初始化及色彩空间转换

在这里插入图片描述
这里首先做rgb到yuv的转换,因为大部分图像算法主要是针对yuv格式的。
rgb转yuv相关文献给出公式,代码实现如下:
在这里插入图片描述
理解没什么难度,不再赘述

在这里插入图片描述
接着是做一些dsc变量初始化的工作,申请了currline和prevline,用于预测算法当中,dsc算法是对slice逐行进行编码。
在这里插入图片描述
这里编码过程的这个函数,是把slice第一行的数据放到data的yuv当中,yuv是3个数组,对于y,u,v分量。第一行因为没有上一行做参考,处理会特殊一点。
在这里插入图片描述
上图是这个函数的具体实现。剪剪支其实不复杂,yidx这里函数调用的时候就是0,循环中是不变的,i在变,一行逐pixel把三个通道的yuv放到原始数组origline中。

3.2 预测和量化

接着代码是一段大循环,逐行编码
在这里插入图片描述
这里是预测和量化的函数
在这里插入图片描述
循环执行了3次,对y,u,v3个通道的数据进行预测,不考虑yuv420,走下面的if分支得到一个预测值pred_x。SamplePredict如下:
在这里插入图片描述
对照下面这张图和公式看
在这里插入图片描述
被预测像素与重构值之前的位置关系如图所示。在当前被预测组(P0、P1 和 P2)周围的样本值(g、c、b、d、e、f 和 a)被用作 MMAP 预测处理。
在使用 MMAP 公式预测像素之前,需要将当前组像素用到的前一行像素值进行量化参数自适应滤波。对上一行的 c、b、d、e 分别应用水平低通滤波,滤波系数为[0.25 0.5 0.25],滤波后产生的滤波像素为 filtC、filtB、filtD、filtE。滤波像素 filtB 的计算过程如下所示:
在这里插入图片描述
经过滤波处理后的像素和原始像素混合,产生用于 MMAP 的值,这些值分别为 blendC、blendB、blendD 和 blendE。滤波值和原始像素值混合处理的公式可
以表示为:
在这里插入图片描述
在这里插入图片描述
经过上述处理过程之后,就可以通过 MMAP 得到组内三个像素的预测值。
MMAP 的预测过程如下所示:
在这里插入图片描述
可以参考相关文献对照代码,不难理解。
接下来是计算几种方式的残差,并存到数组中,以便解码的时候使用
在这里插入图片描述
可以参考下面文件所述与代码对照
在这里插入图片描述

在这里插入图片描述

3.3 平坦度检测和速率控制

(1)平坦度检测。平坦度检测单元通过简单的像素处理来判定当前图像内容的平坦度,从 而 标 志从非平坦区到平坦区的过渡,以减少量化失真。平坦度检测还承担着部分速率控制的任务,为速率控制部分的 QP值调整提供决策依据。为了在编码前完成对像素组的平坦度检测,输入像素需经过一个小容量的缓存,目的是产生一个对编码操作的短暂超前。当一个进入组是平坦的,速率控制就会减小 QP值以最佳化平坦区域的主观质量,并在比特流中发出这个平坦度状态指示。
(2)速率控制 。DSC通过调节 QP值进行速率控制,管理速率缓存的充盈度,保证速率缓存既不上溢,也不下溢,将熵编码产生的每组可变的比特数变为固定的比特数发送到显示链路上。DSC通过调节量化水平来优化主观图像质量,在复杂区域用较大的 QP值,在平坦区域使用较小的 QP值编 码。速 率控制中,DSC采用简单的2的整数幂 量 化 方 法,可随内容自适应地为每个像素组更新 QP。QP值 可 简单地由缓存充盈度和内容活动性程度导出,以避免复杂的率失真运算。编码器和解码器的速率控制单元使用同样的速率缓存模型和速率控制操作,只是编码器的速率控制模块多一个平坦度检测输入。这一措施使得DSC避免花费比特 去编 码 QP的 变 化,保证速率控制在 QP频繁变化时并不影响编码效率。
对应代码如下:
在这里插入图片描述
在这里插入图片描述

3.4 输出编码文件

在这里插入图片描述
这里是在填充数据,填充完后再把图像格式转换回去,再释放内存空间。
在这里插入图片描述
最后在主函数中生成结果文件。
在这里插入图片描述

4.hdmi下dsc开发

to do 主要介绍hdmi2.1协议中的cvtem包和emp包格式, pps参数等。

更多推荐