av1/encoder/mcomp.c
// Refines MV in a small range
Refines MV in a small range
Refines MV in a small range
unsigned int av1_refine_warped_mv(const AV1_COMP *cpi, MACROBLOCK *const x,
                                  BLOCK_SIZE bsize, int *pts0, int *pts_inref0,
                                  int total_samples) {
  const AV1_COMMON *const cm = &cpi->common;
  MACROBLOCKD *xd = &x->e_mbd;
  MB_MODE_INFO *mbmi = xd->mi[0];
  const MV neighbors[8] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 },
                            { 0, -2 }, { 2, 0 }, { 0, 2 }, { -2, 0 } };
  const int_mv ref_mv = av1_get_ref_mv(x, 0);
  int16_t br = mbmi->mv[0].as_mv.row;
  int16_t bc = mbmi->mv[0].as_mv.col;
  int16_t *tr = &mbmi->mv[0].as_mv.row;
  int16_t *tc = &mbmi->mv[0].as_mv.col;
  WarpedMotionParams best_wm_params = mbmi->wm_params;
  int best_num_proj_ref = mbmi->num_proj_ref;
  unsigned int bestmse;
  SubpelMvLimits mv_limits;
  const int start = cm->allow_high_precision_mv ? 0 : 4;
  int ite;
  av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, &ref_mv.as_mv);
  assert(av1_is_subpelmv_in_range(&mv_limits, mbmi->mv[0].as_mv));
  bestmse = av1_compute_motion_cost(cpi, x, bsize, &mbmi->mv[0].as_mv);
  const int mi_row = xd->mi_row;
  const int mi_col = xd->mi_col;
  for (ite = 0; ite < 2; ++ite) {
    int best_idx = -1;
    int idx;
    for (idx = start; idx < start + 4; ++idx) {
      unsigned int thismse;
      *tr = br + neighbors[idx].row;
      *tc = bc + neighbors[idx].col;
      MV this_mv = { *tr, *tc };
      if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) {
        int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
        memcpy(pts, pts0, total_samples * 2 * sizeof(*pts0));
        memcpy(pts_inref, pts_inref0, total_samples * 2 * sizeof(*pts_inref0));
        if (total_samples > 1)
          mbmi->num_proj_ref =
              av1_selectSamples(&this_mv, pts, pts_inref, total_samples, bsize);
        if (!av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize, *tr,
                                 *tc, &mbmi->wm_params, mi_row, mi_col)) {
          thismse = av1_compute_motion_cost(cpi, x, bsize, &this_mv);
          if (thismse < bestmse) {
            best_idx = idx;
            best_wm_params = mbmi->wm_params;
            best_num_proj_ref = mbmi->num_proj_ref;
            bestmse = thismse;
          }
        }
      }
    }
    if (best_idx == -1) break;
    if (best_idx >= 0) {
      br += neighbors[best_idx].row;
      bc += neighbors[best_idx].col;
    }
  }
  *tr = br;
  *tc = bc;
  mbmi->wm_params = best_wm_params;
  mbmi->num_proj_ref = best_num_proj_ref;
  return bestmse;
}
unsigned int av1_refine_warped_mv ( const AV1_COMP * cpi , MACROBLOCK * const x , BLOCK_SIZE bsize , int * pts0 , int * pts_inref0 , int total_samples ) { const AV1_COMMON * const cm = & cpi -> common ; MACROBLOCKD * xd = & x -> e_mbd ; MB_MODE_INFO * mbmi = xd -> mi [ 0 ] ; const MV neighbors [ 8 ] = { { 0 , -1 } , { 1 , 0 } , { 0 , 1 } , { -1 , 0 } , { 0 , -2 } , { 2 , 0 } , { 0 , 2 } , { -2 , 0 } } ; const int_mv ref_mv = av1_get_ref_mv ( x , 0 ) ; int16_t br = mbmi -> mv [ 0 ] . as_mv . row ; int16_t bc = mbmi -> mv [ 0 ] . as_mv . col ; int16_t * tr = & mbmi -> mv [ 0 ] . as_mv . row ; int16_t * tc = & mbmi -> mv [ 0 ] . as_mv . col ; WarpedMotionParams best_wm_params = mbmi -> wm_params ; int best_num_proj_ref = mbmi -> num_proj_ref ; unsigned int bestmse ; SubpelMvLimits mv_limits ; const int start = cm -> allow_high_precision_mv ? 0 : 4 ; int ite ; av1_set_subpel_mv_search_range ( & mv_limits , & x -> mv_limits , & ref_mv . as_mv ) ; assert ( av1_is_subpelmv_in_range ( & mv_limits , mbmi -> mv [ 0 ] . as_mv ) ) ; bestmse = av1_compute_motion_cost ( cpi , x , bsize , & mbmi -> mv [ 0 ] . as_mv ) ; const int mi_row = xd -> mi_row ; const int mi_col = xd -> mi_col ; for ( ite = 0 ; ite < 2 ; ++ ite ) { int best_idx = -1 ; int idx ; for ( idx = start ; idx < start + 4 ; ++ idx ) { unsigned int thismse ; * tr = br + neighbors [ idx ] . row ; * tc = bc + neighbors [ idx ] . col ; MV this_mv = { * tr , * tc } ; if ( av1_is_subpelmv_in_range ( & mv_limits , this_mv ) ) { int pts [ SAMPLES_ARRAY_SIZE ] , pts_inref [ SAMPLES_ARRAY_SIZE ] ; memcpy ( pts , pts0 , total_samples * 2 * sizeof ( * pts0 ) ) ; memcpy ( pts_inref , pts_inref0 , total_samples * 2 * sizeof ( * pts_inref0 ) ) ; if ( total_samples > 1 ) mbmi -> num_proj_ref = av1_selectSamples ( & this_mv , pts , pts_inref , total_samples , bsize ) ; if ( ! av1_find_projection ( mbmi -> num_proj_ref , pts , pts_inref , bsize , * tr , * tc , & mbmi -> wm_params , mi_row , mi_col ) ) { thismse = av1_compute_motion_cost ( cpi , x , bsize , & this_mv ) ; if ( thismse < bestmse ) { best_idx = idx ; best_wm_params = mbmi -> wm_params ; best_num_proj_ref = mbmi -> num_proj_ref ; bestmse = thismse ; } } } } if ( best_idx == -1 ) break ; if ( best_idx >= 0 ) { br += neighbors [ best_idx ] . row ; bc += neighbors [ best_idx ] . col ; } } * tr = br ; * tc = bc ; mbmi -> wm_params = best_wm_params ; mbmi -> num_proj_ref = best_num_proj_ref ; return bestmse ; }
Refines MV in a small range
Refines MV in a small range
// Calculate the center position's error // MV search