H265 SAO 技术

from: http://blog.sina.com.cn/s/blog_4ae178ba0101814r.html

SAO : Sample adaptive offset

这是目前H265中比较热门的技术,根据以前的测试,SAO性价比远远超过Deblock和ALF.

 

paper: Sample Adaptive Offset for HEVC

                           1.  SAO在流程中的位置和历史:

    H265 SAO 技术_第1张图片

从流程中可以看到,SAO和ALF是loop内的操作,接在Deblocking filter的后面,输入包括原始的YUV图像和Deblocking的输出,最后产生部分需要参数需要entropy进行编码。ALF是类似的。

    H265 SAO 技术_第2张图片
Decoder端:

  H265 SAO 技术_第3张图片


SAO原始的思想来自于Samsung的提案JCTVC-A124。可以参考这个文档获得详细的信息。在三星的提案中提出了比较复杂的BDC(Band - correction, 位于ALF和DPB之间)和EXC(extreme-value correction,位于Deblocking he ALF之间,也就是现在SAO的位置),BDC和EXC都是对pixel进行分类,然后为每一个分类分配一个offset值。这个offset就是在 entropy中要编码的参数。不同的是,BDC使用的是pixel的intensity(Luma值)来对pixel进行分类;而EXC使用的模板中心 pixel和neibor pixel之间的梯度来进行的分类(edge特性).

 

使用经过BDC/EXC处理后的参考帧,能够取得更好的压缩率,但是因为BDC/EXC太复杂,因此没有被H265采用。

但是基于BDC/EXC提出的SAO(JCTVC-BO77/C147/D122/E049)最后被采用了。

 

在原始的提案中SAO分为LUMA SAO和CHROMA SAO(JCTVC-F056)。

 

SAO的offset包含BO(Band offset)和EO(Edge offset)。

 

SAO采用了不同于BDC/EXC的pixel分类的方法,降低了复杂度。

 

                       2. SAO算法提出的理论基础

 

在对SAO算法分析之前,需要对三星的BDC/EXC的算法进行了解,参考JCTVC-A124文档。

第一次提出了几个概念:

 CU : Coding Unit,可以是16x16,32x32,64x64,128x128。然而,CU 的size可以不是固定的,而是可以变化的,在SPS中定义了LCU/SCU来限制CU size的变化范围。(必须是正方形)

  sps->log2_min_coding_block_size_minus3   (SCU)
  sps->log2_diff_max_min_coding_block_size (LCU)

 

可以把一个picture划分成LCU的集合,在每一个LCU中再进行CU的划分(CU hierarchy Depth). Hierarchy 的层次决定了可以出现的CU的size的数目: 比如

   LCU = 128X128, MAX_hierarchy_depth = 5

那么CU可以出现的size只有5种,为:

   128x128(LCU), 64x64, 32x32 , 16x16, 8x8(SCU)

 

 

在一个LCU中可以包含INTER CU和INTRA CU,因此CU才是等同于MB。 LCU只是一个概念上的值,在编码上还是以CU为单位。

 

 PU:  Prediction Unit,是prediction时使用的size,包括intra prediction/inter prediciton类似于H264中的partition。

TU:  transform Unit, DCT transform时使用的unit,比如DCT4X4/8X8/16X16/32X32/64X64,可以包含一个或者多个PU。更大的DCT size有利用处理超分辨率的图像。

 

其实在H264的时候,也有这些概念,只不过

  CU -> MB

  PU -> PARTITION

  TU -> DCT4X4/8X8

在H265中提供了更大的size的选择。这也是为了支持超分辨率的图像的原因。

 

                3. H265 draft SAO 算法

通过PSNR的计算公式可以看到,重构数据和原始YUV之间的差的平方和是决定PSNR的因素。SAO通过分析deblocking后的数据和原始YUV之间的关系来对deblock后的数据进行delta操作,使得尽量接近原始YUV,达到提高PSNR的目的。

一个最基本的想法就是把deblock的重构数据和原始YUV中每一个相同位置的pixel做差值,把这个差值传给decoder,这样可以完全恢复原始 YUV.但是这实际上是不现实的,如果每一个pixel都传输一个offset,这会导致码率会非常的高,达不到压缩的效果。(如同DPCM)

H265在码率和PSNR之间做了一个tradeoff,以较小的码率增加来提高PSNR。下面就看H265是怎么做的。

 

H265是基于CTB来做SAO。通过分析deblock重构pixel和原始输入YUV之间的关系将pixel分成了三种SAO模式:

     H265 SAO 技术_第4张图片 

如上表中可以看到,可以不做SAO/Band offset/edge offset 三个mode。

EdgeOffset mode:

在这种模式下,SAO首先需要为该CTB选择使用哪一种梯度模式,水平/垂直/45度/135度。这是用sao_eo_class来表示。

         H265 SAO 技术_第5张图片 

当为某个CTB选择使用了上面某种梯度模式后,开始计算该CTB中的当前sample P和相邻2个pixel之间的关系,用edgeIdx表示:

    H265 SAO 技术_第6张图片 

因为edgeIdx的计算是针对deblocking以后的重构图像进行的,encoder和decoder使用相同的方法来计算,因此不需要传输这个信息给decoder,而是可以由decoder自己来计算,这样虽然增加了计算量,但是可以降低码率。

对于edgeIdx 为0的flat area,可以不需要做任何操作。对于1~4,SAO为每一个edgeIdx分配了一个offset,这个offset会add到重构像素中。因为SAO不是为每一个pixel分配一个offset,而是先把pixel进行梯度的计算,并且做edgeIdx的分类,对每一个edgeIdx类分配一个offset(对每一个CTB有4个offset就足够),这样可以减少码率的消耗。另外,为了进一步降低码率,H265 SAO规定对于edgeIdx=1,2这两种情况下,offset值必须是正数;对于edgeIdx=3,4时,offset必须是负数。通过这种强行的要求,符号位可以不进行编码。

 

Bandoff Mode:

SAO encoder把有效的YUV取值范围(0-255 fullRange, 16-235 BT601/709) 平均分为32个band(如下图,如果是0-255,就是每一个band的范围是8,一共分成32个band),通过某些算法来选择其中连续的4个band进行补偿,当CTB中的sample的Luma/Chroma处于这4个选定的band中时,需要对这个sample进行补偿(把该band相关的offset值加到sample的值上)。

                  H265 SAO 技术_第7张图片 

encoder端如何选择4个band:

从上面这个图中可以看到这个原理:在encoder端会统计当前CTB中的sample的Luma/chroma值,做32band的直方图统计,每一个band中包含的该YUV中的sample求均值,下面举个例子:

比如假设有一个band是31-38,假设该CTB中有3个pixel的值在这个band中,分别为:

               32

               34

               36

这样可以知道原始YUV该CTB中的sample出现在这个band中的均值为(32+34+36)/3= 34;

对deblock后的重构图像同样做这样的处理,也求出该band中的均值,假设为32.

那么可见,deblocking后的重构YUV和原始YUV在该CTB上,并且该band上有均值上的差值为34-32=+2. SAO因此可以分配band offset=+2 到这个band上,在decoder端,为每一个处于该band上的deblocking后的sample值加上2,这样可以保证在该band上出现的重构pixel和原始YUV上的该CTB的该band上的均值是相等的。

 

对32个band都做这样的处理,最后选择连续4个,offset值最大的band作为最终确定的需要补偿的band。并且起始band值和4个band offset值写到码流中传输给decoder。 通过这种band offset的方式,可以把均值差别最大的4个band补偿成均值相等,来拉近原始YUV和重构图像之间的差值。

 

一个问题:为什么band offset 模式中只是选择4个连续的band?

标准给出的答案是:

1. 在flat area部分,大部分的pixel的取值应该会集中在很少的几个band中,因此使用连续的4个band能够覆盖大部分的pixel。(也就是说如果对flat area的某一个CTB做直方图的话,这个pixel会很集中在很少的几个取值点,因此使用4个连续band可以很好的覆盖.

2. 因为edge offset模式使用了4个offset值,为了不增加码率,band offset也复用了这4个offset值的syntax,这样不需要另外再增加syntax来专门表示band offset。

 

 

 

附录上H265语法来表示上面的信息:

    H265 SAO 技术_第8张图片 

从上面的语法中可以看到,对于edgeoffset模式,提供sao_eo_class_luma/chroma的值来选择使用什么模式的梯度。并且为1-5这4种edgeIdx提供了offset值,一共4个offset。没有符号位提供。

对于band offset 模式,提供了sao_band_position来表示4个连续band的起始band是哪一个。并且为这4个band分别提供了band offset值,并且提供了符号位。

 

另外,如果当前CTB的SAO参数和左边或者上面的CTB的SAO参数相同,那么也就不需要为当前CTB再传输SAO参数了,而是直接使用左边CTB或者TOP CTB中的SAO参数即可。这样可以进一步降低码率。这就是sao_merge_left_flag/sao_merge_up_flag的作用。需要注意的是因为H265引入了TILE/SLICE结构,而tile是并行处理的,另外也不能跨SLICE,因此当前CTB只有和left/TOP CTB处于同一个tile/SLICE时才能共享SAO参数。

 

 

总结: SAO是一在deblocking后的一个后处理步骤,会影响到inter prediction的参考帧值。SAO是对重构像素进行了PSNR提升的一个重要步骤,直接对luma/chroma值进行非线性操作。H265 SAO做的tradeoff就是首先对CTB中的pixel进行分类,再对每一个类别分别进行处理,这样避免了对每一个pixel直接进行处理带来的高码率的代价,从而转换成了对分类后的类进行的处理,而分类的类别的数目是比较少的,对于band offset和edge offset都是4个类别。因此只是需要提供4个offset值就足够。

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