av1/encoder/mcomp.c
// Exhaustive motion search around a given centre position with a given
// step size.
Exhaustive motion search around a given centre position with a given
step size.
Exhaustive motion search around a given centre position with a given step size .
static int exhuastive_mesh_search(const MACROBLOCK *x, FULLPEL_MV *ref_mv,
                                  FULLPEL_MV *best_mv,
                                  FULLPEL_MV *second_best_mv, int range,
                                  int step, int sad_per_bit,
                                  const aom_variance_fn_ptr_t *fn_ptr,
                                  FULLPEL_MV start_mv) {
  const MACROBLOCKD *const xd = &x->e_mbd;
  const struct buf_2d *const what = &x->plane[0].src;
  const struct buf_2d *const in_what = &xd->plane[0].pre[0];
  unsigned int best_sad = INT_MAX;
  int r, c, i;
  int start_col, end_col, start_row, end_row;
  int col_step = (step > 1) ? step : 4;
  assert(step >= 1);
  clamp_fullmv(&start_mv, &x->mv_limits);
  *best_mv = start_mv;
  best_sad = fn_ptr->sdf(what->buf, what->stride,
                         get_buf_from_mv(in_what, &start_mv), in_what->stride) +
             mvsad_err_cost(x, &start_mv, ref_mv, sad_per_bit);
  start_row = AOMMAX(-range, x->mv_limits.row_min - start_mv.row);
  start_col = AOMMAX(-range, x->mv_limits.col_min - start_mv.col);
  end_row = AOMMIN(range, x->mv_limits.row_max - start_mv.row);
  end_col = AOMMIN(range, x->mv_limits.col_max - start_mv.col);
  for (r = start_row; r <= end_row; r += step) {
    for (c = start_col; c <= end_col; c += col_step) {
      if (step > 1) {
        const FULLPEL_MV mv = { start_mv.row + r, start_mv.col + c };
        unsigned int sad =
            fn_ptr->sdf(what->buf, what->stride, get_buf_from_mv(in_what, &mv),
                        in_what->stride);
        if (sad < best_sad) {
          sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
          if (sad < best_sad) {
            best_sad = sad;
            if (second_best_mv) {
              *second_best_mv = *best_mv;
            }
            *best_mv = mv;
          }
        }
      } else {
        if (c + 3 <= end_col) {
          unsigned int sads[4];
          const uint8_t *addrs[4];
          for (i = 0; i < 4; ++i) {
            const FULLPEL_MV mv = { start_mv.row + r, start_mv.col + c + i };
            addrs[i] = get_buf_from_mv(in_what, &mv);
          }
          fn_ptr->sdx4df(what->buf, what->stride, addrs, in_what->stride, sads);
          for (i = 0; i < 4; ++i) {
            if (sads[i] < best_sad) {
              const FULLPEL_MV mv = { start_mv.row + r, start_mv.col + c + i };
              const unsigned int sad =
                  sads[i] + mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
              if (sad < best_sad) {
                best_sad = sad;
                if (second_best_mv) {
                  *second_best_mv = *best_mv;
                }
                *best_mv = mv;
              }
            }
          }
        } else {
          for (i = 0; i < end_col - c; ++i) {
            const FULLPEL_MV mv = { start_mv.row + r, start_mv.col + c + i };
            unsigned int sad =
                fn_ptr->sdf(what->buf, what->stride,
                            get_buf_from_mv(in_what, &mv), in_what->stride);
            if (sad < best_sad) {
              sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
              if (sad < best_sad) {
                best_sad = sad;
                if (second_best_mv) {
                  *second_best_mv = *best_mv;
                }
                *best_mv = mv;
              }
            }
          }
        }
      }
    }
  }
  return best_sad;
}
static int exhuastive_mesh_search ( const MACROBLOCK * x , FULLPEL_MV * ref_mv , FULLPEL_MV * best_mv , FULLPEL_MV * second_best_mv , int range , int step , int sad_per_bit , const aom_variance_fn_ptr_t * fn_ptr , FULLPEL_MV start_mv ) { const MACROBLOCKD * const xd = & x -> e_mbd ; const struct buf_2d * const what = & x -> plane [ 0 ] . src ; const struct buf_2d * const in_what = & xd -> plane [ 0 ] . pre [ 0 ] ; unsigned int best_sad = INT_MAX ; int r , c , i ; int start_col , end_col , start_row , end_row ; int col_step = ( step > 1 ) ? step : 4 ; assert ( step >= 1 ) ; clamp_fullmv ( & start_mv , & x -> mv_limits ) ; * best_mv = start_mv ; best_sad = fn_ptr -> sdf ( what -> buf , what -> stride , get_buf_from_mv ( in_what , & start_mv ) , in_what -> stride ) + mvsad_err_cost ( x , & start_mv , ref_mv , sad_per_bit ) ; start_row = AOMMAX ( - range , x -> mv_limits . row_min - start_mv . row ) ; start_col = AOMMAX ( - range , x -> mv_limits . col_min - start_mv . col ) ; end_row = AOMMIN ( range , x -> mv_limits . row_max - start_mv . row ) ; end_col = AOMMIN ( range , x -> mv_limits . col_max - start_mv . col ) ; for ( r = start_row ; r <= end_row ; r += step ) { for ( c = start_col ; c <= end_col ; c += col_step ) { if ( step > 1 ) { const FULLPEL_MV mv = { start_mv . row + r , start_mv . col + c } ; unsigned int sad = fn_ptr -> sdf ( what -> buf , what -> stride , get_buf_from_mv ( in_what , & mv ) , in_what -> stride ) ; if ( sad < best_sad ) { sad += mvsad_err_cost ( x , & mv , ref_mv , sad_per_bit ) ; if ( sad < best_sad ) { best_sad = sad ; if ( second_best_mv ) { * second_best_mv = * best_mv ; } * best_mv = mv ; } } } else { if ( c + 3 <= end_col ) { unsigned int sads [ 4 ] ; const uint8_t * addrs [ 4 ] ; for ( i = 0 ; i < 4 ; ++ i ) { const FULLPEL_MV mv = { start_mv . row + r , start_mv . col + c + i } ; addrs [ i ] = get_buf_from_mv ( in_what , & mv ) ; } fn_ptr -> sdx4df ( what -> buf , what -> stride , addrs , in_what -> stride , sads ) ; for ( i = 0 ; i < 4 ; ++ i ) { if ( sads [ i ] < best_sad ) { const FULLPEL_MV mv = { start_mv . row + r , start_mv . col + c + i } ; const unsigned int sad = sads [ i ] + mvsad_err_cost ( x , & mv , ref_mv , sad_per_bit ) ; if ( sad < best_sad ) { best_sad = sad ; if ( second_best_mv ) { * second_best_mv = * best_mv ; } * best_mv = mv ; } } } } else { for ( i = 0 ; i < end_col - c ; ++ i ) { const FULLPEL_MV mv = { start_mv . row + r , start_mv . col + c + i } ; unsigned int sad = fn_ptr -> sdf ( what -> buf , what -> stride , get_buf_from_mv ( in_what , & mv ) , in_what -> stride ) ; if ( sad < best_sad ) { sad += mvsad_err_cost ( x , & mv , ref_mv , sad_per_bit ) ; if ( sad < best_sad ) { best_sad = sad ; if ( second_best_mv ) { * second_best_mv = * best_mv ; } * best_mv = mv ; } } } } } } } return best_sad ; }
Exhaustive motion search around a given centre position with a given
step size.
Exhaustive motion search around a given centre position with a given step size .
// Step > 1 means we are not checking every location in this pass. // 4 sads in a single call if we are checking every location