SVT-AV1学习--compute_subpel_params函数

一 compute_subpel_params函数说明

compute_subpel_params 函数在SVT-AV1源码中扮演着关键角色,用于计算呀像素精度运动补偿所需的参数。以下是该函数的详细作用说明。

函数参数说明

SequenceControlSet scs;指向序列控制集的指针,包含视频序列的编码参数和配置信息。

int16_t pre_y,int16_t pre_x 表示预测块在参考帧中的位置坐标。

MV mv 运动矢量,表示当前块相对于参考块的位移

const struct ScaleFactors const sf;//缩放因子结构体指针,用于处理不同分辨率下的缩放

uint16_t frame_width, uint16_t frame_height 当前帧的宽度和高度。

uint8_t blk_width, uint8_t blk_height;//当前处理块的宽度和高度。

MacroBlock av1xd 指向宏块解码结构体的指针,包含宏块相关的解码信息。

constu int32_t ss_y, const uint32_t ss_x; 垂直和水平方向的子采样因子。

SubpelParams subpel_params;输出参数,用于存储计算得到的亚像素参数

int32_t pos_y, int32_t pos_x;输出参数,用于存储计算得到的呀像素位置坐标。

函数作用

1 亚像素精度运动补偿,在视频编码中,运动估计通常在整像素级别进行,但是为了获得更高的编码效率,需要进行呀像素精度的运动补偿,该函数通过计算亚像素参数,使得运动补偿能够在亚像素级别进行,从而提高编码质量。

2 计算亚像素位置 根据输入的运动矢量和块的位置,计算出亚像素级别的位置坐标。这些坐标将用于后续的运动补偿过程。

3 确定插值滤波参数 亚像素运动补偿需要使用插值滤波器来生成亚像素位置的像素值。该函数计算出插值滤波器所需的参数,如滤波器系数和偏移量。

4 处理块边界条件 考虑块边界可能超出参数帧边界的情况,函数需要处理这些边界条件,确保运动补偿的正确性。

函数流程

1 初始化参数:根据输入的运动矢量和块位置,初始化相关的计算参数

2 计算亚像素位置:根据运动矢量和块位置,计算出亚像素几倍的位置坐标

3 确定插值滤波器参数 根据亚像素位置,确定插值滤波器的系数和偏移量。

4 处理边界条件 检查块边界是否超出参考帧边界,并进行相应的处理

5 输出结果 将计算得到的亚像素参数和位置坐标存储到输出参数中。

总结 compute_subpel_params 函数在视频变啊吗中扮演着重要角色,通过计算呀像素精度的运动补偿参数,提高了编码效率和视频质量。该函数的实现涉及到运动矢量处理,插值滤波器参数计算以及边界条件处理等多方面。

二 函数注释

static void computer_subpel_params(SequenceControlSet *scs, int16_t pre_y, int16_t pre_x, Mv mv, const struct ScaleFactors *const sf, uint16_t frame_width, uint16_t frame_height, uint8_t blk_width, uint8_t blk_height, MacroBlockD *av1xd, const uint32_t ss_y, const uint32_t ss_x, SubpelParams *subpel_params, int32_t *pos_y, int32_t *pos_x)

{//检查是否需要进行缩放处理

const int32_t is_scaled = av1_is_scaled(sf);

//如果需要缩放处理

if (is_scaled) {

// 计算原始位置的y坐标,考虑运动矢量的影响

int orig_pos_y = (pre_y + 0) << SUBPEL_BITS;

orig_pos_y += mv.row * (1 << (1 - ss_y));

//计算原始位置的x坐标,考虑运动矢量的影响

int orig_pos_x = (pre_x + 0) << SUBPEL_BITS;

orig_pos_x += mv.col * (1<<(1 - ss_x));//参考缩放因子ss_x运动矢量影响

//使用缩放因子原始坐标转换缩放坐标(垂直方向)

*pos_y = sf->scale_value_y(orig_pos_y, sf);

//使用缩放因子原石坐标转换缩放坐标(水平方向)

*pos_x = sf->scale_value_x(orig_pos_x, sf);

//添加额外偏移量(用于缩放过程中的误差)

*pos_x += SCALE_EXTRA_OFF;

*pos_y += SCALE_EXTRA_OFF;

//计算边界限制(用于防止内存访问越界

//border_in_pixels 边界像素大小基于大小额外边距

const int border_in_pixels = scs->super_blokc_size * 2 + 32;

//计算顶部边界(考虑缩放因子 ss_y 和插值扩展)

const int top = - (((border_in_pixels >> ss_y) - INTERPOLATION_OFFSET) << SCALE_SUBPEL_BITS);

//计算左侧边界(考虑缩放因子ss_x 和插值扩展)

const int left =- ((border_in_pixels >. s_x) - INTERPOLATION_OFFSET) << SCALE_SUBPEL_BITS;

//计算地步边界(基于帧高度和插值扩展

const int bottom = ((frame_height >> s_y) + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;

//计算右侧边界(基于帧宽度和插值扩展)

const int right = ((frame_width >> ss_x) + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;

//将缩放后的坐标限制在允许范围内(垂直方向)

*pos_y = clamp(*pos_y, top, bottom);

//将缩放后的坐标限制在允许的范围内(水平方向)

*pos_x = clamp(*pos_x, left, right);

//提取呀像素偏移(水平方向)

subpel_params->subpel_x = *pos_x & SCALE_SUBPEL_MASK;

//提取亚像素偏移(垂直方向)

subpel_params->subpel_y = *pos_y & SCALE_SUBPEL_MASK;

//设置水平方向缩放步长

subpel_params->xs = sf->x_step_q4;

//设置垂直方向缩放步长

subpel_params->ys = sf->y_step_q4;

//缩放坐标转换整数精度(垂直方向)

*pos_y = *pos_y >> SCALE_SUBPEL_BITS;

//缩放坐标转换整数精度(水平方向)

*pos_x = *pos_x >> SCALE_SUBPEL_BITS;

else {

//如果不需要缩放直接裁剪运动矢量

MV mv_q4;

//裁剪运动矢量确保允许范围内

mv_q4 = clamp_mv_to_umv_border_sb(av1xd, &mv, blk_width, blk_height,ss_x, ss_y);

//提取亚像素偏移(水平方向)

subpel_params->subpel_x = (m4_q4.col & SUBPEL_MASK) << SCALE_EXTRA_BITS;

//设置呀像素偏移 (垂直方向)

subpel_params->subpel_y = (mv_q4.row & SUBPEL_MASK) << SCALE_EXTRA_BITS;

//设置水平方向的补偿(默认值)

subpel_params->xs = SCALE_SUBPEL_SHIFTS;

//设置垂直方向的步长(默认值)

subpel_params->ys = SCALE_SUBPEL_SHIFT;

//计算整数精度的坐标(垂直方向)

*pos_y = pre_y = (mv_q4.row >> SUBPEL_BITS);

//计算整数精度的坐标(水平方向)

*pos_x = pre_x = (mv_q4.col >> SUBPEL_BITS);

}

}

}

1 缩放相关逻辑

is_scaled代码计算缩放后坐标确保这些坐标允许范围

使用scale_value_yscale_value_x函数原石坐标转换缩放坐标

添加SCALE_EXTRA_OFF偏移量为了补偿缩放过程中误差

2 边界限制

clamp 函数用于确保坐标不会超出允许范围避免内存访问越界

border_in_pixels 边界像素大小基于超级快大小额外

3 缩放逻辑

is_scaledfalse直接裁剪运动矢量提取像素偏移

使用默认步长(SCALE_SUBPEL_SHIFTS)

4 像素偏移

subpel_xsubpel_y存储亚像素偏移用于后续插值操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值