summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngie Chiang <angiebird@google.com>2018-09-24 17:37:05 -0700
committerAngie Chiang <angiebird@google.com>2018-09-25 17:05:06 -0700
commitf3a2b935e5863bf8640dbcbd9f3d194709c61f60 (patch)
tree467c5a86626edd98334431be3af602d0662d3f24
parentcdaca1f3558acb90afaf0b405665758781561eea (diff)
downloadlibvpx-f3a2b935e5863bf8640dbcbd9f3d194709c61f60.tar
libvpx-f3a2b935e5863bf8640dbcbd9f3d194709c61f60.tar.gz
libvpx-f3a2b935e5863bf8640dbcbd9f3d194709c61f60.tar.bz2
libvpx-f3a2b935e5863bf8640dbcbd9f3d194709c61f60.zip
Add vp9_diamond_search_sad_new
This new version of diamond search function will take into account neighbor motion vectors' inconsistency while doing mv search Change-Id: Icbde9880305cb8aea7937d6ddcef1597bf9be018
-rw-r--r--vp9/encoder/vp9_mcomp.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c
index 30f101574..9e3d95cb7 100644
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -1577,6 +1577,153 @@ static int exhuastive_mesh_search(const MACROBLOCK *x, MV *ref_mv, MV *best_mv,
return best_sad;
}
+#if CONFIG_NON_GREEDY_MV
+#define NB_MVS_NUM 4
+
+static double nb_mvs_inconsistency(const MV *mv, const int_mv *nb_mvs,
+ double lambda) {
+ int i;
+ double best_cost = -1;
+ vpx_clear_system_state();
+ for (i = 0; i < NB_MVS_NUM; ++i) {
+ if (nb_mvs[i].as_int != INVALID_MV) {
+ MV nb_mv = nb_mvs[i].as_mv;
+ const double row_diff = mv->row - nb_mv.row;
+ const double col_diff = mv->col - nb_mv.col;
+ double cost = row_diff * row_diff + col_diff * col_diff;
+ cost = log2(1 + cost);
+ if (best_cost < 0) {
+ best_cost = cost;
+ } else {
+ best_cost = cost < best_cost ? cost : best_cost;
+ }
+ }
+ }
+ if (best_cost < 0) {
+ return 0;
+ } else {
+ return best_cost * lambda;
+ }
+}
+
+double vp9_diamond_search_sad_new(const MACROBLOCK *x,
+ const search_site_config *cfg,
+ const MV *init_full_mv, MV *best_full_mv,
+ int search_param, double lambda, int *num00,
+ const vp9_variance_fn_ptr_t *fn_ptr,
+ const int_mv *nb_full_mvs) {
+ int i, j, step;
+
+ const MACROBLOCKD *const xd = &x->e_mbd;
+ uint8_t *what = x->plane[0].src.buf;
+ const int what_stride = x->plane[0].src.stride;
+ const uint8_t *in_what;
+ const int in_what_stride = xd->plane[0].pre[0].stride;
+ const uint8_t *best_address;
+
+ double bestsad;
+ int best_site = -1;
+ int last_site = -1;
+
+ // search_param determines the length of the initial step and hence the number
+ // of iterations.
+ // 0 = initial step (MAX_FIRST_STEP) pel
+ // 1 = (MAX_FIRST_STEP/2) pel,
+ // 2 = (MAX_FIRST_STEP/4) pel...
+ // const search_site *ss = &cfg->ss[search_param * cfg->searches_per_step];
+ const MV *ss_mv = &cfg->ss_mv[search_param * cfg->searches_per_step];
+ const intptr_t *ss_os = &cfg->ss_os[search_param * cfg->searches_per_step];
+ const int tot_steps = cfg->total_steps - search_param;
+ vpx_clear_system_state();
+
+ *best_full_mv = *init_full_mv;
+ clamp_mv(best_full_mv, x->mv_limits.col_min, x->mv_limits.col_max,
+ x->mv_limits.row_min, x->mv_limits.row_max);
+ *num00 = 0;
+
+ // Work out the start point for the search
+ in_what = xd->plane[0].pre[0].buf + best_full_mv->row * in_what_stride +
+ best_full_mv->col;
+ best_address = in_what;
+
+ // Check the starting position
+ bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride) +
+ nb_mvs_inconsistency(best_full_mv, nb_full_mvs, lambda);
+
+ i = 0;
+
+ for (step = 0; step < tot_steps; step++) {
+ int all_in = 1, t;
+
+ // All_in is true if every one of the points we are checking are within
+ // the bounds of the image.
+ all_in &= ((best_full_mv->row + ss_mv[i].row) > x->mv_limits.row_min);
+ all_in &= ((best_full_mv->row + ss_mv[i + 1].row) < x->mv_limits.row_max);
+ all_in &= ((best_full_mv->col + ss_mv[i + 2].col) > x->mv_limits.col_min);
+ all_in &= ((best_full_mv->col + ss_mv[i + 3].col) < x->mv_limits.col_max);
+
+ // If all the pixels are within the bounds we don't check whether the
+ // search point is valid in this loop, otherwise we check each point
+ // for validity..
+ if (all_in) {
+ unsigned int sad_array[4];
+
+ for (j = 0; j < cfg->searches_per_step; j += 4) {
+ unsigned char const *block_offset[4];
+
+ for (t = 0; t < 4; t++) block_offset[t] = ss_os[i + t] + best_address;
+
+ fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride,
+ sad_array);
+
+ for (t = 0; t < 4; t++, i++) {
+ if (sad_array[t] < bestsad) {
+ const MV this_mv = { best_full_mv->row + ss_mv[i].row,
+ best_full_mv->col + ss_mv[i].col };
+ double thissad = sad_array[t] + nb_mvs_inconsistency(
+ &this_mv, nb_full_mvs, lambda);
+ if (thissad < bestsad) {
+ bestsad = thissad;
+ best_site = i;
+ }
+ }
+ }
+ }
+ } else {
+ for (j = 0; j < cfg->searches_per_step; j++) {
+ // Trap illegal vectors
+ const MV this_mv = { best_full_mv->row + ss_mv[i].row,
+ best_full_mv->col + ss_mv[i].col };
+
+ if (is_mv_in(&x->mv_limits, &this_mv)) {
+ const uint8_t *const check_here = ss_os[i] + best_address;
+ double thissad =
+ fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
+
+ if (thissad < bestsad) {
+ thissad += nb_mvs_inconsistency(&this_mv, nb_full_mvs, lambda);
+ if (thissad < bestsad) {
+ bestsad = thissad;
+ best_site = i;
+ }
+ }
+ }
+ i++;
+ }
+ }
+ if (best_site != last_site) {
+ best_full_mv->row += ss_mv[best_site].row;
+ best_full_mv->col += ss_mv[best_site].col;
+ best_address += ss_os[best_site];
+ last_site = best_site;
+ } else if (best_address == in_what) {
+ (*num00)++;
+ }
+ }
+ return bestsad;
+}
+#endif // CONFIG_NON_GREEDY_MV
+
int vp9_diamond_search_sad_c(const MACROBLOCK *x, const search_site_config *cfg,
MV *ref_mv, MV *best_mv, int search_param,
int sad_per_bit, int *num00,