Add parameter search to global motion computation
Change-Id: I66ea5a819ab54ecb5327eee20f798d7d7f0833d3
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 200b02c..8796ac9 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4403,7 +4403,80 @@
#if CONFIG_GLOBAL_MOTION
#define MIN_TRANS_THRESH 8
#define GLOBAL_MOTION_ADVANTAGE_THRESH 0.60
-#define GLOBAL_MOTION_MODEL TRANSLATION
+#define GLOBAL_MOTION_MODEL ROTZOOM
+static void refine_integerized_param(WarpedMotionParams *wm,
+#if CONFIG_AOM_HIGHBITDEPTH
+ int use_hbd, int bd,
+#endif // CONFIG_AOM_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) {
+ int i = 0, p;
+ int n_params = n_trans_model_params[wm->wmtype];
+ int16_t *param_mat = (int16_t *)wm->wmmat;
+ double step_error;
+ int step;
+ int16_t *param;
+ int16_t curr_param;
+ int16_t best_param;
+
+ double best_error =
+ av1_warp_erroradv(wm,
+#if CONFIG_AOM_HIGHBITDEPTH
+ use_hbd, bd,
+#endif // CONFIG_AOM_HIGHBITDEPTH
+ ref, r_width, r_height, r_stride, dst, 0, 0, d_width,
+ d_height, d_stride, 0, 0, 16, 16);
+ for (p = 0; p < n_params; ++p) {
+ param = param_mat + p;
+ step = 1 << (n_refinements + 1);
+ curr_param = *param;
+ best_param = curr_param;
+ for (i = 0; i < n_refinements; i++) {
+ // look to the left
+ *param = curr_param - step;
+ step_error =
+ av1_warp_erroradv(wm,
+#if CONFIG_AOM_HIGHBITDEPTH
+ use_hbd, bd,
+#endif // CONFIG_AOM_HIGHBITDEPTH
+ ref, r_width, r_height, r_stride, dst, 0, 0,
+ d_width, d_height, d_stride, 0, 0, 16, 16);
+ if (step_error < best_error) {
+ step >>= 1;
+ best_error = step_error;
+ best_param = *param;
+ curr_param = best_param;
+ continue;
+ }
+
+ // look to the right
+ *param = curr_param + step;
+ step_error =
+ av1_warp_erroradv(wm,
+#if CONFIG_AOM_HIGHBITDEPTH
+ use_hbd, bd,
+#endif // CONFIG_AOM_HIGHBITDEPTH
+ ref, r_width, r_height, r_stride, dst, 0, 0,
+ d_width, d_height, d_stride, 0, 0, 16, 16);
+ if (step_error < best_error) {
+ step >>= 1;
+ best_error = step_error;
+ best_param = *param;
+ curr_param = best_param;
+ continue;
+ }
+
+ // no improvement found-> means we're either already at a minimum or
+ // step is too wide
+ step >>= 1;
+ }
+
+ *param = best_param;
+ }
+}
+
static void convert_to_params(double *H, TransformationType type,
int16_t *model) {
int i;
@@ -4416,6 +4489,7 @@
model[1] = (int16_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
GM_TRANS_DECODE_FACTOR;
+ // TODO(sarahparker) 1 should be subtracted here
for (i = 2; i < n_params; ++i) {
model[i] = (int16_t)floor(H[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
model[i] = (int16_t)clamp(model[i], GM_ALPHA_MIN, GM_ALPHA_MAX) *
@@ -4476,6 +4550,14 @@
convert_model_to_params(H, GLOBAL_MOTION_MODEL,
&cm->global_motion[frame]);
if (get_gmtype(&cm->global_motion[frame]) > GLOBAL_ZERO) {
+ refine_integerized_param(
+ &cm->global_motion[frame].motion_params,
+#if CONFIG_AOM_HIGHBITDEPTH
+ xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
+#endif // CONFIG_AOM_HIGHBITDEPTH
+ ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
+ ref_buf->y_stride, cpi->Source->y_buffer, cpi->Source->y_width,
+ cpi->Source->y_height, cpi->Source->y_stride, 3);
// compute the advantage of using gm parameters over 0 motion
double erroradvantage = av1_warp_erroradv(
&cm->global_motion[frame].motion_params,