一.前言
本来打算先分析HEVC SCC里面的IBC相关源代码实现的,鉴于手机看代码实在不方便,比如想查看函数调用关系时,没法直接跳转。所以还是先把HEVC SCC里面的屏幕内容编码工具原理部分都写完,等周末在电脑上再分析代码吧。
二.palette总体介绍
据观察,和自然场景内容相比,在屏幕内容视频帧里面,除了会含有大量重复字符以外,它的每个CU块里面像素点的颜色种类数也是比较少的。所以,在HEVC SCC里面可以考虑引入palette工具编码屏幕内容。
那什么是palette?
palette,一般会翻译为调色板,其实在HEVC视频编码里面,翻译成主色调会更贴切一些。
HEVC SCC里面palette指的是,把每个编码单元CU里面像素点的颜色值和索引组成的表。
palette模式也不是什么新鲜事物,其实在PNG和Tif里面,已经用了很多年了。
HEVC SCC又把它重新拿过来,基于屏幕内容里面颜色种类数少的特性,和现在的混合编码框架组合在一起,来提高屏幕内容的压缩性能。
但palette概念和思想拿过来以后,具体如何设计palette模式的编码算法,以及便于软硬件实现倒是一个难点。
在HEVC SCC标准里面,palette模式支持在CU级编码。为其建立像素点颜色的lookup table,表里面存储颜色和对应的index。如下图所示:
上图index1表示的是(R,G,B)=(0,0,0)的纯黑颜色。
一旦CU的palette表构建好,那CU里面的所有samples可以将其分成两类,一类是indexed samples,一类是escape samples。
前者表示的是,CU里面这个像素点的颜色可以用palette表里面的颜色index来表示,只要它和palette表里的颜色值相似即可。
那如何衡量两个颜色是不是相似呢,编码器端通常会使用失真SAD或者SSE,加阈值的方式来判断。
如果CU里面有些像素点的颜色,判断下来确实跟已有palette表里面的颜色差异很大,那就把它分到escape samples类里面。而这一类的像素点需要进行量化编码。
上面那个图中下部分就是对3x3块里面像素点,使用palette表(大小为4,索引为0-3)进行分类的结果。
在得到了CU的palette表以后,接下来就是对其进行编码得到码流。编码包括两部分,palette表的编码和CU中每个像素索引的编码。
HEVC SCC里面palette编码从输入一个CU块原始像素点值到熵编码得到码流的过程,如下图所示:
因为在CU级会有个flag来决定是否使用palette模式。如上图所示,如果对CU使能palette编码模式,则首先会选择CU里面像素点的主要颜色形成一个palette表,然后根据CU里面像素点颜色值和palette表,映射得到palette index。
接着palette的index会将CU里面的像素(颜色值)划分为两类,如上图major colors and escape colors(上图中index 4就是)。
最后,对于颜色在palette表里面的像素点,我们只要熵编码index到码流就行了。而颜色不在palette表里面的,需要进行量化后熵编码。
上图中的Copy-left和Copy-Above是采用预测编码方式,来提升palette index编码性能。
具体HEVC SCC是如何构建CU的palette表?以及如何对palette表进行编码呢?
鉴于上次把IBC的原理放到一篇里面介绍,内容有点太多,辛辛苦苦写了好几天,结果实际阅读效果并不是太好。所以palette编码原理打算细分来说。
三.总结一下
所谓的视频压缩编码,实际就是对数字像素点的各个颜色分量值(不管是RGB还是YUV)进行一通处理,最后将其变成以比特流表示的码流数据。而解码器会根据标准预先定义好的码流格式,读取比特流最后还原处数字像素点的颜色分量值。
既然这样,那我如果发现当前帧里面像素点的颜色种类比较少,那我就可以直接给这些颜色种类建一个索引表。告诉解码器哪个像素点对应哪个颜色索引以及索引表,那它就可以以此来还原出像素点值。
既可省去原先的那一通处理,且可能这样只编码颜色索引,比编码颜色像素残差还节省比特数。这大概就是palette编码的原理吧。
而HEVC SCC里面palette编码的核心思想是,用出现频率较高的几种颜色,来表示当前CU里的像素点值,从而可以跳过传统的变换,量化编码过程,同时通过编码颜色的index来达到压缩屏幕内容的目的。但请注意有一个前提,那就是像素点颜色种类比较少。