Commit 6e3557c9 authored by emilkeyder@google.com's avatar emilkeyder@google.com Committed by Sarah Parker

Split av1_warp_erroradv into av1_{frame,warp}_error.

This avoids repeatedly computing the frame error in
refine_integerized_param.

Change-Id: If4af77b68a7e61a700bafa3f60940b9017e12b40
parent 1dcb7075
......@@ -1121,31 +1121,38 @@ static void highbd_warp_plane(WarpedMotionParams *wm, const uint8_t *const ref8,
}
}
static double highbd_warp_erroradv(
static int64_t highbd_frame_error(const uint16_t *const ref, int stride,
const uint16_t *const dst, int p_col,
int p_row, int p_width, int p_height,
int p_stride, int bd) {
int64_t sum_error = 0;
for (int i = 0; i < p_height; ++i) {
for (int j = 0; j < p_width; ++j) {
sum_error += highbd_error_measure(
dst[j + i * p_stride] - ref[(j + p_col) + (i + p_row) * stride], bd);
}
}
return sum_error;
}
static int64_t highbd_warp_error(
WarpedMotionParams *wm, const uint8_t *const ref8, int width, int height,
int stride, const uint8_t *const dst8, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x, int subsampling_y,
int x_scale, int y_scale, int bd) {
int gm_err = 0, no_gm_err = 0;
int64_t gm_sumerr = 0, no_gm_sumerr = 0;
int i, j;
int64_t gm_sumerr = 0;
uint16_t *tmp = aom_malloc(p_width * p_height * sizeof(*tmp));
const uint16_t *const dst = CONVERT_TO_SHORTPTR(dst8);
const uint16_t *const ref = CONVERT_TO_SHORTPTR(ref8);
if (!tmp) return INT64_MAX;
highbd_warp_plane(wm, ref8, width, height, stride, CONVERT_TO_BYTEPTR(tmp),
p_col, p_row, p_width, p_height, p_width, subsampling_x,
subsampling_y, x_scale, y_scale, bd, 0);
for (i = 0; i < p_height; ++i) {
for (j = 0; j < p_width; ++j) {
gm_err = dst[j + i * p_stride] - tmp[j + i * p_width];
no_gm_err =
dst[j + i * p_stride] - ref[(j + p_col) + (i + p_row) * stride];
gm_sumerr += highbd_error_measure(gm_err, bd);
no_gm_sumerr += highbd_error_measure(no_gm_err, bd);
}
}
gm_sumerr = highbd_frame_error(tmp, p_width, CONVERT_TO_SHORTPTR(dst8), p_col,
p_row, p_width, p_height, p_stride, bd);
aom_free(tmp);
return (double)gm_sumerr / no_gm_sumerr;
return gm_sumerr;
}
#endif // CONFIG_HIGHBITDEPTH
......@@ -1380,53 +1387,76 @@ static void warp_plane(WarpedMotionParams *wm, const uint8_t *const ref,
}
}
static double warp_erroradv(WarpedMotionParams *wm, const uint8_t *const ref,
int width, int height, int stride,
const uint8_t *const dst, int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int x_scale,
int y_scale) {
int gm_err = 0, no_gm_err = 0;
int64_t gm_sumerr = 0, no_gm_sumerr = 0;
int i, j;
static int64_t frame_error(const uint8_t *const ref, int stride,
const uint8_t *const dst, int p_col, int p_row,
int p_width, int p_height, int p_stride) {
int64_t sum_error = 0;
for (int i = 0; i < p_height; ++i) {
for (int j = 0; j < p_width; ++j) {
sum_error += (int64_t)error_measure(
dst[j + i * p_stride] - ref[(j + p_col) + (i + p_row) * stride]);
}
}
return sum_error;
}
static int64_t warp_error(WarpedMotionParams *wm, const uint8_t *const ref,
int width, int height, int stride,
const uint8_t *const dst, int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int x_scale,
int y_scale) {
int64_t gm_sumerr = 0;
uint8_t *tmp = aom_malloc(p_width * p_height);
if (!tmp) return INT64_MAX;
warp_plane(wm, ref, width, height, stride, tmp, p_col, p_row, p_width,
p_height, p_width, subsampling_x, subsampling_y, x_scale, y_scale,
0);
for (i = 0; i < p_height; ++i) {
for (j = 0; j < p_width; ++j) {
gm_err = dst[j + i * p_stride] - tmp[j + i * p_width];
no_gm_err =
dst[j + i * p_stride] - ref[(j + p_col) + (i + p_row) * stride];
gm_sumerr += (int64_t)error_measure(gm_err);
no_gm_sumerr += (int64_t)error_measure(no_gm_err);
}
}
gm_sumerr =
frame_error(tmp, p_width, dst, p_col, p_row, p_width, p_height, p_stride);
aom_free(tmp);
return (double)gm_sumerr / no_gm_sumerr;
return gm_sumerr;
}
int64_t av1_frame_error(
#if CONFIG_HIGHBITDEPTH
int use_hbd, int bd,
#endif // CONFIG_HIGHBITDEPTH
const uint8_t *ref, int stride, uint8_t *dst, int p_col, int p_row,
int p_width, int p_height, int p_stride) {
#if CONFIG_HIGHBITDEPTH
if (use_hbd) {
return highbd_frame_error(CONVERT_TO_SHORTPTR(ref), stride,
CONVERT_TO_SHORTPTR(dst), p_col, p_row, p_width,
p_height, p_stride, bd);
}
#endif // CONFIG_HIGHBITDEPTH
return frame_error(ref, stride, dst, p_col, p_row, p_width, p_height,
p_stride);
}
double av1_warp_erroradv(WarpedMotionParams *wm,
int64_t av1_warp_error(WarpedMotionParams *wm,
#if CONFIG_HIGHBITDEPTH
int use_hbd, int bd,
int use_hbd, int bd,
#endif // CONFIG_HIGHBITDEPTH
const uint8_t *ref, int width, int height, int stride,
uint8_t *dst, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale) {
const uint8_t *ref, int width, int height, int stride,
uint8_t *dst, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale) {
if (wm->wmtype <= AFFINE)
if (!get_shear_params(wm)) return 1;
#if CONFIG_HIGHBITDEPTH
if (use_hbd)
return highbd_warp_erroradv(
wm, ref, width, height, stride, dst, p_col, p_row, p_width, p_height,
p_stride, subsampling_x, subsampling_y, x_scale, y_scale, bd);
return highbd_warp_error(wm, ref, width, height, stride, dst, p_col, p_row,
p_width, p_height, p_stride, subsampling_x,
subsampling_y, x_scale, y_scale, bd);
#endif // CONFIG_HIGHBITDEPTH
return warp_erroradv(wm, ref, width, height, stride, dst, p_col, p_row,
p_width, p_height, p_stride, subsampling_x,
subsampling_y, x_scale, y_scale);
return warp_error(wm, ref, width, height, stride, dst, p_col, p_row, p_width,
p_height, p_stride, subsampling_x, subsampling_y, x_scale,
y_scale);
}
void av1_warp_plane(WarpedMotionParams *wm,
......
......@@ -73,14 +73,25 @@ void project_points(const WarpedMotionParams *wm_params, int *points, int *proj,
const int n, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y);
double av1_warp_erroradv(WarpedMotionParams *wm,
// Returns the error between the result of applying motion 'wm' to the frame
// described by 'ref' and the frame described by 'dst'.
int64_t av1_warp_error(WarpedMotionParams *wm,
#if CONFIG_HIGHBITDEPTH
int use_hbd, int bd,
int use_hbd, int bd,
#endif // CONFIG_HIGHBITDEPTH
const uint8_t *ref, int width, int height, int stride,
uint8_t *dst, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale);
const uint8_t *ref, int width, int height, int stride,
uint8_t *dst, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale);
// Returns the error between the frame described by 'ref' and the frame
// described by 'dst'.
int64_t av1_frame_error(
#if CONFIG_HIGHBITDEPTH
int use_hbd, int bd,
#endif // CONFIG_HIGHBITDEPTH
const uint8_t *ref, int stride, uint8_t *dst, int p_col, int p_row,
int p_width, int p_height, int p_stride);
void av1_warp_plane(WarpedMotionParams *wm,
#if CONFIG_HIGHBITDEPTH
......
......@@ -5185,7 +5185,6 @@ static void encode_frame_internal(AV1_COMP *cpi) {
const double *params_this_motion;
int inliers_by_motion[RANSAC_NUM_MOTIONS];
WarpedMotionParams tmp_wm_params;
static const double kInfiniteErrAdv = 1e12;
static const double kIdentityParams[MAX_PARAMDIM - 1] = {
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0
};
......@@ -5204,10 +5203,19 @@ static void encode_frame_internal(AV1_COMP *cpi) {
} else if (ref_buf[frame] &&
do_gm_search_logic(&cpi->sf, num_refs_using_gm, frame)) {
TransformationType model;
const int64_t ref_frame_error = av1_frame_error(
#if CONFIG_HIGHBITDEPTH
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
#endif // CONFIG_HIGHBITDEPTH
ref_buf[frame]->y_buffer, ref_buf[frame]->y_stride,
cpi->source->y_buffer, 0, 0, cpi->source->y_width,
cpi->source->y_height, cpi->source->y_stride);
if (ref_frame_error == 0) continue;
aom_clear_system_state();
for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES_ENC; ++model) {
double best_erroradvantage = kInfiniteErrAdv;
int64_t best_warp_error = INT64_MAX;
// Initially set all params to identity.
for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
memcpy(params_by_motion + (MAX_PARAMDIM - 1) * i, kIdentityParams,
......@@ -5228,7 +5236,7 @@ static void encode_frame_internal(AV1_COMP *cpi) {
convert_model_to_params(params_this_motion, &tmp_wm_params);
if (tmp_wm_params.wmtype != IDENTITY) {
const double erroradv_this_motion = refine_integerized_param(
const int64_t warp_error = refine_integerized_param(
&tmp_wm_params, tmp_wm_params.wmtype,
#if CONFIG_HIGHBITDEPTH
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
......@@ -5237,8 +5245,8 @@ static void encode_frame_internal(AV1_COMP *cpi) {
ref_buf[frame]->y_height, ref_buf[frame]->y_stride,
cpi->source->y_buffer, cpi->source->y_width,
cpi->source->y_height, cpi->source->y_stride, 3);
if (erroradv_this_motion < best_erroradvantage) {
best_erroradvantage = erroradv_this_motion;
if (warp_error < best_warp_error) {
best_warp_error = warp_error;
// Save the wm_params modified by refine_integerized_param()
// rather than motion index to avoid rerunning refine() below.
memcpy(&(cm->global_motion[frame]), &tmp_wm_params,
......@@ -5264,7 +5272,7 @@ static void encode_frame_internal(AV1_COMP *cpi) {
// If the best error advantage found doesn't meet the threshold for
// this motion type, revert to IDENTITY.
if (!is_enough_erroradvantage(
best_erroradvantage,
(double)best_warp_error / ref_frame_error,
gm_get_params_cost(&cm->global_motion[frame],
&cm->prev_frame->global_motion[frame],
cm->allow_high_precision_mv))) {
......
......@@ -124,14 +124,15 @@ static void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
wm->wmtype = wmtype;
}
double refine_integerized_param(WarpedMotionParams *wm,
TransformationType wmtype,
int64_t refine_integerized_param(WarpedMotionParams *wm,
TransformationType wmtype,
#if CONFIG_HIGHBITDEPTH
int use_hbd, int bd,
int use_hbd, int bd,
#endif // CONFIG_HIGHBITDEPTH
uint8_t *ref, int r_width, int r_height,
int r_stride, uint8_t *dst, int d_width,
int d_height, int d_stride, int n_refinements) {
uint8_t *ref, int r_width, int r_height,
int r_stride, uint8_t *dst, int d_width,
int d_height, int d_stride,
int n_refinements) {
static const int max_trans_model_params[TRANS_TYPES] = {
0, 2, 4, 6, 8, 8, 8
};
......@@ -139,22 +140,21 @@ double refine_integerized_param(WarpedMotionParams *wm,
int i = 0, p;
int n_params = max_trans_model_params[wmtype];
int32_t *param_mat = wm->wmmat;
double step_error;
int64_t step_error, best_error;
int32_t step;
int32_t *param;
int32_t curr_param;
int32_t best_param;
double best_error;
force_wmtype(wm, wmtype);
best_error = av1_warp_erroradv(wm,
best_error = av1_warp_error(wm,
#if CONFIG_HIGHBITDEPTH
use_hbd, bd,
use_hbd, bd,
#endif // CONFIG_HIGHBITDEPTH
ref, r_width, r_height, r_stride,
dst + border * d_stride + border, border,
border, d_width - 2 * border,
d_height - 2 * border, d_stride, 0, 0, 16, 16);
ref, r_width, r_height, r_stride,
dst + border * d_stride + border, border, border,
d_width - 2 * border, d_height - 2 * border,
d_stride, 0, 0, 16, 16);
step = 1 << (n_refinements + 1);
for (i = 0; i < n_refinements; i++, step >>= 1) {
for (p = 0; p < n_params; ++p) {
......@@ -167,7 +167,7 @@ double refine_integerized_param(WarpedMotionParams *wm,
best_param = curr_param;
// look to the left
*param = add_param_offset(p, curr_param, -step);
step_error = av1_warp_erroradv(
step_error = av1_warp_error(
wm,
#if CONFIG_HIGHBITDEPTH
use_hbd, bd,
......@@ -183,7 +183,7 @@ double refine_integerized_param(WarpedMotionParams *wm,
// look to the right
*param = add_param_offset(p, curr_param, step);
step_error = av1_warp_erroradv(
step_error = av1_warp_error(
wm,
#if CONFIG_HIGHBITDEPTH
use_hbd, bd,
......@@ -202,7 +202,7 @@ double refine_integerized_param(WarpedMotionParams *wm,
// for the biggest step size
while (step_dir) {
*param = add_param_offset(p, best_param, step * step_dir);
step_error = av1_warp_erroradv(
step_error = av1_warp_error(
wm,
#if CONFIG_HIGHBITDEPTH
use_hbd, bd,
......
......@@ -26,14 +26,17 @@ void convert_model_to_params(const double *params, WarpedMotionParams *model);
int is_enough_erroradvantage(double erroradv, int params_cost);
double refine_integerized_param(WarpedMotionParams *wm,
TransformationType wmtype,
// Returns the av1_warp_error between "dst" and the result of applying the
// motion params that result from fine-tuning "wm" to "ref". Note that "wm" is
// modified in place.
int64_t refine_integerized_param(WarpedMotionParams *wm,
TransformationType wmtype,
#if CONFIG_HIGHBITDEPTH
int use_hbd, int bd,
int use_hbd, int bd,
#endif // CONFIG_HIGHBITDEPTH
uint8_t *ref, int r_width, int r_height,
int r_stride, uint8_t *dst, int d_width,
int d_height, int d_stride, int n_refinements);
uint8_t *ref, int r_width, int r_height,
int r_stride, uint8_t *dst, int d_width,
int d_height, int d_stride, int n_refinements);
/*
Computes "num_motions" candidate global motion parameters between two frames.
......
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