Commit 15836145 authored by Debargha Mukherjee's avatar Debargha Mukherjee

Changed scaling of MVs to use higher precision.

This is intended to be a no-op when scaling is not
enabled, but is expected to result in more accurate
prediction when references need to be scaled.

However note all xs, yx, subpel_x and subpel_y values
are now at higher than 1/16th precision.

Change-Id: I4b22573ea290a31fc58ead980bb0d5e5a9e89243
parent 65b80fd3
......@@ -604,8 +604,6 @@ typedef enum {
} RestorationType;
#endif // CONFIG_LOOP_RESTORATION
#define SCALE_DENOMINATOR 16
#if CONFIG_FRAME_SUPERRES
#define SUPERRES_SCALE_BITS 3
#define SUPERRES_SCALE_NUMERATOR_MIN 8
......
......@@ -827,11 +827,12 @@ void av1_highbd_build_inter_predictor(
const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
is_q4 ? src_mv->col : src_mv->col * 2 };
MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
const int subpel_x = mv.col & SUBPEL_MASK;
const int subpel_y = mv.row & SUBPEL_MASK;
const int subpel_x = mv.col & SCALE_SUBPEL_MASK;
const int subpel_y = mv.row & SCALE_SUBPEL_MASK;
ConvolveParams conv_params = get_conv_params(ref, ref, plane);
src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);
src += (mv.row >> SCALE_SUBPEL_BITS) * src_stride +
(mv.col >> SCALE_SUBPEL_BITS);
av1_make_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
sf, w, h, &conv_params, interp_filter,
......@@ -864,10 +865,11 @@ void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
is_q4 ? src_mv->col : src_mv->col * 2 };
MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
const int subpel_x = mv.col & SUBPEL_MASK;
const int subpel_y = mv.row & SUBPEL_MASK;
const int subpel_x = mv.col & SCALE_SUBPEL_MASK;
const int subpel_y = mv.row & SCALE_SUBPEL_MASK;
src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);
src += (mv.row >> SCALE_SUBPEL_BITS) * src_stride +
(mv.col >> SCALE_SUBPEL_BITS);
av1_make_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
sf, w, h, conv_params, interp_filter,
......@@ -1038,27 +1040,28 @@ void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd, int plane,
int pos_y = sf->scale_value_y(orig_pos_y, sf);
int pos_x = sf->scale_value_x(orig_pos_x, sf);
const int top = -((AOM_INTERP_EXTEND + bh) << SUBPEL_BITS);
const int top = -((AOM_INTERP_EXTEND + bh) << SCALE_SUBPEL_BITS);
const int bottom = (pre_buf->height + AOM_INTERP_EXTEND)
<< SUBPEL_BITS;
const int left = -((AOM_INTERP_EXTEND + bw) << SUBPEL_BITS);
<< SCALE_SUBPEL_BITS;
const int left = -((AOM_INTERP_EXTEND + bw) << SCALE_SUBPEL_BITS);
const int right = (pre_buf->width + AOM_INTERP_EXTEND)
<< SUBPEL_BITS;
<< SCALE_SUBPEL_BITS;
pos_y = clamp(pos_y, top, bottom);
pos_x = clamp(pos_x, left, right);
pre = pre_buf->buf0 + (pos_y >> SUBPEL_BITS) * pre_buf->stride +
(pos_x >> SUBPEL_BITS);
subpel_x = pos_x & SUBPEL_MASK;
subpel_y = pos_y & SUBPEL_MASK;
pre = pre_buf->buf0 +
(pos_y >> SCALE_SUBPEL_BITS) * pre_buf->stride +
(pos_x >> SCALE_SUBPEL_BITS);
subpel_x = pos_x & SCALE_SUBPEL_MASK;
subpel_y = pos_y & SCALE_SUBPEL_MASK;
xs = sf->x_step_q4;
ys = sf->y_step_q4;
} else {
const MV mv_q4 = clamp_mv_to_umv_border_sb(
xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
xs = ys = SCALE_DENOMINATOR;
subpel_x = mv_q4.col & SUBPEL_MASK;
subpel_y = mv_q4.row & SUBPEL_MASK;
xs = ys = SCALE_SUBPEL_SHIFTS;
subpel_x = (mv_q4.col & SUBPEL_MASK) << SCALE_EXTRA_BITS;
subpel_y = (mv_q4.row & SUBPEL_MASK) << SCALE_EXTRA_BITS;
pre = pre_buf->buf +
(y + (mv_q4.row >> SUBPEL_BITS)) * pre_buf->stride +
(x + (mv_q4.col >> SUBPEL_BITS));
......@@ -1160,26 +1163,31 @@ void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd, int plane,
// Clamp against the reference frame borders, with enough extension
// that we don't force the reference block to be partially onscreen.
const int top = -((AOM_INTERP_EXTEND + bh) << SUBPEL_BITS);
const int bottom = (pre_buf->height + AOM_INTERP_EXTEND) << SUBPEL_BITS;
const int left = -((AOM_INTERP_EXTEND + bw) << SUBPEL_BITS);
const int right = (pre_buf->width + AOM_INTERP_EXTEND) << SUBPEL_BITS;
const int top = -((AOM_INTERP_EXTEND + bh) << SCALE_SUBPEL_BITS);
const int bottom = (pre_buf->height + AOM_INTERP_EXTEND)
<< SCALE_SUBPEL_BITS;
const int left = -((AOM_INTERP_EXTEND + bw) << SCALE_SUBPEL_BITS);
const int right = (pre_buf->width + AOM_INTERP_EXTEND)
<< SCALE_SUBPEL_BITS;
pos_y = clamp(pos_y, top, bottom);
pos_x = clamp(pos_x, left, right);
pre[ref] = pre_buf->buf0 + (pos_y >> SUBPEL_BITS) * pre_buf->stride +
(pos_x >> SUBPEL_BITS);
subpel_params[ref].subpel_x = pos_x & SUBPEL_MASK;
subpel_params[ref].subpel_y = pos_y & SUBPEL_MASK;
pre[ref] = pre_buf->buf0 +
(pos_y >> SCALE_SUBPEL_BITS) * pre_buf->stride +
(pos_x >> SCALE_SUBPEL_BITS);
subpel_params[ref].subpel_x = pos_x & SCALE_SUBPEL_MASK;
subpel_params[ref].subpel_y = pos_y & SCALE_SUBPEL_MASK;
subpel_params[ref].xs = sf->x_step_q4;
subpel_params[ref].ys = sf->y_step_q4;
} else {
const MV mv_q4 = clamp_mv_to_umv_border_sb(
xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
subpel_params[ref].subpel_x = mv_q4.col & SUBPEL_MASK;
subpel_params[ref].subpel_y = mv_q4.row & SUBPEL_MASK;
subpel_params[ref].xs = SCALE_DENOMINATOR;
subpel_params[ref].ys = SCALE_DENOMINATOR;
subpel_params[ref].subpel_x = (mv_q4.col & SUBPEL_MASK)
<< SCALE_EXTRA_BITS;
subpel_params[ref].subpel_y = (mv_q4.row & SUBPEL_MASK)
<< SCALE_EXTRA_BITS;
subpel_params[ref].xs = SCALE_SUBPEL_SHIFTS;
subpel_params[ref].ys = SCALE_SUBPEL_SHIFTS;
pre[ref] = pre_buf->buf +
(y + (mv_q4.row >> SUBPEL_BITS)) * pre_buf->stride +
(x + (mv_q4.col >> SUBPEL_BITS));
......@@ -1275,6 +1283,7 @@ void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd, int plane,
}
}
#if 0
void av1_build_inter_predictor_sub8x8(const AV1_COMMON *cm, MACROBLOCKD *xd,
int plane, int i, int ir, int ic,
int mi_row, int mi_col) {
......@@ -1336,6 +1345,7 @@ void av1_build_inter_predictor_sub8x8(const AV1_COMMON *cm, MACROBLOCKD *xd,
mi_row * MI_SIZE + 4 * ir, xd);
}
}
#endif
static void build_inter_predictors_for_planes(const AV1_COMMON *cm,
MACROBLOCKD *xd, BLOCK_SIZE bsize,
......@@ -3005,25 +3015,26 @@ static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
int pos_y = sf->scale_value_y(orig_pos_y, sf);
int pos_x = sf->scale_value_x(orig_pos_x, sf);
const int top = -((AOM_INTERP_EXTEND + bh) << SUBPEL_BITS);
const int bottom = (pre_buf->height + AOM_INTERP_EXTEND) << SUBPEL_BITS;
const int left = -((AOM_INTERP_EXTEND + bw) << SUBPEL_BITS);
const int right = (pre_buf->width + AOM_INTERP_EXTEND) << SUBPEL_BITS;
const int top = -((AOM_INTERP_EXTEND + bh) << SCALE_SUBPEL_BITS);
const int bottom = (pre_buf->height + AOM_INTERP_EXTEND)
<< SCALE_SUBPEL_BITS;
const int left = -((AOM_INTERP_EXTEND + bw) << SCALE_SUBPEL_BITS);
const int right = (pre_buf->width + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
pos_y = clamp(pos_y, top, bottom);
pos_x = clamp(pos_x, left, right);
pre = pre_buf->buf0 + (pos_y >> SUBPEL_BITS) * pre_buf->stride +
(pos_x >> SUBPEL_BITS);
subpel_x = pos_x & SUBPEL_MASK;
subpel_y = pos_y & SUBPEL_MASK;
pre = pre_buf->buf0 + (pos_y >> SCALE_SUBPEL_BITS) * pre_buf->stride +
(pos_x >> SCALE_SUBPEL_BITS);
subpel_x = pos_x & SCALE_SUBPEL_MASK;
subpel_y = pos_y & SCALE_SUBPEL_MASK;
xs = sf->x_step_q4;
ys = sf->y_step_q4;
} else {
const MV mv_q4 = clamp_mv_to_umv_border_sb(
xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
xs = ys = SCALE_DENOMINATOR;
subpel_x = mv_q4.col & SUBPEL_MASK;
subpel_y = mv_q4.row & SUBPEL_MASK;
xs = ys = SCALE_SUBPEL_SHIFTS;
subpel_x = (mv_q4.col & SUBPEL_MASK) << SCALE_EXTRA_BITS;
subpel_y = (mv_q4.row & SUBPEL_MASK) << SCALE_EXTRA_BITS;
pre = pre_buf->buf + (y + (mv_q4.row >> SUBPEL_BITS)) * pre_buf->stride +
(x + (mv_q4.col >> SUBPEL_BITS));
}
......
......@@ -32,7 +32,9 @@
extern "C" {
#endif
static INLINE int has_scale(int xs, int ys) { return xs != 16 || ys != 16; }
static INLINE int has_scale(int xs, int ys) {
return xs != SCALE_SUBPEL_SHIFTS || ys != SCALE_SUBPEL_SHIFTS;
}
static INLINE void inter_predictor(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride, int subpel_x,
......@@ -62,37 +64,51 @@ static INLINE void inter_predictor(const uint8_t *src, int src_stride,
assert(conv_params->do_average == 0 || conv_params->do_average == 1);
assert(sf);
if (has_scale(xs, ys)) {
// TODO(afergs, debargha): Use a different scale convolve function
// that uses higher precision for subpel_x, subpel_y, xs, ys
av1_convolve_c(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
} else if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
subpel_x >> SCALE_EXTRA_BITS, xs >> SCALE_EXTRA_BITS,
subpel_y >> SCALE_EXTRA_BITS, ys >> SCALE_EXTRA_BITS,
conv_params);
} else {
subpel_x >>= SCALE_EXTRA_BITS;
subpel_y >>= SCALE_EXTRA_BITS;
xs >>= SCALE_EXTRA_BITS;
ys >>= SCALE_EXTRA_BITS;
assert(subpel_x < SUBPEL_SHIFTS);
assert(subpel_y < SUBPEL_SHIFTS);
assert(xs <= SUBPEL_SHIFTS);
assert(ys <= SUBPEL_SHIFTS);
if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
#if CONFIG_CONVOLVE_ROUND
av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
#if CONFIG_DUAL_FILTER
interp_filter,
interp_filter,
#else // CONFIG_DUAL_FILTER
&interp_filter,
&interp_filter,
#endif // CONFIG_DUAL_FILTER
subpel_x, xs, subpel_y, ys, conv_params);
conv_params->do_post_rounding = 1;
subpel_x, xs, subpel_y, ys, conv_params);
conv_params->do_post_rounding = 1;
#else
assert(0);
assert(0);
#endif // CONFIG_CONVOLVE_ROUND
} else {
assert(conv_params->round == CONVOLVE_OPT_ROUND);
if (w <= 2 || h <= 2) {
av1_convolve_c(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
} else if (interp_filter_params_x.taps == SUBPEL_TAPS &&
interp_filter_params_y.taps == SUBPEL_TAPS) {
const int16_t *kernel_x =
av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
const int16_t *kernel_y =
av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
sf->predict[subpel_x != 0][subpel_y != 0][conv_params->do_average](
src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
} else {
av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
assert(conv_params->round == CONVOLVE_OPT_ROUND);
if (w <= 2 || h <= 2) {
av1_convolve_c(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
} else if (interp_filter_params_x.taps == SUBPEL_TAPS &&
interp_filter_params_y.taps == SUBPEL_TAPS) {
const int16_t *kernel_x = av1_get_interp_filter_subpel_kernel(
interp_filter_params_x, subpel_x);
const int16_t *kernel_y = av1_get_interp_filter_subpel_kernel(
interp_filter_params_y, subpel_y);
sf->predict[subpel_x != 0][subpel_y != 0][conv_params->do_average](
src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
} else {
av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
}
}
}
}
......@@ -100,8 +116,7 @@ static INLINE void inter_predictor(const uint8_t *src, int src_stride,
#if CONFIG_HIGHBITDEPTH
static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride,
const int subpel_x,
const int subpel_y,
int subpel_x, int subpel_y,
const struct scale_factors *sf, int w,
int h, ConvolveParams *conv_params,
#if CONFIG_DUAL_FILTER
......@@ -125,34 +140,49 @@ static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
#endif
if (has_scale(xs, ys)) {
// TODO(afergs, debargha): Use a different scale convolve function
// that uses higher precision for subpel_x, subpel_y, xs, ys
av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, avg, bd);
} else if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
subpel_x >> SCALE_EXTRA_BITS, xs >> SCALE_EXTRA_BITS,
subpel_y >> SCALE_EXTRA_BITS, ys >> SCALE_EXTRA_BITS,
avg, bd);
} else {
subpel_x >>= SCALE_EXTRA_BITS;
subpel_y >>= SCALE_EXTRA_BITS;
xs >>= SCALE_EXTRA_BITS;
ys >>= SCALE_EXTRA_BITS;
assert(subpel_x < SUBPEL_SHIFTS);
assert(subpel_y < SUBPEL_SHIFTS);
assert(xs <= SUBPEL_SHIFTS);
assert(ys <= SUBPEL_SHIFTS);
if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
#if CONFIG_CONVOLVE_ROUND
av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
#if CONFIG_DUAL_FILTER
interp_filter,
#else // CONFIG_DUAL_FILTER
&interp_filter,
interp_filter,
#else // CONFIG_DUAL_FILTER
&interp_filter,
#endif // CONFIG_DUAL_FILTER
subpel_x, xs, subpel_y, ys, conv_params, bd);
conv_params->do_post_rounding = 1;
subpel_x, xs, subpel_y, ys, conv_params,
bd);
conv_params->do_post_rounding = 1;
#else
assert(0);
assert(0);
#endif // CONFIG_CONVOLVE_ROUND
} else {
if (interp_filter_params_x.taps == SUBPEL_TAPS &&
interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
const int16_t *kernel_x =
av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
const int16_t *kernel_y =
av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
sf->highbd_predict[subpel_x != 0][subpel_y != 0][avg](
src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
bd);
} else {
av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, avg, bd);
if (interp_filter_params_x.taps == SUBPEL_TAPS &&
interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
const int16_t *kernel_x = av1_get_interp_filter_subpel_kernel(
interp_filter_params_x, subpel_x);
const int16_t *kernel_y = av1_get_interp_filter_subpel_kernel(
interp_filter_params_y, subpel_y);
sf->highbd_predict[subpel_x != 0][subpel_y != 0][avg](
src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
bd);
} else {
av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h,
interp_filter, subpel_x, xs, subpel_y, ys, avg, bd);
}
}
}
}
......@@ -619,8 +649,10 @@ void av1_highbd_build_inter_predictor(
static INLINE int scaled_buffer_offset(int x_offset, int y_offset, int stride,
const struct scale_factors *sf) {
const int x = sf ? sf->scale_value_x(x_offset, sf) : x_offset;
const int y = sf ? sf->scale_value_y(y_offset, sf) : y_offset;
const int x =
sf ? sf->scale_value_x(x_offset, sf) >> SCALE_EXTRA_BITS : x_offset;
const int y =
sf ? sf->scale_value_y(y_offset, sf) >> SCALE_EXTRA_BITS : y_offset;
return y * stride + x;
}
......
......@@ -14,17 +14,22 @@
#include "av1/common/scale.h"
#include "aom_dsp/aom_filter.h"
// Note: Expect val to be in q4 precision
static INLINE int scaled_x(int val, const struct scale_factors *sf) {
return (int)((int64_t)val * sf->x_scale_fp >> REF_SCALE_SHIFT);
return (int)((int64_t)val * sf->x_scale_fp >>
(REF_SCALE_SHIFT - SCALE_EXTRA_BITS));
}
// Note: Expect val to be in q4 precision
static INLINE int scaled_y(int val, const struct scale_factors *sf) {
return (int)((int64_t)val * sf->y_scale_fp >> REF_SCALE_SHIFT);
return (int)((int64_t)val * sf->y_scale_fp >>
(REF_SCALE_SHIFT - SCALE_EXTRA_BITS));
}
// Note: Expect val to be in q4 precision
static int unscaled_value(int val, const struct scale_factors *sf) {
(void)sf;
return val;
return val << SCALE_EXTRA_BITS;
}
static int get_fixed_point_scale_factor(int other_size, int this_size) {
......@@ -35,11 +40,13 @@ static int get_fixed_point_scale_factor(int other_size, int this_size) {
return (other_size << REF_SCALE_SHIFT) / this_size;
}
MV32 av1_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf) {
const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf) & SUBPEL_MASK;
const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf) & SUBPEL_MASK;
const MV32 res = { scaled_y(mv->row, sf) + y_off_q4,
scaled_x(mv->col, sf) + x_off_q4 };
// Note: x and y are integer precision, mv is g4 precision.
MV32 av1_scale_mv(const MV *mvq4, int x, int y,
const struct scale_factors *sf) {
const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf) & SCALE_SUBPEL_MASK;
const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf) & SCALE_SUBPEL_MASK;
const MV32 res = { scaled_y(mvq4->row, sf) + y_off_q4,
scaled_x(mvq4->col, sf) + x_off_q4 };
return res;
}
......@@ -59,8 +66,8 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);
sf->x_step_q4 = scaled_x(16, sf);
sf->y_step_q4 = scaled_y(16, sf);
sf->x_step_q4 = scaled_x(SUBPEL_SHIFTS, sf);
sf->y_step_q4 = scaled_y(SUBPEL_SHIFTS, sf);
if (av1_is_scaled(sf)) {
sf->scale_value_x = scaled_x;
......@@ -76,8 +83,8 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
// applied in one direction only, and not at all for 0,0, seems to give the
// best quality, but it may be worth trying an additional mode that does
// do the filtering on full-pel.
if (sf->x_step_q4 == 16) {
if (sf->y_step_q4 == 16) {
if (sf->x_step_q4 == SCALE_SUBPEL_SHIFTS) {
if (sf->y_step_q4 == SCALE_SUBPEL_SHIFTS) {
// No scaling in either direction.
sf->predict[0][0][0] = aom_convolve_copy;
sf->predict[0][0][1] = aom_convolve_avg;
......@@ -95,7 +102,7 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
sf->predict[1][0][1] = aom_convolve8_avg;
}
} else {
if (sf->y_step_q4 == 16) {
if (sf->y_step_q4 == SCALE_SUBPEL_SHIFTS) {
// No scaling in the y direction. Must always scale in the x direction.
sf->predict[0][0][0] = aom_convolve8_horiz;
sf->predict[0][0][1] = aom_convolve8_avg_horiz;
......@@ -119,8 +126,8 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
#if CONFIG_HIGHBITDEPTH
if (use_highbd) {
if (sf->x_step_q4 == 16) {
if (sf->y_step_q4 == 16) {
if (sf->x_step_q4 == SCALE_SUBPEL_SHIFTS) {
if (sf->y_step_q4 == SCALE_SUBPEL_SHIFTS) {
// No scaling in either direction.
sf->highbd_predict[0][0][0] = aom_highbd_convolve_copy;
sf->highbd_predict[0][0][1] = aom_highbd_convolve_avg;
......@@ -138,7 +145,7 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
sf->highbd_predict[1][0][1] = aom_highbd_convolve8_avg;
}
} else {
if (sf->y_step_q4 == 16) {
if (sf->y_step_q4 == SCALE_SUBPEL_SHIFTS) {
// No scaling in the y direction. Must always scale in the x direction.
sf->highbd_predict[0][0][0] = aom_highbd_convolve8_horiz;
sf->highbd_predict[0][0][1] = aom_highbd_convolve8_avg_horiz;
......
......@@ -19,6 +19,13 @@
extern "C" {
#endif
#define SCALE_DENOMINATOR 16
#define SCALE_SUBPEL_BITS 8
#define SCALE_SUBPEL_SHIFTS (1 << SCALE_SUBPEL_BITS)
#define SCALE_SUBPEL_MASK (SCALE_SUBPEL_SHIFTS - 1)
#define SCALE_EXTRA_BITS (SCALE_SUBPEL_BITS - SUBPEL_BITS)
#define REF_SCALE_SHIFT 14
#define REF_NO_SCALE (1 << REF_SCALE_SHIFT)
#define REF_INVALID_SCALE -1
......
......@@ -17,6 +17,7 @@
#include "./av1_rtcd.h"
#include "av1/common/warped_motion.h"
#include "av1/common/scale.h"
#define WARP_ERROR_BLOCK 32
......@@ -1147,8 +1148,8 @@ static void highbd_warp_plane(WarpedMotionParams *wm, const uint8_t *const ref8,
wm->wmmat[5] = wm->wmmat[2];
wm->wmmat[4] = -wm->wmmat[3];
}
if ((wm->wmtype == ROTZOOM || wm->wmtype == AFFINE) && x_scale == 16 &&
y_scale == 16) {
if ((wm->wmtype == ROTZOOM || wm->wmtype == AFFINE) &&
x_scale == SCALE_SUBPEL_SHIFTS && y_scale == SCALE_SUBPEL_SHIFTS) {
const int32_t *const mat = wm->wmmat;
const int16_t alpha = wm->alpha;
const int16_t beta = wm->beta;
......@@ -1579,8 +1580,8 @@ static void warp_plane(WarpedMotionParams *wm, const uint8_t *const ref,
wm->wmmat[5] = wm->wmmat[2];
wm->wmmat[4] = -wm->wmmat[3];
}
if ((wm->wmtype == ROTZOOM || wm->wmtype == AFFINE) && x_scale == 16 &&
y_scale == 16) {
if ((wm->wmtype == ROTZOOM || wm->wmtype == AFFINE) &&
x_scale == SCALE_SUBPEL_SHIFTS && y_scale == SCALE_SUBPEL_SHIFTS) {
const int32_t *const mat = wm->wmmat;
const int16_t alpha = wm->alpha;
const int16_t beta = wm->beta;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment