i_deblocking_filter_alphac0 和 i_deblocking_filter_beta的应用
-
功能:在 x264 环路滤波中,
i_deblocking_filter_alphac0
和 i_deblocking_filter_beta
是环路滤波模块中两个重要的参数,它们用于控制去块滤波器(deblocking filter)的行为条件。这些参数通常在编码器的配置中进行设置,并对最终编码视频的质量有显著影响。
- 应用流程:
- 从原理流程可以看到,
i_deblocking_filter_alphac0
和 i_deblocking_filter_beta
作为是否进行滤波的阈值,以及修改不同边界像素比如 p0
、p1
、p2
、q0
、q1
、q2
的阈值条件,满足不同条件就进行相应的像素调整。
-
第一步:默认值设置,在
x264_param_default
函数中完成;
-
第二步:根据视频特点或需求调整二者的值,在
param_apply_tune
函数中完成;
-
第三步:初始化 header 中去块相关变量,主要将
i_deblocking_filter_alphac0
和 i_deblocking_filter_beta
转换成i_alpha_c0_offset
、i_beta_offset
,二倍的关系,在slice_header_init
函数中完成;
-
第四步:将
i_alpha_c0_offset
、i_beta_offset
二者写入码流中,供解码识别,在slice_header_write
函数中完成;
-
第五步:将
i_alpha_c0_offset
、i_beta_offset
转换成 a
、b
局部变量,根据不同条件应用到具体的滤波函数中,在x264_frame_deblock_row
函数中完成;rdo
模块中x264_macroblock_deblock
函数有类似的操作。
-
第六步:根据不同的分量、滤波强度、滤波方向指向具体的滤波运算函数,比如亮度分量普通滤波通过
deblock_edge_luma_c
函数实现,亮度分量强滤波通过deblock_edge_luma_intra_c
函数实现。
-
第七步:通过调整,修改需要滤波的重建像素值,完成滤波操作。
- 具体如下图说明:
相关函数说明
-
x264_param_default
- 设置 x264_param_t 结构体中的所有编码参数到默认值。这个函数非常重要,必须被调用,因为它为编码过程提供了一套合理的起点。这些参数包括但不限于分辨率、帧率、编码模式(如恒定量化参数CQP、平均比特率ABR等)、去块滤波参数、宏块树率控制(MB-tree)、量化矩阵等。
-
param_apply_tune
- 用于调整编码参数以适应特定的视频内容或优化视觉质量。这个函数可以根据指定的调整值(tune value)对编码参数进行优化,例如针对电影、动画、含噪点的视频、静态图片等不同类型的视频内容进行专门的参数调整。这些调整值可以是 film、animation、grain、stillimage、psnr、ssim、fastdecode、zerolatency 和 touhou 等,其中 film、animation、grain、stillimage、psnr 和 ssim 是视觉优化调整值,而 fastdecode、zerolatency 是编码速度优化调整值。param_apply_tune 函数可以同时使用多个调整值,如果它们之间不冲突的话。
- 在实际使用中,
param_apply_tune
函数通常在设置了编码器的默认参数之后被调用,以进一步细化和优化编码设置。例如,在初始化编码器参数结构体 x264_param_t 并设置了预设(preset)之后,可以通过调用 param_apply_tune
来应用特定的调整值,从而根据视频内容调整编码参数,以达到更好的编码效率和质量
-
slice_header_init
- 在 x264 编码器中用于初始化切片头(Slice Header)的数据结构。在 H.264/AVC 视频编码标准中,切片头是每个切片的元数据部分,它包含了解码当前切片所需的重要信息。
-
slice_header_write
- 将 H.264 视频编码中的切片头(Slice Header)信息写入到比特流(bitstream)中。在 H.264 视频编码标准中,每个切片的开始都有一个切片头,它携带了解码当前切片所需的必要信息。
-
x264_frame_deblock_row
- 用于对视频帧中的行(row)进行去块滤波处理(deblocking)。去块滤波是视频编码中常用的一种技术,用于减少宏块(macroblock)边界处的视觉不连续性,即所谓的块效应(block artifacts),这些效应通常在压缩率较高的视频编码中出现。
-
deblock_edge
- 用于普通滤波,也就是当边界强度(BS)为 1、2 或 3 时的滤波情况。这个函数会根据宏块的量化参数(QP)、alpha 表值和 beta 表值计算滤波的门限值,然后根据这些值和 BS 值决定是否进行滤波以及滤波的强度。
- deblock_edge_luma_c
- 关于滤波强度 Bs=1、2、3 的滤波运算相关函数的具体实现,主要是亮度分量的滤波运算,色度分量相似操作。
-
deblock_edge_intra
- 用于强滤波,即当边界强度 Bs 为 4 时的情况。这种滤波通常用于帧内编码的宏块(Intra macroblock)或者当宏块的边界被认为是强真实边界时。与
deblock_edge
相比,deblock_edge_intra
会使用更强的滤波器参数,以减少视觉上的不连续性。
- deblock_edge_luma_intra_c
- 关于滤波强度 Bs=4的滤波运算相关函数的具体实现,主要是亮度分量的滤波运算,色度分量相似操作。
相关去块滤波数据表
static const uint8_t i_alpha_table[52+12*3] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 4, 4, 5, 6,
7, 8, 9, 10, 12, 13, 15, 17, 20, 22,
25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
80, 90,101,113,127,144,162,182,203,226,
255,255,
255,255,255,255,255,255,255,255,255,255,255,255,
};
static const uint8_t i_beta_table[52+12*3] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 2, 2, 3,
3, 3, 3, 4, 4, 4, 6, 6, 7, 7,
8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
};
static const int8_t i_tc0_table[52+12*3][4] =
{
{-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
{-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
{-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
{-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
{-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
{-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
{-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 1 },
{-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 1, 1 }, {-1, 0, 1, 1 }, {-1, 1, 1, 1 },
{-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 },
{-1, 1, 1, 2 }, {-1, 1, 2, 3 }, {-1, 1, 2, 3 }, {-1, 2, 2, 3 }, {-1, 2, 2, 4 }, {-1, 2, 3, 4 },
{-1, 2, 3, 4 }, {-1, 3, 3, 5 }, {-1, 3, 4, 6 }, {-1, 3, 4, 6 }, {-1, 4, 5, 7 }, {-1, 4, 5, 8 },
{-1, 4, 6, 9 }, {-1, 5, 7,10 }, {-1, 6, 8,11 }, {-1, 6, 8,13 }, {-1, 7,10,14 }, {-1, 8,11,16 },
{-1, 9,12,18 }, {-1,10,13,20 }, {-1,11,15,23 }, {-1,13,17,25 },
{-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
{-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
};
#define alpha_table(x) i_alpha_table[(x)+24]
#define beta_table(x) i_beta_table[(x)+24]
#define tc0_table(x) i_tc0_table[(x)+24]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46