deblock 原理详解

一 deblock缘由

摄像时背景是雪白的墙,结果解码时问题出现了。

问题现象:
        解码的图像在墙壁部分有很明显的方块,其它图像变化大的地方(如人脸部分)情况还好。

问题分析:
        以前没有这种情况的呀。改变了的只有编码速率。原来为了兼顾网络状况,我们将码率降得比较低。码率小,量化的精度就低,宏块与宏块之间的量化误差变大。当颜色变化很平缓时,这种很小的误差就变得明显了,图像上的体现就是宏块边界出现明显的颜色跳变,也就是方块。

问题解决:
        还好mpeg4标准考虑到了这个现象,他们提供了一种叫deblock的解码后处理方法来弱化这种现象。实际将deblock添加后图像确实平滑许多,方块也没了。


deblock原理:
     大概做法就是将每个点与它上下10个点和左右10个点的颜色平均。具体做法是将图像按8*8划分成块,按块的边界做平均。 如下图所示。

                         |                             |
                         |                             |
         块1          |   块2                    |            v0
  v0 v1 v2 v3 v4|v5 v6 v7 v8 v9      |             v1
                         |                             |            v2
                         |                             |            v3
                         |                             |            v4
 ----------------------------------------------------------------
                        |                              |            v5
                        |                              |            v6
                        |                              |            v7
           块3       |        块4                |            v8
                        |                              |            v9
                        |                              |
                        |                              |
 -----------------------------------------------------------------

      每次计算取10个点,首先判断10个点的差别,如果差别很小就用默认模式将v4 v5做个细小的修正,如果差别很大则用DC offset模式修正v1-v8共8个点的值。判别的算法是:
     eq_cnt =  y(v0-v1) + y(v1-v2) + y(v2-v3) + y(v4-v5) + y(v5-v6)
  + y(v6-v7) + y(v7-v8)
 其中if(x<= THR1) y(x) =0  else  y(x) = 1;    //THR1 是一个经验值 1

    if(eq_cnt < THR2)           //THR1 是一个经验值 6
        default mode
    else
        DC offset mode

DC offset模式的规则:
     
    max = MAX(v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]);   
    min = MIN(v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]);
    if((max - min) < 2* quant)
     颜色平均
    else
        什么也不做

按 1,1,2,2,4,2,2,1,1 的权重平均颜色。比如

s[1] = (uint8_t)((6*p0 +(v[1]<<2)+(v[2]<<1)+(v[3]<<1)+v[4]+v[5]+8)>>4);   
s[2] = (uint8_t)(((p0<<2)+(v[1]<<1)+(v[2]<<2)+(v[3]<<1)+(v[4]<<1)+v[5]+v[6]+8)>>4);
s[3] = (uint8_t)(((p0<<1)+(v[1]<<1)+(v[2]<<1)+(v[3]<<2)+(v[4]<<1)+(v[5]<<1)+v[6]+v[7]+8)>>4);

    类似的计算出s[1]-s[8],然后回写到v[1]-v[8]的位置。

 

计算量分析:
    统计可以知道绝大部分使用了DC offset模式。如果图像尺寸是352*288,只分析亮度分量的计算量。
8*8块竖向分界线有352/8-1 = 43 条 ,每条分界线上有288个点,也就是竖向deblock要做43*288=12384个平均操作。
横向向分界线有288/8-1 = 35 条 ,每条分界线上有352个点,也就是竖向deblock要做35*352=12320个平均操作。
每个平均操作需要执行:
    (1)从内存中读取10个byte, 竖向时10个byte是连续的,横向时每个byte相隔一行的宽度
    (2)计算eq_cnt
    (3)从v[1]-v[8]中找出最大的最小的值
    (4)计算s[1]-s[8]
    (5)将s[1]-s[8]存到v[1]-v[8]

    另外,由于这些操作会修改图像的值,而如果图像是I或P帧,它还要作为后继帧的参考帧,图像数据不能变,所以需要将它拷贝到临时区中处理,这个拷贝也极耗时间。


    天啦,每帧deblock将会大约读两遍帧数据和写一遍帧数据,将比yuv->rgb更恐怖的耗时间。实际的情况真是
令人沮丧,原本优化到32fbs了,加上deblock后直接降到16fbs。


优化分析:
    (1)读取和写入内存会占大部分时间,不过这部分没什么好优化的。
    (2)计算eq_cnt,这部分计算量很小,也不必在意
    (3)从v[1]-v[8]中找出最大的最小的值

max = MAX(s[1],MAX(s[2],MAX(s[3],MAX(s[4],MAX(s[5],MAX(s[6],MAX(s[7],s[8])))))));
min = MIN(s[1],MIN(s[2],MIN(s[3],MIN(s[4],MIN(s[5],MIN(s[6],MIN(s[7],s[8])))))));

xvid给了两种方法计算MAX和MIN

#define MIN(X, Y) ((X)<(Y)?(X):(Y))
#define MAX(X, Y) ((X)>(Y)?(X):(Y))
#define FAST_MAX(x,y) ((x) - ((((x) - (y))>>(32 - 1)) & ((x) - (y))))
#define FAST_MIN(x,y) ((x) + ((((y) - (x))>>(32 - 1)) & ((y) - (x))))
第二种方法耗4条指令。
如果用汇编则只需3条指令 

   mov r1,r2    //    r1 = max(r2,r3)
   cmp r3,r1
   movgt r1,r3

     (4)计算s[1]-s[8],公式中有一些重复的计算,可以先计算重复部分后整体代换。


      这些优化的都是耗时不太大的部分,真正耗时的是内存的存取部分。可以根据图像质量的状况适当减小计算的点数。标准中每次平均计算都取10点写8点,实际可以读8点写6点。

二 其他描述

一、x264的deblock小FAQ:
1、第一个值(Alpha deblocking)是去块范围,越大,去块越厉害,细节越少,视频也越模糊。一般来说默认值0就够了,不要超出+-2的范围;
2、第二个值(Beta deblocking)是去块阈值,越小,保留越多细节;越大,去块越猛,可以越好得去除明显的块效应;把这个值弄高点有利于去除各种错误;
3、总之,值越大画面越flat(1:2),值越小画面细节越多(-2:-1);
4、一些建议值
Low- 0:3
Medium- 1:-1
High- 0:-3

 

二、deblock顾名思义就是去除色块的?
第一个值决定总体使用程度(包括一旦要决定deblocking处理的话,处理的强度);第二个值为阈值设定,即某一处该不该做deblocking处理。(具体做不做deblocking、强度如何应该还会受其他影响,见下文)

当然这只是大致的说明

deblock如果强度过大的话,会使画面有一定的柔化/模糊效果(但这远远比不上用诸如AVS滤镜来搞柔化处理),所以反过来看也许就像是负值在做锐化一样,但是不是deblock造成了字体锐化过度造成模糊就不清楚了(不知道你所说的模糊到底是什么情况,至少截个png吧,一般锐化过度是会造成ringing啊这样的现象;不过总觉得deblock负值应该不能算锐化处理……)

另外,x264的deblock是自适应的(Adaptive),也就是说如果给的码率很足(比如crf 14,其他码率控制相关参数为默认),deblock这个参数不管怎么设(包括开不开)都很难看出画面区别的;当码率较低(比如crf 27,其余同上),deblock的作用会增大,不同deblock参数区别也容易用眼睛看出来

就我看到的,deblock对压缩画面效果影响最大的是线条部分(嗯字体边缘确实也是能算到这里的)

此外,deblock至少还跟cqm和psy是有一定关系的

 

三、deblock作用是减少编码过程中产生的block,不会消除片源的block

qp越低,deblock的作用也就越弱,低到一定程度就不会启用
deblock强度开的越高,block越少但画面越平滑

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译好的x265,带y4m文件 Syntax: x265 [options] infile [-o] outfile infile can be YUV or Y4M outfile is raw HEVC bitstream Executable Options: -h/--help Show this help text and exit -V/--version Show version info and exit Output Options: -o/--output Bitstream output file name --log-level Logging level: none error warning info debug full. Default info --no-progress Disable CLI progress reports --[no-]cu-stats Enable logging stats about distribution of cu across all modes. Default disabled Input Options: --input Raw YUV or Y4M input file name. `-` for stdin --fps Source frame rate (float or num/denom), auto-detected if Y4M --input-res WxH Source picture size [w x h], auto-detected if Y4M -f/--frames Maximum number of frames to encode. Default all --seek First frame to encode Quality reporting metrics: --[no-]ssim Enable reporting SSIM metric scores. Default disabled --[no-]psnr Enable reporting PSNR metric scores. Default disabled Profile, Level, Tier: --profile Enforce an encode profile: main, main10, mainstillpicture --level-idc Force a minumum required decoder level (as '5.0' or '50') --[no-]high-tier If a decoder level is specified, this modifier selects High tier of that level Threading, performance: --threads Number of threads for thread pool (0: detect CPU core count, default) -F/--frame-threads Number of concurrently encoded frames. 0: auto-determined by core count --[no-]wpp Enable Wavefront Parallel Processing. Default enabled --[no-]pmode Parallel mode analysis. Default disabled --[no-]pme Parallel motion estimation. De
去块滤波(Deblock)是视频编码中的一种技术,用于减少压缩后图像的块状伪影和边界伪影。在VVC编码标准中,去块滤波是以CU(Coding Unit)为单元进行的。具体的去块滤波过程如下: 1. 首先,通过设置边界是否可用去块滤波,确定需要进行滤波的边界。这些边界包括内部子块边界、左侧边界和上侧边界。 2. 然后,遍历CU中的全部子TU(Transform Unit),设置子TU的垂直和水平边界,并根据边界长度确定需要进行滤波的像素数。 3. 接下来,遍历CU中的全部子PU(Prediction Unit),进行类似的边界设置过程。 4. 针对每个需要进行滤波的边界,先对边界进行排序,然后调用相应的滤波函数进行滤波。滤波过程包括对亮度分量和色度分量的滤波。 总的来说,去块滤波通过对CU、TU和PU进行边界设置,并调用相应的滤波函数对边界进行滤波,以减少压缩后图像的块状伪影和边界伪影。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [H.266/VVC技术学习之环路滤波:去块滤波(Deblock)技术](https://blog.csdn.net/BigDream123/article/details/115016745)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [H.266/VVC代码学习:去块滤波Deblock代码一](https://blog.csdn.net/BigDream123/article/details/115974424)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值