③如果c>a且c==b或者c==a且c> b,则将像素c划分为种类3。
④如果c>a且c>b,则将像素c划分为种类4。
⑤如果不属于以上4种情况,则将像素c划分为种类0。
像素所处的种类 决定了像素的补偿值匹配。种类1和种类2的补偿值大于等于0,种类3和种类4的补偿值小于等于0。对于边界补偿来讲,只需要传送补偿值的绝对值,解码器根据像素补偿种类即可判断出它的符号。
2.2 边带补偿(BO)
边界补偿根据重构后的像素值进行分类,总共分成32类 也就是32个边带。 比如说8bit,其像素值范围为0-255。每个边带有8个像素。同一个边带范围内的像素使用相同的补偿值。 一般情况下,在一定的图像区域内,像素值的波动范围很小,一个CTB中的大多数像素属于少数几个边带。H.265/HEVC 标准规定一个CTB只能选择4条连续的边带,并只对属于这4个边带的像素进行补偿。 选择哪4条边带可以通过率失真优化方法确定,然后将最小边带号以及4个补偿值传至解码端。
2.3 参数融合
参数融合 也就是对于一个CTB块,其sao参数使用的是相邻的sao参数,编码时只需要传递 使用了哪个sao即可。如下C为当前块,AB为邻近块,C可以使用A或者B块的sao参数。
三、 sao相关的语法元素
(1) sao_merge_left_flag。
该语法元素代表当前CTU块的SAO参数信息是否与左侧相邻块进行了融合,取值为0或1。
当等于1时,表示当前CTU块的SAO信息,即语法元素sao _type_ idx_luma, sao_ type_idx_chroma, sao_band_position, sao_eo_class_luma, sao_eo_class_chroma, sao_offset_abs 以及sao_offset_sign的值是根据左侧CTU块的相应语法元素得到的;
当该值等于0时,表示以上构成SAO信息的语法元素的值不是从左侧CTU得到的。其默认值为0。
(2) sao_merge_up_flag
跟上面的参数类似,但是这里是跟上面的元素merge。
(3) sao_type_idx_luma。
该语法元素代表亮度分量的补偿类型。
数组SaoTypeIdx[cIdx][rx][ry]表示色彩分量为cldx且位置为(rx,ry)处的CTB块的补偿类型.
该变量取值为0时,表示不补偿;
该变量取值为1时,表示边带补偿;
该变量取值为2时,表示边界补偿。
亮度分量的补偿类型,即数组SaoTypeIdx[0][rx][ry]的值由以下步骤得到。
如果sao_type_idx_luma 存在,则将其赋给SaoTypeIdx[0][rx][ry]。
否则,进行以下步骤。
若sao_merge_left_flag=1,则将SaoTypeIdx[0][rx- 1][ry] 的值赋给SaoTypeIdx[0][rx][ry]。
若sao_merge_ up_ flag=1, 则将SaoTypeIdx[0][rx][ry-1]的值赋给SaoTypeIdx[0][rx][ry]。
否则,将SaoTypeldx[0][rx][ry]设置为0。
(4) sao_type_ idx_chroma。
该语法元素代表色度分量的补偿类型。
色度分量的补偿类型,即数组SaoTypeIdx[cIdx][x][ry]的值(cIdx=1,2) 由以下步骤得到。
如果sao_ type_ idx_ chroma 存在,则将其赋给SaoTypeIdx[cIdx][x][ry]。
否则,进行以下步骤。
若sao_ merge_ left_ flag=1,则将SaoTypeIdx[0][rx - 1][ry]的值赋给SaoTypeIdx[cIdx][rx][ry]。
若sao_ merge_ up_ flag=1, 将SaoTypeIdx[0][rx][ry-1]的值赋给SaoTypeIdx[cIdx][rx][ry]。
否则,将SaoTypeIdx[cIdx][rx][ry]设置为0。
(5) sao_offset_ abs[cIdx][rx][ry][i].
该语法元素表示色彩分量为Idx,位置为(rx,ry)的 CTB,它的第i个种类的补偿值。
当其不存在时,通过以下步骤得到。
若sao_merge_ left_flag=1,将sao_ offtset_ abs[cIdx][rx- -1][ry][i]的值赋给sao_ offset _abs[cIdx][rx][ry][i]。
若sao_ merge_ up_ flag=1, 则将sao_ offset_ abs[cIdx][rx][ry-1][i]
的值赋给sao_ offset_ _abs[cIdx][rx][ry][i]。
否则,将其设为0。
(6)sao_ offset_ sign[cIdx][rx][ry][i]。
当SaoTypeIdx[cIdx][rx][ry]=1, 即边带补偿时,该值代表了色彩分量为Idx,位置为(rx,ry)的CTB,它的第i个补偿值的符号。
当该值不存在时 跟前面类似可以通过上面或者左边的值得到。
(7) sao_band_ position[cIdx][rx][ry]。
该语法元素代表了进行边带补偿的最小边带位置。当该值不存在时 跟前面类似可以通过上面或者左边的值得到。
(8) sao_eo_class_luma
该语法元素代表了亮度分量的边界补偿模式。
数组SaoEoClass[cIdx][rx][ry]表示了色彩分量为cIdx, 在位置(rx,ry)处的CTB的补偿类型。
SaoEoClass[0][rx][ry]通过以下步骤得到。如果sao_ eo_ _class_ luma 存在,则将其值赋给SaoEoClass[0][rx][ry]。
当该值不存在时 跟前面类似可以通过上面或者左边的同样的sao 参数值得到。
(9) sao_ eo_class_chroma。
该语法元素代表了色度分量的边界补偿模式。SaoEoClass[cIdx][rx][ry]的值(cIdx=1 ,2)通过以下步骤得到。
如果sao_ eo_ class_chroma 存在,则将其值赋给SaoEoClass[cIdx][rx][ry]。
当该值不存在时 跟前面类似可以通过上面或者左边的同样的sao 参数值得到。
sample_adaptive_offset_ enabled_ flag:
该语法元素标识是否采用SAO补偿技术。当该值取1时,表示使用;该值取0时,表示不使用。
loop filter_ across _tiles_enabled_flag: 该语法元素用于标识在tile 的边界处是否执行环路滤波操作,包括去方块滤波和像素自适应补偿。当取值为1时,表示执行;取值为0时,表示不执行。
pps_loop_filter_across_slices _enabled_flag: 该语法元素用于标识在Slice的左边界以及上边界处是否执行环路滤波操作。当取值为1时,表示执行;取值为0时,表示不执行。
slice_sao_ uma_ flag: 该语法元素标识当前Slice的亮度分量是否允许进行SAO操作。当取值为1时,表示允许进行SAO;取值为0时,表示不允许进行SAO。当该语法元素未出现时,默认其值为0。
slice_sao_ chroma flag: 该语法元素标识当前Slice的色度分量是否允许进行SAO操作。当取值为1时,表示允许进行SAO;取值为0时,表示不允许进行SAO。当该语法元素未出现时,默认其值为0。
slice_loop_filter_across_slices_enabled_ flag: 该语法元素标识当前Slice的左边界及上边界是否进行环路滤波操作,包括去方块滤波和像素自适应补偿。当取值为1时,表示可能进行(具体情况要根据后续条件判断);取值为0时,不进行环路滤波。当该语法元素未出现时,其值等于pps_loop_filter_across_slices_enabled_flag 的值。
四、总结
sao相对于deblock 模块来说相对简单。首先它是作用与重构后的图像 在 去块滤波之后,它处理的基本单位是ctu。sao实际可以分为 三种类型的补偿方式,具体采用哪种方式 编码器用的是率失真来进行选择率失真可以说是贯穿整个编码过程,许许多多的编码参数都是这个决定的。
sao如果是跟周围的像素进行比较来分类的话 就是边界补偿 根据比较像素的方向 可以有4种模式,而每种模式中 跟周边像素大小的不同又可以分为5种方式,而需要补偿的情况是其中的4种。
sao如果是用自身像素值的分类的话就是边带补偿,不同像素深度是8还是10比特,都是按照像素的范围固定的分为32个边带。
而在一个ctu内部只补偿4连续4个边带里面的像素,其他就不补偿了。
sao最后一种方式 有点类似于像素的帧内预测,用的是周边ctu的sao参数直接预测出当前ctu的sao参数。
总的来说 sao在编码端是要了解如何运用率失真来决策补偿模式,然后具体某个模式需要传输什么信息到解码端。而解码端呢,需要了解编码端传输过来的各种参数的意义。