Remove MACROBLOCK from fractional_mv_step_fp This CL further modularizes subpel search by removing MACROBLOCK from the subpel search functions. Unfortunately, MACROBLOCKD and AV1_COMMON cannot be removed (or even made const) yet as they are called by some dsp functions, so those will have to be done by a separate CL. BUG=aomedia:2594 Change-Id: I60106e54673b8d6e5a4b258d75c54919d5b5894e
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c index 78486e7..1b48c2b 100644 --- a/av1/encoder/mcomp.c +++ b/av1/encoder/mcomp.c
@@ -100,6 +100,8 @@ ms_params->cost_list = cond_cost_list_const(cpi, cost_list); ms_params->do_reset_fractional_mv = do_reset_fractional_mv; + av1_set_subpel_mv_search_range(&ms_params->mv_limits, &x->mv_limits, ref_mv); + // Mvcost params init_mv_cost_params(&ms_params->mv_cost_params, x, ref_mv); @@ -107,21 +109,25 @@ ms_params->var_params.vfp = &cpi->fn_ptr[bsize]; ms_params->var_params.subpel_search_type = cpi->sf.mv_sf.use_accurate_subpel_search; - ms_params->var_params.second_pred = second_pred; - ms_params->var_params.mask = mask; - ms_params->var_params.mask_stride = mask_stride; - ms_params->var_params.invert_mask = invert_mask; ms_params->var_params.w = block_size_wide[bsize]; ms_params->var_params.h = block_size_high[bsize]; + + // Ref and src buffers + MSBuffers *ms_buffers = &ms_params->var_params.ms_buffers; + init_ms_buffers(ms_buffers, x); + ms_buffers->second_pred = second_pred; + ms_buffers->mask = mask; + ms_buffers->mask_stride = mask_stride; + ms_buffers->inv_mask = invert_mask; } -static INLINE int get_offset_from_mv(const FULLPEL_MV *mv, int stride) { +static INLINE int get_offset_from_fullmv(const FULLPEL_MV *mv, int stride) { return mv->row * stride + mv->col; } -static INLINE const uint8_t *get_buf_from_mv(const struct buf_2d *buf, - const FULLPEL_MV *mv) { - return &buf->buf[get_offset_from_mv(mv, buf->stride)]; +static INLINE const uint8_t *get_buf_from_fullmv(const struct buf_2d *buf, + const FULLPEL_MV *mv) { + return &buf->buf[get_offset_from_fullmv(mv, buf->stride)]; } void av1_set_mv_search_range(FullMvLimits *mv_limits, const MV *mv) { @@ -294,7 +300,7 @@ for (i = 0; i <= num_search_pts; ++i) { search_site *const ss = &cfg->ss[stage_index][i]; ss->mv = ss_mvs[i]; - ss->offset = get_offset_from_mv(&ss->mv, stride); + ss->offset = get_offset_from_fullmv(&ss->mv, stride); } cfg->searches_per_step[stage_index] = num_search_pts; cfg->radius[stage_index] = radius; @@ -338,7 +344,7 @@ for (i = 0; i <= num_search_pts; ++i) { search_site *const ss = &cfg->ss[stage_index][i]; ss->mv = ss_mvs[i]; - ss->offset = get_offset_from_mv(&ss->mv, stride); + ss->offset = get_offset_from_fullmv(&ss->mv, stride); } cfg->searches_per_step[stage_index] = num_search_pts; cfg->radius[stage_index] = radius; @@ -379,7 +385,7 @@ for (int i = 0; i <= num_search_pts; ++i) { search_site *const ss = &cfg->ss[stage_index][i]; ss->mv = ss_mvs[i]; - ss->offset = get_offset_from_mv(&ss->mv, stride); + ss->offset = get_offset_from_fullmv(&ss->mv, stride); } cfg->searches_per_step[stage_index] = num_search_pts; cfg->radius[stage_index] = radius; @@ -412,7 +418,7 @@ unsigned unused; int bestsme; - bestsme = vfp->vf(src_buf, src_stride, get_buf_from_mv(ref, this_mv), + bestsme = vfp->vf(src_buf, src_stride, get_buf_from_fullmv(ref, this_mv), ref_stride, &unused); bestsme += mv_err_cost_(&sub_this_mv, &ms_params->mv_cost_params); @@ -449,13 +455,13 @@ if (mask) { bestsme = vfp->msvf(src_buf, src_stride, 0, 0, - get_buf_from_mv(ref, this_mv), ref_stride, second_pred, - mask, mask_stride, invert_mask, &unused); + get_buf_from_fullmv(ref, this_mv), ref_stride, + second_pred, mask, mask_stride, invert_mask, &unused); } else if (second_pred) { - bestsme = vfp->svaf(get_buf_from_mv(ref, this_mv), ref_stride, 0, 0, + bestsme = vfp->svaf(get_buf_from_fullmv(ref, this_mv), ref_stride, 0, 0, src_buf, src_stride, &unused, second_pred); } else { - bestsme = vfp->vf(src_buf, src_stride, get_buf_from_mv(ref, this_mv), + bestsme = vfp->vf(src_buf, src_stride, get_buf_from_fullmv(ref, this_mv), ref_stride, &unused); } @@ -543,15 +549,15 @@ // Refresh the costlist it does not contain valid sad if (!costlist_has_sad) { - cost_list[0] = get_mvpred_sad(ms_params, src, - get_buf_from_mv(ref, &best_mv), ref_stride); + cost_list[0] = get_mvpred_sad( + ms_params, src, get_buf_from_fullmv(ref, &best_mv), ref_stride); if (check_bounds(&ms_params->mv_limits, br, bc, 1)) { for (int i = 0; i < 4; i++) { const FULLPEL_MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col }; cost_list[i + 1] = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); } } else { for (int i = 0; i < 4; i++) { @@ -561,7 +567,7 @@ cost_list[i + 1] = INT_MAX; } else { cost_list[i + 1] = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); } } } @@ -628,8 +634,8 @@ int costlist_has_sad = 0; // Work out the start point for the search - raw_bestsad = get_mvpred_sad(ms_params, src, get_buf_from_mv(ref, &start_mv), - ref_stride); + raw_bestsad = get_mvpred_sad(ms_params, src, + get_buf_from_fullmv(ref, &start_mv), ref_stride); bestsad = raw_bestsad + mvsad_err_cost_(&start_mv, mv_cost_params); // Search all possible scales up to the search param around the center point @@ -644,8 +650,8 @@ for (i = 0; i < num_candidates[t]; i++) { const FULLPEL_MV this_mv = { br + candidates[t][i].row, bc + candidates[t][i].col }; - thissad = get_mvpred_sad(ms_params, src, - get_buf_from_mv(ref, &this_mv), ref_stride); + thissad = get_mvpred_sad( + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } else { @@ -653,8 +659,8 @@ const FULLPEL_MV this_mv = { br + candidates[t][i].row, bc + candidates[t][i].col }; if (!av1_is_fullmv_in_range(&ms_params->mv_limits, this_mv)) continue; - thissad = get_mvpred_sad(ms_params, src, - get_buf_from_mv(ref, &this_mv), ref_stride); + thissad = get_mvpred_sad( + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } @@ -686,7 +692,7 @@ const FULLPEL_MV this_mv = { br + candidates[s][i].row, bc + candidates[s][i].col }; thissad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } else { @@ -696,7 +702,7 @@ if (!av1_is_fullmv_in_range(&ms_params->mv_limits, this_mv)) continue; thissad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } @@ -724,7 +730,7 @@ bc + candidates[s][next_chkpts_indices[i]].col }; thissad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } else { @@ -736,7 +742,7 @@ if (!av1_is_fullmv_in_range(&ms_params->mv_limits, this_mv)) continue; thissad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } @@ -759,7 +765,7 @@ const FULLPEL_MV this_mv = { br + candidates[s][i].row, bc + candidates[s][i].col }; cost_list[i + 1] = thissad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } else { @@ -769,7 +775,7 @@ if (!av1_is_fullmv_in_range(&ms_params->mv_limits, this_mv)) continue; cost_list[i + 1] = thissad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } @@ -797,7 +803,7 @@ bc + candidates[s][next_chkpts_indices[i]].col }; cost_list[next_chkpts_indices[i] + 1] = thissad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } else { @@ -811,7 +817,7 @@ continue; } cost_list[next_chkpts_indices[i] + 1] = thissad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &this_mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &this_mv), ref_stride); CHECK_BETTER } } @@ -1029,7 +1035,7 @@ *best_mv = start_mv; // Check the starting position - best_address = get_buf_from_mv(ref, &start_mv); + best_address = get_buf_from_fullmv(ref, &start_mv); bestsad = get_mvpred_compound_sad(ms_params, src, best_address, ref_stride); bestsad += mvsad_err_cost_(best_mv, &ms_params->mv_cost_params); @@ -1193,7 +1199,7 @@ clamp_fullmv(&start_mv, &ms_params->mv_limits); *best_mv = start_mv; - best_sad = get_mvpred_sad(ms_params, src, get_buf_from_mv(ref, &start_mv), + best_sad = get_mvpred_sad(ms_params, src, get_buf_from_fullmv(ref, &start_mv), ref_stride); best_sad += mvsad_err_cost_(&start_mv, mv_cost_params); start_row = AOMMAX(-range, ms_params->mv_limits.row_min - start_mv.row); @@ -1207,7 +1213,7 @@ if (step > 1) { const FULLPEL_MV mv = { start_mv.row + r, start_mv.col + c }; unsigned int sad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &mv), ref_stride); if (sad < best_sad) { sad += mvsad_err_cost_(&mv, mv_cost_params); if (sad < best_sad) { @@ -1225,7 +1231,7 @@ 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(ref, &mv); + addrs[i] = get_buf_from_fullmv(ref, &mv); } vfp->sdx4df(src->buf, src->stride, addrs, ref_stride, sads); @@ -1247,7 +1253,7 @@ for (i = 0; i < end_col - c; ++i) { const FULLPEL_MV mv = { start_mv.row + r, start_mv.col + c + i }; unsigned int sad = get_mvpred_sad( - ms_params, src, get_buf_from_mv(ref, &mv), ref_stride); + ms_params, src, get_buf_from_fullmv(ref, &mv), ref_stride); if (sad < best_sad) { sad += mvsad_err_cost_(&mv, mv_cost_params); if (sad < best_sad) { @@ -1364,19 +1370,20 @@ clamp_fullmv(best_mv, &x->mv_limits); if (mask) { - best_sad = fn_ptr->msdf(what->buf, what->stride, - get_buf_from_mv(in_what, best_mv), in_what->stride, - second_pred, mask, mask_stride, invert_mask) + - mvsad_err_cost(best_mv, &full_ref_mv, x->nmv_vec_cost, - CONVERT_TO_CONST_MVCOST(x->mv_cost_stack), - error_per_bit, x->mv_cost_type); - } else { best_sad = - fn_ptr->sdaf(what->buf, what->stride, get_buf_from_mv(in_what, best_mv), - in_what->stride, second_pred) + + fn_ptr->msdf(what->buf, what->stride, + get_buf_from_fullmv(in_what, best_mv), in_what->stride, + second_pred, mask, mask_stride, invert_mask) + mvsad_err_cost(best_mv, &full_ref_mv, x->nmv_vec_cost, CONVERT_TO_CONST_MVCOST(x->mv_cost_stack), error_per_bit, x->mv_cost_type); + } else { + best_sad = fn_ptr->sdaf(what->buf, what->stride, + get_buf_from_fullmv(in_what, best_mv), + in_what->stride, second_pred) + + mvsad_err_cost(best_mv, &full_ref_mv, x->nmv_vec_cost, + CONVERT_TO_CONST_MVCOST(x->mv_cost_stack), + error_per_bit, x->mv_cost_type); } do_refine_search_grid[grid_coord] = 1; @@ -1397,11 +1404,11 @@ unsigned int sad; if (mask) { sad = fn_ptr->msdf(what->buf, what->stride, - get_buf_from_mv(in_what, &mv), in_what->stride, + get_buf_from_fullmv(in_what, &mv), in_what->stride, second_pred, mask, mask_stride, invert_mask); } else { sad = fn_ptr->sdaf(what->buf, what->stride, - get_buf_from_mv(in_what, &mv), in_what->stride, + get_buf_from_fullmv(in_what, &mv), in_what->stride, second_pred); } if (sad < best_sad) { @@ -1736,7 +1743,7 @@ FULLPEL_MV this_mv = best_int_mv->as_fullmv; src_buf = x->plane[0].src.buf; - ref_buf = get_buf_from_mv(&xd->plane[0].pre[0], &this_mv); + ref_buf = get_buf_from_fullmv(&xd->plane[0].pre[0], &this_mv); best_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride); { @@ -1768,7 +1775,7 @@ else this_mv.col += 1; - ref_buf = get_buf_from_mv(&xd->plane[0].pre[0], &this_mv); + ref_buf = get_buf_from_fullmv(&xd->plane[0].pre[0], &this_mv); tmp_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride); if (best_sad > tmp_sad) { @@ -1805,7 +1812,7 @@ const MV mv = get_mv_from_fullmv(this_mv); unsigned int unused; - return vfp->ovf(get_buf_from_mv(ref_buf, this_mv), ref_buf->stride, wsrc, + return vfp->ovf(get_buf_from_fullmv(ref_buf, this_mv), ref_buf->stride, wsrc, mask, &unused) + mv_err_cost_(&mv, mv_cost_params); } @@ -1821,7 +1828,7 @@ const FULLPEL_MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } }; const int kSearchRange = 8; - unsigned int best_sad = fn_ptr->osdf(get_buf_from_mv(ref_buf, best_mv), + unsigned int best_sad = fn_ptr->osdf(get_buf_from_fullmv(ref_buf, best_mv), ref_buf->stride, wsrc, mask) + mvsad_err_cost_(best_mv, mv_cost_params); @@ -1832,7 +1839,7 @@ const FULLPEL_MV mv = { best_mv->row + neighbors[j].row, best_mv->col + neighbors[j].col }; if (av1_is_fullmv_in_range(&ms_params->mv_limits, mv)) { - unsigned int sad = fn_ptr->osdf(get_buf_from_mv(ref_buf, &mv), + unsigned int sad = fn_ptr->osdf(get_buf_from_fullmv(ref_buf, &mv), ref_buf->stride, wsrc, mask); if (sad < best_sad) { sad += mvsad_err_cost_(&mv, mv_cost_params); @@ -1877,7 +1884,7 @@ int step; clamp_fullmv(&start_mv, &ms_params->mv_limits); - best_address = init_ref = get_buf_from_mv(ref_buf, &start_mv); + best_address = init_ref = get_buf_from_fullmv(ref_buf, &start_mv); *num00 = 0; *best_mv = start_mv; @@ -1997,63 +2004,73 @@ */ // Returns the subpel offset used by various subpel variance functions [m]sv[a]f -static INLINE int sp(int x) { return x & 7; } +static INLINE int get_subpel_part(int x) { return x & 7; } // Gets the address of the ref buffer at subpel location (r, c), rounded to the // nearest fullpel precision toward - \infty -static INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c) { - const int offset = (r >> 3) * stride + (c >> 3); - return buf + offset; + +static INLINE const uint8_t *get_buf_from_mv(const struct buf_2d *buf, + const MV mv) { + const int offset = (mv.row >> 3) * buf->stride + (mv.col >> 3); + return &buf->buf[offset]; } // Estimates the variance of prediction residue using bilinear filter for fast // search. static INLINE int estimated_pref_error( - const MV *this_mv, const uint8_t *src, const int src_stride, - const uint8_t *ref, int ref_stride, - const SUBPEL_SEARCH_VAR_PARAMS *var_params, unsigned int *sse) { + const MV *this_mv, const SUBPEL_SEARCH_VAR_PARAMS *var_params, + unsigned int *sse) { const aom_variance_fn_ptr_t *vfp = var_params->vfp; - const uint8_t *second_pred = var_params->second_pred; - const uint8_t *mask = var_params->mask; - const int mask_stride = var_params->mask_stride; - const int invert_mask = var_params->invert_mask; - const int r = this_mv->row; - const int c = this_mv->col; + + const MSBuffers *ms_buffers = &var_params->ms_buffers; + const uint8_t *src = ms_buffers->src->buf; + const uint8_t *ref = get_buf_from_mv(ms_buffers->ref, *this_mv); + const int src_stride = ms_buffers->src->stride; + const int ref_stride = ms_buffers->ref->stride; + const uint8_t *second_pred = ms_buffers->second_pred; + const uint8_t *mask = ms_buffers->mask; + const int mask_stride = ms_buffers->mask_stride; + const int invert_mask = ms_buffers->inv_mask; + + const int subpel_x_q3 = get_subpel_part(this_mv->col); + const int subpel_y_q3 = get_subpel_part(this_mv->row); if (second_pred == NULL) { - return vfp->svf(pre(ref, ref_stride, r, c), ref_stride, sp(c), sp(r), src, - src_stride, sse); + return vfp->svf(ref, ref_stride, subpel_x_q3, subpel_y_q3, src, src_stride, + sse); } else if (mask) { - return vfp->msvf(pre(ref, ref_stride, r, c), ref_stride, sp(c), sp(r), src, - src_stride, second_pred, mask, mask_stride, invert_mask, - sse); + return vfp->msvf(ref, ref_stride, subpel_x_q3, subpel_y_q3, src, src_stride, + second_pred, mask, mask_stride, invert_mask, sse); } else { - return vfp->svaf(pre(ref, ref_stride, r, c), ref_stride, sp(c), sp(r), src, - src_stride, sse, second_pred); + return vfp->svaf(ref, ref_stride, subpel_x_q3, subpel_y_q3, src, src_stride, + sse, second_pred); } } // Calculates the variance of prediction residue. static int upsampled_pref_error(MACROBLOCKD *xd, const AV1_COMMON *cm, - const MV *this_mv, const uint8_t *src, - int src_stride, const uint8_t *ref, - int ref_stride, + const MV *this_mv, const SUBPEL_SEARCH_VAR_PARAMS *var_params, unsigned int *sse) { const aom_variance_fn_ptr_t *vfp = var_params->vfp; const SUBPEL_SEARCH_TYPE subpel_search_type = var_params->subpel_search_type; - const uint8_t *second_pred = var_params->second_pred; - const uint8_t *mask = var_params->mask; - const int mask_stride = var_params->mask_stride; - const int invert_mask = var_params->invert_mask; + + const MSBuffers *ms_buffers = &var_params->ms_buffers; + const uint8_t *src = ms_buffers->src->buf; + const uint8_t *ref = get_buf_from_mv(ms_buffers->ref, *this_mv); + const int src_stride = ms_buffers->src->stride; + const int ref_stride = ms_buffers->ref->stride; + const uint8_t *second_pred = ms_buffers->second_pred; + const uint8_t *mask = ms_buffers->mask; + const int mask_stride = ms_buffers->mask_stride; + const int invert_mask = ms_buffers->inv_mask; const int w = var_params->w; const int h = var_params->h; const int mi_row = xd->mi_row; const int mi_col = xd->mi_col; - const int subpel_x_q3 = sp(this_mv->col); - const int subpel_y_q3 = sp(this_mv->row); - ref = pre(ref, ref_stride, this_mv->row, this_mv->col); + const int subpel_x_q3 = get_subpel_part(this_mv->col); + const int subpel_y_q3 = get_subpel_part(this_mv->row); unsigned int besterr; #if CONFIG_AV1_HIGHBITDEPTH @@ -2127,15 +2144,13 @@ // it uses bilinear filter to estimate the prediction. static INLINE unsigned int check_better_fast( const MV *this_mv, MV *best_mv, const SubpelMvLimits *mv_limits, - const uint8_t *const src, const int src_stride, const uint8_t *const ref, - int ref_stride, const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion, int *has_better_mv) { unsigned int cost; if (av1_is_subpelmv_in_range(mv_limits, *this_mv)) { unsigned int sse; - int thismse = estimated_pref_error(this_mv, src, src_stride, ref, - ref_stride, var_params, &sse); + int thismse = estimated_pref_error(this_mv, var_params, &sse); cost = mv_err_cost_(this_mv, mv_cost_params); cost += thismse; @@ -2156,17 +2171,14 @@ // both prediction error and residue into account. static AOM_FORCE_INLINE unsigned int check_better( MACROBLOCKD *xd, const AV1_COMMON *cm, const MV *this_mv, MV *best_mv, - const SubpelMvLimits *mv_limits, const uint8_t *const src, - const int src_stride, const uint8_t *const ref, int ref_stride, - const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SubpelMvLimits *mv_limits, const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion, int *is_better) { unsigned int cost; if (av1_is_subpelmv_in_range(mv_limits, *this_mv)) { unsigned int sse; int thismse; - thismse = upsampled_pref_error(xd, cm, this_mv, src, src_stride, ref, - ref_stride, var_params, &sse); + thismse = upsampled_pref_error(xd, cm, this_mv, var_params, &sse); cost = mv_err_cost_(this_mv, mv_cost_params); cost += thismse; if (cost < *besterr) { @@ -2197,40 +2209,38 @@ // calculation. static AOM_FORCE_INLINE MV first_level_check_fast( const MV this_mv, MV *best_mv, int hstep, const SubpelMvLimits *mv_limits, - const uint8_t *const src, const int src_stride, const uint8_t *const ref, - int ref_stride, const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion) { // Check the four cardinal directions const MV left_mv = { this_mv.row, this_mv.col - hstep }; int dummy = 0; - const unsigned int left = check_better_fast( - &left_mv, best_mv, mv_limits, src, src_stride, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int left = + check_better_fast(&left_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); const MV right_mv = { this_mv.row, this_mv.col + hstep }; - const unsigned int right = check_better_fast( - &right_mv, best_mv, mv_limits, src, src_stride, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int right = + check_better_fast(&right_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); const MV top_mv = { this_mv.row - hstep, this_mv.col }; - const unsigned int up = check_better_fast( - &top_mv, best_mv, mv_limits, src, src_stride, ref, ref_stride, var_params, - mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int up = + check_better_fast(&top_mv, best_mv, mv_limits, var_params, mv_cost_params, + besterr, sse1, distortion, &dummy); const MV bottom_mv = { this_mv.row + hstep, this_mv.col }; - const unsigned int down = check_better_fast( - &bottom_mv, best_mv, mv_limits, src, src_stride, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int down = + check_better_fast(&bottom_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); const MV diag_step = get_best_diag_step(hstep, left, right, up, down); const MV diag_mv = { this_mv.row + diag_step.row, this_mv.col + diag_step.col }; // Check the diagonal direction with the best mv - check_better_fast(&diag_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + check_better_fast(&diag_mv, best_mv, mv_limits, var_params, mv_cost_params, + besterr, sse1, distortion, &dummy); return diag_step; } @@ -2239,9 +2249,7 @@ // performs two extra chess pattern searches in the best quadrant. static AOM_FORCE_INLINE void second_level_check_fast( const MV this_mv, const MV diag_step, MV *best_mv, int hstep, - const SubpelMvLimits *mv_limits, const uint8_t *const src, - const int src_stride, const uint8_t *const ref, int ref_stride, - const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SubpelMvLimits *mv_limits, const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion) { assert(diag_step.row == hstep || diag_step.row == -hstep); @@ -2256,47 +2264,39 @@ assert(diag_step.row == br - tr); const MV chess_mv_1 = { br, bc + diag_step.col }; const MV chess_mv_2 = { br + diag_step.row, bc }; - check_better_fast(&chess_mv_1, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + check_better_fast(&chess_mv_1, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); - check_better_fast(&chess_mv_2, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + check_better_fast(&chess_mv_2, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); } else if (tr == br && tc != bc) { assert(diag_step.col == bc - tc); // Continue searching in the best direction const MV bottom_long_mv = { br + hstep, bc + diag_step.col }; const MV top_long_mv = { br - hstep, bc + diag_step.col }; - check_better_fast(&bottom_long_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); - check_better_fast(&top_long_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + check_better_fast(&bottom_long_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); + check_better_fast(&top_long_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); // Search in the direction opposite of the best quadrant const MV rev_mv = { br - diag_step.row, bc }; - check_better_fast(&rev_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + check_better_fast(&rev_mv, best_mv, mv_limits, var_params, mv_cost_params, + besterr, sse1, distortion, &dummy); } else if (tr != br && tc == bc) { assert(diag_step.row == br - tr); // Continue searching in the best direction const MV right_long_mv = { br + diag_step.row, bc + hstep }; const MV left_long_mv = { br + diag_step.row, bc - hstep }; - check_better_fast(&right_long_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); - check_better_fast(&left_long_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + check_better_fast(&right_long_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); + check_better_fast(&left_long_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); // Search in the direction opposite of the best quadrant const MV rev_mv = { br, bc - diag_step.col }; - check_better_fast(&rev_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + check_better_fast(&rev_mv, best_mv, mv_limits, var_params, mv_cost_params, + besterr, sse1, distortion, &dummy); } } @@ -2305,54 +2305,51 @@ // diagonal/chess-pattern searches in the best quadrant. static AOM_FORCE_INLINE void two_level_checks_fast( const MV this_mv, MV *best_mv, int hstep, const SubpelMvLimits *mv_limits, - const uint8_t *const src, const int src_stride, const uint8_t *const ref, - int ref_stride, const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion, int iters) { - const MV diag_step = first_level_check_fast( - this_mv, best_mv, hstep, mv_limits, src, src_stride, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion); + const MV diag_step = + first_level_check_fast(this_mv, best_mv, hstep, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion); if (iters > 1) { - second_level_check_fast(this_mv, diag_step, best_mv, hstep, mv_limits, src, - src_stride, ref, ref_stride, var_params, - mv_cost_params, besterr, sse1, distortion); + second_level_check_fast(this_mv, diag_step, best_mv, hstep, mv_limits, + var_params, mv_cost_params, besterr, sse1, + distortion); } } -static AOM_FORCE_INLINE MV first_level_check( - MACROBLOCKD *xd, const AV1_COMMON *const cm, const MV this_mv, MV *best_mv, - const int hstep, const SubpelMvLimits *mv_limits, const uint8_t *const src, - const int src_stride, const uint8_t *const ref, int ref_stride, - const SUBPEL_SEARCH_VAR_PARAMS *var_params, - const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, - unsigned int *sse1, int *distortion) { +static AOM_FORCE_INLINE MV +first_level_check(MACROBLOCKD *xd, const AV1_COMMON *const cm, const MV this_mv, + MV *best_mv, const int hstep, const SubpelMvLimits *mv_limits, + const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, + unsigned int *sse1, int *distortion) { int dummy = 0; const MV left_mv = { this_mv.row, this_mv.col - hstep }; const MV right_mv = { this_mv.row, this_mv.col + hstep }; const MV top_mv = { this_mv.row - hstep, this_mv.col }; const MV bottom_mv = { this_mv.row + hstep, this_mv.col }; - const unsigned int left = check_better( - xd, cm, &left_mv, best_mv, mv_limits, src, src_stride, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); - const unsigned int right = check_better( - xd, cm, &right_mv, best_mv, mv_limits, src, src_stride, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); - const unsigned int up = check_better( - xd, cm, &top_mv, best_mv, mv_limits, src, src_stride, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); - const unsigned int down = check_better( - xd, cm, &bottom_mv, best_mv, mv_limits, src, src_stride, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int left = + check_better(xd, cm, &left_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int right = + check_better(xd, cm, &right_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int up = + check_better(xd, cm, &top_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int down = + check_better(xd, cm, &bottom_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); const MV diag_step = get_best_diag_step(hstep, left, right, up, down); const MV diag_mv = { this_mv.row + diag_step.row, this_mv.col + diag_step.col }; // Check the diagonal direction with the best mv - check_better(xd, cm, &diag_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + check_better(xd, cm, &diag_mv, best_mv, mv_limits, var_params, mv_cost_params, + besterr, sse1, distortion, &dummy); return diag_step; } @@ -2362,8 +2359,7 @@ // from av1_find_best_sub_pixel_tree static AOM_FORCE_INLINE void second_level_check_v2( MACROBLOCKD *xd, const AV1_COMMON *const cm, const MV this_mv, MV diag_step, - MV *best_mv, const SubpelMvLimits *mv_limits, const uint8_t *const src, - const int src_stride, const uint8_t *const ref, int ref_stride, + MV *best_mv, const SubpelMvLimits *mv_limits, const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion) { @@ -2386,52 +2382,53 @@ int has_better_mv = 0; if (var_params->subpel_search_type != USE_2_TAPS_ORIG) { - check_better(xd, cm, &row_bias_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &has_better_mv); - check_better(xd, cm, &col_bias_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &has_better_mv); + check_better(xd, cm, &row_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &has_better_mv); + check_better(xd, cm, &col_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &has_better_mv); // Do an additional search if the second iteration gives a better mv if (has_better_mv) { - check_better(xd, cm, &diag_bias_mv, best_mv, mv_limits, src, src_stride, - ref, ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &has_better_mv); + check_better(xd, cm, &diag_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &has_better_mv); } } else { - check_better_fast(&row_bias_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &has_better_mv); - check_better_fast(&col_bias_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &has_better_mv); + check_better_fast(&row_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); + check_better_fast(&col_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); // Do an additional search if the second iteration gives a better mv if (has_better_mv) { - check_better_fast(&diag_bias_mv, best_mv, mv_limits, src, src_stride, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &has_better_mv); + check_better_fast(&diag_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); } } } // Gets the error at the beginning when the mv has fullpel precision static unsigned int setup_center_error( - const MACROBLOCKD *xd, const MV *bestmv, const uint8_t *const src, - const int src_stride, const uint8_t *y, int y_stride, + const MACROBLOCKD *xd, const MV *bestmv, const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *sse1, int *distortion) { const aom_variance_fn_ptr_t *vfp = var_params->vfp; - const uint8_t *second_pred = var_params->second_pred; - const uint8_t *mask = var_params->mask; - const int mask_stride = var_params->mask_stride; - const int invert_mask = var_params->invert_mask; const int w = var_params->w; const int h = var_params->h; + const MSBuffers *ms_buffers = &var_params->ms_buffers; + const uint8_t *src = ms_buffers->src->buf; + const uint8_t *y = get_buf_from_mv(ms_buffers->ref, *bestmv); + const int src_stride = ms_buffers->src->stride; + const int y_stride = ms_buffers->ref->stride; + const uint8_t *second_pred = ms_buffers->second_pred; + const uint8_t *mask = ms_buffers->mask; + const int mask_stride = ms_buffers->mask_stride; + const int invert_mask = ms_buffers->inv_mask; + unsigned int besterr; - y = pre(y, y_stride, bestmv->row, bestmv->col); if (second_pred != NULL) { #if CONFIG_AV1_HIGHBITDEPTH @@ -2477,11 +2474,9 @@ // Gets the error at the beginning when the mv has fullpel precision static unsigned int upsampled_setup_center_error( MACROBLOCKD *xd, const AV1_COMMON *const cm, const MV *bestmv, - const uint8_t *const src, const int src_stride, const uint8_t *const y, - int y_stride, const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *sse1, int *distortion) { - unsigned int besterr = upsampled_pref_error(xd, cm, bestmv, src, src_stride, - y, y_stride, var_params, sse1); + unsigned int besterr = upsampled_pref_error(xd, cm, bestmv, var_params, sse1); *distortion = besterr; besterr += mv_err_cost_(bestmv, mv_cost_params); return besterr; @@ -2513,37 +2508,24 @@ } int av1_find_best_sub_pixel_tree_pruned_evenmore( - MACROBLOCK *x, const AV1_COMMON *const cm, - const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, int *distortion, - unsigned int *sse1) { + MACROBLOCKD *xd, const AV1_COMMON *const cm, + const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, MV start_mv, MV *bestmv, + int *distortion, unsigned int *sse1, int_mv *last_mv_search_list) { + (void)cm; + (void)last_mv_search_list; const int allow_hp = ms_params->allow_hp; const int forced_stop = ms_params->forced_stop; const int iters_per_step = ms_params->iters_per_step; const int *cost_list = ms_params->cost_list; + const SubpelMvLimits *mv_limits = &ms_params->mv_limits; const MV_COST_PARAMS *mv_cost_params = &ms_params->mv_cost_params; const SUBPEL_SEARCH_VAR_PARAMS *var_params = &ms_params->var_params; - const uint8_t *const src_address = x->plane[0].src.buf; - const int src_stride = x->plane[0].src.stride; - const MACROBLOCKD *xd = &x->e_mbd; unsigned int besterr = INT_MAX; - const uint8_t *const ref_address = xd->plane[0].pre[0].buf; - const int ref_stride = xd->plane[0].pre[0].stride; - - convert_fullmv_to_mv(&x->best_mv); - MV *bestmv = &x->best_mv.as_mv; - MV start_mv = *bestmv; - int hstep = INIT_SUBPEL_STEP_SIZE; + *bestmv = start_mv; - SubpelMvLimits mv_limits; - av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, - mv_cost_params->ref_mv); - - (void)cm; - - besterr = setup_center_error(xd, bestmv, src_address, src_stride, ref_address, - ref_stride, var_params, mv_cost_params, sse1, + besterr = setup_center_error(xd, bestmv, var_params, mv_cost_params, sse1, distortion); if (cost_list && cost_list[0] != INT_MAX && cost_list[1] != INT_MAX && @@ -2554,13 +2536,11 @@ get_cost_surf_min(cost_list, &ir, &ic, 2); if (ir != 0 || ic != 0) { const MV this_mv = { start_mv.row + 2 * ir, start_mv.col + 2 * ic }; - check_better_fast(&this_mv, bestmv, &mv_limits, src_address, src_stride, - ref_address, ref_stride, var_params, mv_cost_params, + check_better_fast(&this_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); } } else { - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); @@ -2569,8 +2549,7 @@ if (forced_stop != HALF_PEL) { hstep >>= 1; start_mv = *bestmv; - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); } @@ -2579,8 +2558,7 @@ if (allow_hp && forced_stop == EIGHTH_PEL) { hstep >>= 1; start_mv = *bestmv; - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); } @@ -2589,37 +2567,24 @@ } int av1_find_best_sub_pixel_tree_pruned_more( - MACROBLOCK *x, const AV1_COMMON *const cm, - const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, int *distortion, - unsigned int *sse1) { + MACROBLOCKD *xd, const AV1_COMMON *const cm, + const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, MV start_mv, MV *bestmv, + int *distortion, unsigned int *sse1, int_mv *last_mv_search_list) { + (void)cm; + (void)last_mv_search_list; const int allow_hp = ms_params->allow_hp; const int forced_stop = ms_params->forced_stop; const int iters_per_step = ms_params->iters_per_step; const int *cost_list = ms_params->cost_list; + const SubpelMvLimits *mv_limits = &ms_params->mv_limits; const MV_COST_PARAMS *mv_cost_params = &ms_params->mv_cost_params; const SUBPEL_SEARCH_VAR_PARAMS *var_params = &ms_params->var_params; - const uint8_t *const src_address = x->plane[0].src.buf; - const int src_stride = x->plane[0].src.stride; - const MACROBLOCKD *xd = &x->e_mbd; unsigned int besterr = INT_MAX; - const uint8_t *const ref_address = xd->plane[0].pre[0].buf; - const int ref_stride = xd->plane[0].pre[0].stride; - - convert_fullmv_to_mv(&x->best_mv); - MV *bestmv = &x->best_mv.as_mv; - MV start_mv = *bestmv; - int hstep = INIT_SUBPEL_STEP_SIZE; + *bestmv = start_mv; - SubpelMvLimits mv_limits; - av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, - mv_cost_params->ref_mv); - - (void)cm; - - besterr = setup_center_error(xd, bestmv, src_address, src_stride, ref_address, - ref_stride, var_params, mv_cost_params, sse1, + besterr = setup_center_error(xd, bestmv, var_params, mv_cost_params, sse1, distortion); if (cost_list && cost_list[0] != INT_MAX && cost_list[1] != INT_MAX && cost_list[2] != INT_MAX && cost_list[3] != INT_MAX && @@ -2630,13 +2595,11 @@ const MV this_mv = { start_mv.row + ir * hstep, start_mv.col + ic * hstep }; int dummy = 0; - check_better_fast(&this_mv, bestmv, &mv_limits, src_address, src_stride, - ref_address, ref_stride, var_params, mv_cost_params, + check_better_fast(&this_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); } } else { - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); } @@ -2646,8 +2609,7 @@ if (forced_stop != HALF_PEL) { hstep >>= 1; start_mv = *bestmv; - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); } @@ -2655,8 +2617,7 @@ if (allow_hp && forced_stop == EIGHTH_PEL) { hstep >>= 1; start_mv = *bestmv; - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); } @@ -2665,36 +2626,24 @@ } int av1_find_best_sub_pixel_tree_pruned( - MACROBLOCK *x, const AV1_COMMON *const cm, - const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, int *distortion, - unsigned int *sse1) { + MACROBLOCKD *xd, const AV1_COMMON *const cm, + const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, MV start_mv, MV *bestmv, + int *distortion, unsigned int *sse1, int_mv *last_mv_search_list) { + (void)cm; + (void)last_mv_search_list; const int allow_hp = ms_params->allow_hp; const int forced_stop = ms_params->forced_stop; const int iters_per_step = ms_params->iters_per_step; const int *cost_list = ms_params->cost_list; + const SubpelMvLimits *mv_limits = &ms_params->mv_limits; const MV_COST_PARAMS *mv_cost_params = &ms_params->mv_cost_params; const SUBPEL_SEARCH_VAR_PARAMS *var_params = &ms_params->var_params; - const uint8_t *const src_address = x->plane[0].src.buf; - const int src_stride = x->plane[0].src.stride; - const MACROBLOCKD *xd = &x->e_mbd; unsigned int besterr = INT_MAX; - const uint8_t *const ref_address = xd->plane[0].pre[0].buf; - const int ref_stride = xd->plane[0].pre[0].stride; - - convert_fullmv_to_mv(&x->best_mv); - MV *bestmv = &x->best_mv.as_mv; - MV start_mv = *bestmv; - int hstep = INIT_SUBPEL_STEP_SIZE; + *bestmv = start_mv; - SubpelMvLimits mv_limits; - av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, - mv_cost_params->ref_mv); - (void)cm; - - besterr = setup_center_error(xd, bestmv, src_address, src_stride, ref_address, - ref_stride, var_params, mv_cost_params, sse1, + besterr = setup_center_error(xd, bestmv, var_params, mv_cost_params, sse1, distortion); if (cost_list && cost_list[0] != INT_MAX && cost_list[1] != INT_MAX && cost_list[2] != INT_MAX && cost_list[3] != INT_MAX && @@ -2716,53 +2665,40 @@ switch (whichdir) { case 0: // bottom left quadrant - check_better_fast(&left_mv, bestmv, &mv_limits, src_address, src_stride, - ref_address, ref_stride, var_params, mv_cost_params, - &besterr, sse1, distortion, &dummy); - check_better_fast(&bottom_mv, bestmv, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + check_better_fast(&left_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); - check_better_fast(&bottom_left_mv, bestmv, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + check_better_fast(&bottom_mv, bestmv, mv_limits, var_params, + mv_cost_params, &besterr, sse1, distortion, &dummy); + check_better_fast(&bottom_left_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); break; case 1: // bottom right quadrant - check_better_fast(&right_mv, bestmv, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + check_better_fast(&right_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); - check_better_fast(&bottom_mv, bestmv, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + check_better_fast(&bottom_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); - check_better_fast(&bottom_right_mv, bestmv, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + check_better_fast(&bottom_right_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); break; case 2: // top left quadrant - check_better_fast(&left_mv, bestmv, &mv_limits, src_address, src_stride, - ref_address, ref_stride, var_params, mv_cost_params, - &besterr, sse1, distortion, &dummy); - check_better_fast(&top_mv, bestmv, &mv_limits, src_address, src_stride, - ref_address, ref_stride, var_params, mv_cost_params, - &besterr, sse1, distortion, &dummy); - check_better_fast(&top_left_mv, bestmv, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + check_better_fast(&left_mv, bestmv, mv_limits, var_params, + mv_cost_params, &besterr, sse1, distortion, &dummy); + check_better_fast(&top_mv, bestmv, mv_limits, var_params, + mv_cost_params, &besterr, sse1, distortion, &dummy); + check_better_fast(&top_left_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); break; case 3: // top right quadrant - check_better_fast(&right_mv, bestmv, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + check_better_fast(&right_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); - check_better_fast(&top_mv, bestmv, &mv_limits, src_address, src_stride, - ref_address, ref_stride, var_params, mv_cost_params, - &besterr, sse1, distortion, &dummy); - check_better_fast(&top_right_mv, bestmv, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + check_better_fast(&top_mv, bestmv, mv_limits, var_params, + mv_cost_params, &besterr, sse1, distortion, &dummy); + check_better_fast(&top_right_mv, bestmv, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, &dummy); break; } } else { - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); } @@ -2772,8 +2708,7 @@ if (forced_stop != HALF_PEL) { hstep >>= 1; start_mv = *bestmv; - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); } @@ -2781,8 +2716,7 @@ if (allow_hp && forced_stop == EIGHTH_PEL) { hstep >>= 1; start_mv = *bestmv; - two_level_checks_fast(start_mv, bestmv, hstep, &mv_limits, src_address, - src_stride, ref_address, ref_stride, var_params, + two_level_checks_fast(start_mv, bestmv, hstep, mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion, iters_per_step); } @@ -2790,78 +2724,65 @@ return besterr; } -int av1_find_best_sub_pixel_tree(MACROBLOCK *x, const AV1_COMMON *const cm, +int av1_find_best_sub_pixel_tree(MACROBLOCKD *xd, const AV1_COMMON *const cm, const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, - int *distortion, unsigned int *sse1) { + const MV start_mv, MV *bestmv, int *distortion, + unsigned int *sse1, + int_mv *last_mv_search_list) { const int allow_hp = ms_params->allow_hp; const int forced_stop = ms_params->forced_stop; const int iters_per_step = ms_params->iters_per_step; const int do_reset_fractional_mv = ms_params->do_reset_fractional_mv; const MV_COST_PARAMS *mv_cost_params = &ms_params->mv_cost_params; const SUBPEL_SEARCH_VAR_PARAMS *var_params = &ms_params->var_params; - const MV *ref_mv = mv_cost_params->ref_mv; const SUBPEL_SEARCH_TYPE subpel_search_type = ms_params->var_params.subpel_search_type; + const SubpelMvLimits *mv_limits = &ms_params->mv_limits; - MACROBLOCKD *xd = &x->e_mbd; - const uint8_t *const src_address = x->plane[0].src.buf; - const uint8_t *const ref_address = xd->plane[0].pre[0].buf; - const int src_stride = x->plane[0].src.stride; - const int ref_stride = xd->plane[0].pre[0].stride; - - convert_fullmv_to_mv(&x->best_mv); - MV *bestmv = &x->best_mv.as_mv; - - SubpelMvLimits mv_limits; - av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, ref_mv); - + const int round = AOMMIN(FULL_PEL - forced_stop, 3 - !allow_hp); int hstep = INIT_SUBPEL_STEP_SIZE; - int iter, round = FULL_PEL - forced_stop; + unsigned int besterr = INT_MAX; - if (!allow_hp) - if (round == 3) round = 2; + *bestmv = start_mv; if (subpel_search_type != USE_2_TAPS_ORIG) { - besterr = upsampled_setup_center_error( - xd, cm, bestmv, src_address, src_stride, ref_address, ref_stride, - var_params, mv_cost_params, sse1, distortion); + besterr = upsampled_setup_center_error(xd, cm, bestmv, var_params, + mv_cost_params, sse1, distortion); } else { - besterr = setup_center_error(xd, bestmv, src_address, src_stride, - ref_address, ref_stride, var_params, - mv_cost_params, sse1, distortion); + besterr = setup_center_error(xd, bestmv, var_params, mv_cost_params, sse1, + distortion); } - if (do_reset_fractional_mv) { - av1_set_fractional_mv(x->fractional_best_mv); + if (do_reset_fractional_mv && last_mv_search_list) { + av1_set_fractional_mv(last_mv_search_list); } - for (iter = 0; iter < round; ++iter) { + for (int iter = 0; iter < round; ++iter) { MV iter_center_mv = *bestmv; - if (CHECK_MV_EQUAL(x->fractional_best_mv[iter].as_mv, iter_center_mv)) { - return INT_MAX; - } + if (last_mv_search_list) { + if (CHECK_MV_EQUAL(last_mv_search_list[iter].as_mv, iter_center_mv)) { + return INT_MAX; + } - x->fractional_best_mv[iter].as_mv = iter_center_mv; + last_mv_search_list[iter].as_mv = iter_center_mv; + } MV diag_step; if (subpel_search_type != USE_2_TAPS_ORIG) { diag_step = first_level_check(xd, cm, iter_center_mv, bestmv, hstep, - &mv_limits, src_address, src_stride, - ref_address, ref_stride, var_params, - mv_cost_params, &besterr, sse1, distortion); + mv_limits, var_params, mv_cost_params, + &besterr, sse1, distortion); } else { - diag_step = first_level_check_fast( - iter_center_mv, bestmv, hstep, &mv_limits, src_address, src_stride, - ref_address, ref_stride, var_params, mv_cost_params, &besterr, sse1, - distortion); + diag_step = first_level_check_fast(iter_center_mv, bestmv, hstep, + mv_limits, var_params, mv_cost_params, + &besterr, sse1, distortion); } // Check diagonal sub-pixel position if (!CHECK_MV_EQUAL(iter_center_mv, *bestmv) && iters_per_step > 1) { second_level_check_v2(xd, cm, iter_center_mv, diag_step, bestmv, - &mv_limits, src_address, src_stride, ref_address, - ref_stride, var_params, mv_cost_params, &besterr, + mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion); } @@ -2875,24 +2796,23 @@ // vector unit test, which return extreme motion vectors allowed by the MV // limits. // Returns the maximum MV. -int av1_return_max_sub_pixel_mv(MACROBLOCK *x, const AV1_COMMON *const cm, +int av1_return_max_sub_pixel_mv(MACROBLOCKD *xd, const AV1_COMMON *const cm, const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, - int *distortion, unsigned int *sse1) { + const MV start_mv, MV *bestmv, int *distortion, + unsigned int *sse1, + int_mv *last_mv_search_list) { + (void)xd; (void)cm; + (void)start_mv; (void)sse1; (void)distortion; + (void)last_mv_search_list; const int allow_hp = ms_params->allow_hp; - const MV *ref_mv = ms_params->mv_cost_params.ref_mv; + const SubpelMvLimits *mv_limits = &ms_params->mv_limits; - convert_fullmv_to_mv(&x->best_mv); - MV *bestmv = &x->best_mv.as_mv; - - SubpelMvLimits mv_limits; - av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, ref_mv); - - bestmv->row = mv_limits.row_max; - bestmv->col = mv_limits.col_max; + bestmv->row = mv_limits->row_max; + bestmv->col = mv_limits->col_max; unsigned int besterr = 0; @@ -2903,24 +2823,23 @@ } // Returns the minimum MV. -int av1_return_min_sub_pixel_mv(MACROBLOCK *x, const AV1_COMMON *const cm, +int av1_return_min_sub_pixel_mv(MACROBLOCKD *xd, const AV1_COMMON *const cm, const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, - int *distortion, unsigned int *sse1) { + const MV start_mv, MV *bestmv, int *distortion, + unsigned int *sse1, + int_mv *last_mv_search_list) { + (void)xd; (void)cm; + (void)start_mv; (void)sse1; (void)distortion; + (void)last_mv_search_list; const int allow_hp = ms_params->allow_hp; - const MV *ref_mv = ms_params->mv_cost_params.ref_mv; + const SubpelMvLimits *mv_limits = &ms_params->mv_limits; - convert_fullmv_to_mv(&x->best_mv); - MV *bestmv = &x->best_mv.as_mv; - - SubpelMvLimits mv_limits; - av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, ref_mv); - - bestmv->row = mv_limits.row_min; - bestmv->col = mv_limits.col_min; + bestmv->row = mv_limits->row_min; + bestmv->col = mv_limits->col_min; unsigned int besterr = 0; // In the sub-pel motion search, if hp is not used, then the last bit of mv @@ -3013,22 +2932,25 @@ // ============================================================================= // Estimates the variance of prediction residue static INLINE int estimate_obmc_pref_error( - const MV *this_mv, const int32_t *src, const int32_t *mask, - const uint8_t *ref, int ref_stride, - const SUBPEL_SEARCH_VAR_PARAMS *var_params, unsigned int *sse) { + const MV *this_mv, const SUBPEL_SEARCH_VAR_PARAMS *var_params, + unsigned int *sse) { const aom_variance_fn_ptr_t *vfp = var_params->vfp; - const int r = this_mv->row; - const int c = this_mv->col; - return vfp->osvf(pre(ref, ref_stride, r, c), ref_stride, sp(c), sp(r), src, - mask, sse); + const MSBuffers *ms_buffers = &var_params->ms_buffers; + const int32_t *src = ms_buffers->wsrc; + const int32_t *mask = ms_buffers->obmc_mask; + const uint8_t *ref = get_buf_from_mv(ms_buffers->ref, *this_mv); + const int ref_stride = ms_buffers->ref->stride; + + const int subpel_x_q3 = get_subpel_part(this_mv->col); + const int subpel_y_q3 = get_subpel_part(this_mv->row); + + return vfp->osvf(ref, ref_stride, subpel_x_q3, subpel_y_q3, src, mask, sse); } // Calculates the variance of prediction residue static int upsampled_obmc_pref_error(MACROBLOCKD *xd, const AV1_COMMON *cm, - const MV *this_mv, const int32_t *wsrc, - const int32_t *mask, const uint8_t *ref, - int ref_stride, + const MV *this_mv, const SUBPEL_SEARCH_VAR_PARAMS *var_params, unsigned int *sse) { const aom_variance_fn_ptr_t *vfp = var_params->vfp; @@ -3036,11 +2958,17 @@ const int w = var_params->w; const int h = var_params->h; + const MSBuffers *ms_buffers = &var_params->ms_buffers; + const int32_t *wsrc = ms_buffers->wsrc; + const int32_t *mask = ms_buffers->obmc_mask; + const uint8_t *ref = get_buf_from_mv(ms_buffers->ref, *this_mv); + const int ref_stride = ms_buffers->ref->stride; + + const int subpel_x_q3 = get_subpel_part(this_mv->col); + const int subpel_y_q3 = get_subpel_part(this_mv->row); + const int mi_row = xd->mi_row; const int mi_col = xd->mi_col; - const int subpel_x_q3 = sp(this_mv->col); - const int subpel_y_q3 = sp(this_mv->row); - ref = pre(ref, ref_stride, this_mv->row, this_mv->col); unsigned int besterr; DECLARE_ALIGNED(16, uint8_t, pred[2 * MAX_SB_SQUARE]); @@ -3067,12 +2995,15 @@ } static unsigned int setup_obmc_center_error( - const MV *this_mv, const int32_t *const wsrc, const int32_t *mask, - const uint8_t *ref, int ref_stride, - const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const MV *this_mv, const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *sse1, int *distortion) { - // TODO(chiyotsai@google.com): There might be a bug here where we didn't move - // use y + pre(y, r, c). + // TODO(chiyotsai@google.com): There might be a bug here where we didn't use + // get_buf_from_mv(ref, *this_mv). + const MSBuffers *ms_buffers = &var_params->ms_buffers; + const int32_t *wsrc = ms_buffers->wsrc; + const int32_t *mask = ms_buffers->obmc_mask; + const uint8_t *ref = ms_buffers->ref->buf; + const int ref_stride = ms_buffers->ref->stride; unsigned int besterr = var_params->vfp->ovf(ref, ref_stride, wsrc, mask, sse1); *distortion = besterr; @@ -3082,11 +3013,10 @@ static unsigned int upsampled_setup_obmc_center_error( MACROBLOCKD *xd, const AV1_COMMON *const cm, const MV *this_mv, - const int32_t *const wsrc, const int32_t *mask, const uint8_t *const ref, - int ref_stride, const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *sse1, int *distortion) { - unsigned int besterr = upsampled_obmc_pref_error( - xd, cm, this_mv, wsrc, mask, ref, ref_stride, var_params, sse1); + unsigned int besterr = + upsampled_obmc_pref_error(xd, cm, this_mv, var_params, sse1); *distortion = besterr; besterr += mv_err_cost_(this_mv, mv_cost_params); return besterr; @@ -3123,15 +3053,13 @@ // both prediction error and residue into account. static INLINE unsigned int obmc_check_better_fast( const MV *this_mv, MV *best_mv, const SubpelMvLimits *mv_limits, - const int32_t *src, const int32_t *mask, const uint8_t *const ref, - int ref_stride, const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion, int *has_better_mv) { unsigned int cost; if (av1_is_subpelmv_in_range(mv_limits, *this_mv)) { unsigned int sse; - const int thismse = estimate_obmc_pref_error(this_mv, src, mask, ref, - ref_stride, var_params, &sse); + const int thismse = estimate_obmc_pref_error(this_mv, var_params, &sse); cost = estimate_obmc_mvcost(this_mv, mv_cost_params); cost += thismse; @@ -3153,16 +3081,14 @@ // both prediction error and residue into account. static INLINE unsigned int obmc_check_better( MACROBLOCKD *xd, const AV1_COMMON *cm, const MV *this_mv, MV *best_mv, - const SubpelMvLimits *mv_limits, const int32_t *src, const int32_t *mask, - const uint8_t *const ref, int ref_stride, - const SUBPEL_SEARCH_VAR_PARAMS *var_params, + const SubpelMvLimits *mv_limits, const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion, int *has_better_mv) { unsigned int cost; if (av1_is_subpelmv_in_range(mv_limits, *this_mv)) { unsigned int sse; - const int thismse = upsampled_obmc_pref_error( - xd, cm, this_mv, src, mask, ref, ref_stride, var_params, &sse); + const int thismse = + upsampled_obmc_pref_error(xd, cm, this_mv, var_params, &sse); cost = mv_err_cost_(this_mv, mv_cost_params); cost += thismse; @@ -3182,8 +3108,7 @@ static AOM_FORCE_INLINE MV obmc_first_level_check( MACROBLOCKD *xd, const AV1_COMMON *const cm, const MV this_mv, MV *best_mv, - const int hstep, const SubpelMvLimits *mv_limits, const int32_t *const src, - const int32_t *const mask, const uint8_t *const ref, int ref_stride, + const int hstep, const SubpelMvLimits *mv_limits, const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion) { @@ -3194,53 +3119,51 @@ const MV bottom_mv = { this_mv.row + hstep, this_mv.col }; if (var_params->subpel_search_type != USE_2_TAPS_ORIG) { - const unsigned int left = obmc_check_better( - xd, cm, &left_mv, best_mv, mv_limits, src, mask, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); - const unsigned int right = obmc_check_better( - xd, cm, &right_mv, best_mv, mv_limits, src, mask, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); - const unsigned int up = obmc_check_better( - xd, cm, &top_mv, best_mv, mv_limits, src, mask, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); - const unsigned int down = obmc_check_better( - xd, cm, &bottom_mv, best_mv, mv_limits, src, mask, ref, ref_stride, - var_params, mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int left = + obmc_check_better(xd, cm, &left_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int right = + obmc_check_better(xd, cm, &right_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int up = + obmc_check_better(xd, cm, &top_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); + const unsigned int down = + obmc_check_better(xd, cm, &bottom_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); const MV diag_step = get_best_diag_step(hstep, left, right, up, down); const MV diag_mv = { this_mv.row + diag_step.row, this_mv.col + diag_step.col }; // Check the diagonal direction with the best mv - obmc_check_better(xd, cm, &diag_mv, best_mv, mv_limits, src, mask, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &dummy); + obmc_check_better(xd, cm, &diag_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); return diag_step; } else { const unsigned int left = obmc_check_better_fast( - &left_mv, best_mv, mv_limits, src, mask, ref, ref_stride, var_params, - mv_cost_params, besterr, sse1, distortion, &dummy); + &left_mv, best_mv, mv_limits, var_params, mv_cost_params, besterr, sse1, + distortion, &dummy); const unsigned int right = obmc_check_better_fast( - &right_mv, best_mv, mv_limits, src, mask, ref, ref_stride, var_params, - mv_cost_params, besterr, sse1, distortion, &dummy); + &right_mv, best_mv, mv_limits, var_params, mv_cost_params, besterr, + sse1, distortion, &dummy); const unsigned int up = obmc_check_better_fast( - &top_mv, best_mv, mv_limits, src, mask, ref, ref_stride, var_params, - mv_cost_params, besterr, sse1, distortion, &dummy); + &top_mv, best_mv, mv_limits, var_params, mv_cost_params, besterr, sse1, + distortion, &dummy); const unsigned int down = obmc_check_better_fast( - &bottom_mv, best_mv, mv_limits, src, mask, ref, ref_stride, var_params, - mv_cost_params, besterr, sse1, distortion, &dummy); + &bottom_mv, best_mv, mv_limits, var_params, mv_cost_params, besterr, + sse1, distortion, &dummy); const MV diag_step = get_best_diag_step(hstep, left, right, up, down); const MV diag_mv = { this_mv.row + diag_step.row, this_mv.col + diag_step.col }; // Check the diagonal direction with the best mv - obmc_check_better_fast(&diag_mv, best_mv, mv_limits, src, mask, ref, - ref_stride, var_params, mv_cost_params, besterr, - sse1, distortion, &dummy); + obmc_check_better_fast(&diag_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, &dummy); return diag_step; } @@ -3249,8 +3172,7 @@ // A newer version of second level check for obmc that gives better quality. static AOM_FORCE_INLINE void obmc_second_level_check_v2( MACROBLOCKD *xd, const AV1_COMMON *const cm, const MV this_mv, MV diag_step, - MV *best_mv, const SubpelMvLimits *mv_limits, const int32_t *src, - const int32_t *mask, const uint8_t *const ref, int ref_stride, + MV *best_mv, const SubpelMvLimits *mv_limits, const SUBPEL_SEARCH_VAR_PARAMS *var_params, const MV_COST_PARAMS *mv_cost_params, unsigned int *besterr, unsigned int *sse1, int *distortion) { @@ -3273,93 +3195,73 @@ int has_better_mv = 0; if (var_params->subpel_search_type != USE_2_TAPS_ORIG) { - obmc_check_better(xd, cm, &row_bias_mv, best_mv, mv_limits, src, mask, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &has_better_mv); - obmc_check_better(xd, cm, &col_bias_mv, best_mv, mv_limits, src, mask, ref, - ref_stride, var_params, mv_cost_params, besterr, sse1, - distortion, &has_better_mv); + obmc_check_better(xd, cm, &row_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); + obmc_check_better(xd, cm, &col_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); // Do an additional search if the second iteration gives a better mv if (has_better_mv) { - obmc_check_better(xd, cm, &diag_bias_mv, best_mv, mv_limits, src, mask, - ref, ref_stride, var_params, mv_cost_params, besterr, - sse1, distortion, &has_better_mv); + obmc_check_better(xd, cm, &diag_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); } } else { - obmc_check_better_fast(&row_bias_mv, best_mv, mv_limits, src, mask, ref, - ref_stride, var_params, mv_cost_params, besterr, - sse1, distortion, &has_better_mv); - obmc_check_better_fast(&col_bias_mv, best_mv, mv_limits, src, mask, ref, - ref_stride, var_params, mv_cost_params, besterr, - sse1, distortion, &has_better_mv); + obmc_check_better_fast(&row_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); + obmc_check_better_fast(&col_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); // Do an additional search if the second iteration gives a better mv if (has_better_mv) { - obmc_check_better_fast(&diag_bias_mv, best_mv, mv_limits, src, mask, ref, - ref_stride, var_params, mv_cost_params, besterr, - sse1, distortion, &has_better_mv); + obmc_check_better_fast(&diag_bias_mv, best_mv, mv_limits, var_params, + mv_cost_params, besterr, sse1, distortion, + &has_better_mv); } } } int av1_find_best_obmc_sub_pixel_tree_up( - MACROBLOCK *x, const AV1_COMMON *const cm, - const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, int *distortion, - unsigned int *sse1) { + MACROBLOCKD *xd, const AV1_COMMON *const cm, + const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, const MV start_mv, MV *bestmv, + int *distortion, unsigned int *sse1, int_mv *last_mv_search_list) { + (void)last_mv_search_list; const int allow_hp = ms_params->allow_hp; + const int forced_stop = ms_params->forced_stop; const int iters_per_step = ms_params->iters_per_step; - const SUBPEL_FORCE_STOP forced_stop = ms_params->forced_stop; + // const int do_reset_fractional_mv = ms_params->do_reset_fractional_mv; const MV_COST_PARAMS *mv_cost_params = &ms_params->mv_cost_params; const SUBPEL_SEARCH_VAR_PARAMS *var_params = &ms_params->var_params; - const MV *ref_mv = mv_cost_params->ref_mv; const SUBPEL_SEARCH_TYPE subpel_search_type = ms_params->var_params.subpel_search_type; - - const int32_t *wsrc = x->wsrc_buf; - const int32_t *mask = x->mask_buf; - - MACROBLOCKD *xd = &x->e_mbd; - struct macroblockd_plane *const pd = &xd->plane[0]; - const int32_t *const src_address = wsrc; - - const int ref_stride = pd->pre[0].stride; - const uint8_t *ref_address = pd->pre[0].buf; - convert_fullmv_to_mv(&x->best_mv); - MV *bestmv = &x->best_mv.as_mv; - - SubpelMvLimits mv_limits; - - av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, ref_mv); + const SubpelMvLimits *mv_limits = &ms_params->mv_limits; int hstep = INIT_SUBPEL_STEP_SIZE; - int round = FULL_PEL - forced_stop; - - if (!allow_hp) - if (round == 3) round = 2; + const int round = AOMMIN(FULL_PEL - forced_stop, 3 - !allow_hp); unsigned int besterr = INT_MAX; + *bestmv = start_mv; if (subpel_search_type != USE_2_TAPS_ORIG) besterr = upsampled_setup_obmc_center_error( - xd, cm, bestmv, src_address, mask, ref_address, ref_stride, var_params, - mv_cost_params, sse1, distortion); + xd, cm, bestmv, var_params, mv_cost_params, sse1, distortion); else - besterr = setup_obmc_center_error(bestmv, src_address, mask, ref_address, - ref_stride, var_params, mv_cost_params, - sse1, distortion); + besterr = setup_obmc_center_error(bestmv, var_params, mv_cost_params, sse1, + distortion); for (int iter = 0; iter < round; ++iter) { MV iter_center_mv = *bestmv; - MV diag_step = obmc_first_level_check( - xd, cm, iter_center_mv, bestmv, hstep, &mv_limits, src_address, mask, - ref_address, ref_stride, var_params, mv_cost_params, &besterr, sse1, - distortion); + MV diag_step = obmc_first_level_check(xd, cm, iter_center_mv, bestmv, hstep, + mv_limits, var_params, mv_cost_params, + &besterr, sse1, distortion); if (!CHECK_MV_EQUAL(iter_center_mv, *bestmv) && iters_per_step > 1) { obmc_second_level_check_v2(xd, cm, iter_center_mv, diag_step, bestmv, - &mv_limits, src_address, mask, ref_address, - ref_stride, var_params, mv_cost_params, + mv_limits, var_params, mv_cost_params, &besterr, sse1, distortion); } hstep >>= 1; @@ -3380,7 +3282,7 @@ const MV_COST_TYPE mv_cost_type = x->mv_cost_type; unsigned int sse, var; - var = vfp->vf(what->buf, what->stride, get_buf_from_mv(in_what, best_mv), + var = vfp->vf(what->buf, what->stride, get_buf_from_fullmv(in_what, best_mv), in_what->stride, &sse); (void)var; @@ -3398,7 +3300,7 @@ const MV_COST_TYPE mv_cost_type = x->mv_cost_type; unsigned int sse, var; - var = vfp->vf(what->buf, what->stride, get_buf_from_mv(in_what, best_mv), + var = vfp->vf(what->buf, what->stride, get_buf_from_fullmv(in_what, best_mv), in_what->stride, &sse); return var + mv_err_cost(&mv, ref_mv, x->nmv_vec_cost, @@ -3416,7 +3318,7 @@ const MV_COST_TYPE mv_cost_type = x->mv_cost_type; unsigned int unused; - return vfp->svaf(get_buf_from_mv(in_what, best_mv), in_what->stride, 0, 0, + return vfp->svaf(get_buf_from_fullmv(in_what, best_mv), in_what->stride, 0, 0, what->buf, what->stride, &unused, second_pred) + mv_err_cost(&mv, ref_mv, x->nmv_vec_cost, CONVERT_TO_CONST_MVCOST(x->mv_cost_stack), x->errorperbit, @@ -3436,7 +3338,7 @@ unsigned int unused; return vfp->msvf(what->buf, what->stride, 0, 0, - get_buf_from_mv(in_what, best_mv), in_what->stride, + get_buf_from_fullmv(in_what, best_mv), in_what->stride, second_pred, mask, mask_stride, invert_mask, &unused) + mv_err_cost(&mv, ref_mv, x->nmv_vec_cost, CONVERT_TO_CONST_MVCOST(x->mv_cost_stack), x->errorperbit,
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h index f385c38..b9e5b80 100644 --- a/av1/encoder/mcomp.h +++ b/av1/encoder/mcomp.h
@@ -249,10 +249,8 @@ typedef struct { const aom_variance_fn_ptr_t *vfp; SUBPEL_SEARCH_TYPE subpel_search_type; - const uint8_t *second_pred; - const uint8_t *mask; - int mask_stride; - int invert_mask; + // Source and reference buffers + MSBuffers ms_buffers; int w, h; } SUBPEL_SEARCH_VAR_PARAMS; @@ -265,6 +263,7 @@ SUBPEL_FORCE_STOP forced_stop; int iters_per_step; int do_reset_fractional_mv; + SubpelMvLimits mv_limits; // For calculating mv cost MV_COST_PARAMS mv_cost_params; @@ -279,9 +278,11 @@ const int *cost_list, const uint8_t *second_pred, const uint8_t *mask, int mask_stride, int invert_mask, int do_reset_fractional_mv); -typedef int(fractional_mv_step_fp)(MACROBLOCK *x, const AV1_COMMON *const cm, +typedef int(fractional_mv_step_fp)(MACROBLOCKD *xd, const AV1_COMMON *const cm, const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, - int *distortion, unsigned int *sse1); + const MV start_mv, MV *bestmv, + int *distortion, unsigned int *sse1, + int_mv *last_mv_search_list); extern fractional_mv_step_fp av1_find_best_sub_pixel_tree; extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned;
diff --git a/av1/encoder/motion_search_facade.c b/av1/encoder/motion_search_facade.c index 6911043..7a0c38f 100644 --- a/av1/encoder/motion_search_facade.c +++ b/av1/encoder/motion_search_facade.c
@@ -15,6 +15,7 @@ #include "av1/encoder/encodemv.h" #include "av1/encoder/encoder.h" +#include "av1/encoder/mcomp.h" #include "av1/encoder/motion_search_facade.h" #include "av1/encoder/partition_strategy.h" #include "av1/encoder/reconinter_enc.h" @@ -198,48 +199,50 @@ const uint8_t *second_pred = NULL; const uint8_t *mask = NULL; const int mask_stride = 0; - const int invert_mask = 0; + const int invert_mask = 1; const int reset_fractional_mv = 1; + int_mv fractional_ms_list[3]; + av1_set_fractional_mv(fractional_ms_list); int dis; /* TODO: use dis in distortion calculation later. */ SUBPEL_MOTION_SEARCH_PARAMS ms_params; av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize, &ref_mv, cost_list, second_pred, mask, mask_stride, invert_mask, reset_fractional_mv); + MV subpel_start_mv = get_mv_from_fullmv(&x->best_mv.as_fullmv); + switch (mbmi->motion_mode) { case SIMPLE_TRANSLATION: if (cpi->sf.mv_sf.use_accurate_subpel_search) { const int try_second = second_best_mv.as_int != INVALID_MV && second_best_mv.as_int != x->best_mv.as_int; const int best_mv_var = cpi->find_fractional_mv_step( - x, cm, &ms_params, &dis, &x->pred_sse[ref]); + xd, cm, &ms_params, subpel_start_mv, &x->best_mv.as_mv, &dis, + &x->pred_sse[ref], fractional_ms_list); if (try_second) { - SubpelMvLimits subpel_limits; - av1_set_subpel_mv_search_range(&subpel_limits, &x->mv_limits, - &ref_mv); - MV best_mv = x->best_mv.as_mv; - - x->best_mv = second_best_mv; - if (av1_is_subpelmv_in_range( - &subpel_limits, - get_mv_from_fullmv(&x->best_mv.as_fullmv))) { + MV this_best_mv; + subpel_start_mv = get_mv_from_fullmv(&second_best_mv.as_fullmv); + if (av1_is_subpelmv_in_range(&ms_params.mv_limits, + subpel_start_mv)) { ms_params.do_reset_fractional_mv = !reset_fractional_mv; const int this_var = cpi->find_fractional_mv_step( - x, cm, &ms_params, &dis, &x->pred_sse[ref]); - if (this_var < best_mv_var) best_mv = x->best_mv.as_mv; + xd, cm, &ms_params, subpel_start_mv, &this_best_mv, &dis, + &x->pred_sse[ref], fractional_ms_list); + if (this_var < best_mv_var) x->best_mv.as_mv = this_best_mv; } - x->best_mv.as_mv = best_mv; } } else { - cpi->find_fractional_mv_step(x, cm, &ms_params, &dis, - &x->pred_sse[ref]); + cpi->find_fractional_mv_step(xd, cm, &ms_params, subpel_start_mv, + &x->best_mv.as_mv, &dis, + &x->pred_sse[ref], NULL); } break; case OBMC_CAUSAL: - av1_find_best_obmc_sub_pixel_tree_up(x, cm, &ms_params, &dis, - &x->pred_sse[ref]); + av1_find_best_obmc_sub_pixel_tree_up(xd, cm, &ms_params, + subpel_start_mv, &x->best_mv.as_mv, + &dis, &x->pred_sse[ref], NULL); break; default: assert(0 && "Invalid motion mode!\n"); } @@ -410,7 +413,9 @@ &ref_mv[id].as_mv, NULL, second_pred, mask, mask_stride, id, 1); ms_params.forced_stop = EIGHTH_PEL; - bestsme = cpi->find_fractional_mv_step(x, cm, &ms_params, &dis, &sse); + MV start_mv = get_mv_from_fullmv(&x->best_mv.as_fullmv); + bestsme = cpi->find_fractional_mv_step( + xd, cm, &ms_params, start_mv, &x->best_mv.as_mv, &dis, &sse, NULL); } // Restore the pointer to the first prediction buffer. @@ -528,7 +533,9 @@ NULL, second_pred, mask, mask_stride, ref_idx, 1); ms_params.forced_stop = EIGHTH_PEL; - bestsme = cpi->find_fractional_mv_step(x, cm, &ms_params, &dis, &sse); + MV start_mv = get_mv_from_fullmv(&best_int_mv->as_fullmv); + bestsme = cpi->find_fractional_mv_step( + xd, cm, &ms_params, start_mv, &best_int_mv->as_mv, &dis, &sse, NULL); } // Restore the pointer to the first unscaled prediction buffer. @@ -725,9 +732,11 @@ av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize, &ref_mv, cost_list, second_pred, mask, mask_stride, invert_mask, reset_fractional_mv); + MV subpel_start_mv = get_mv_from_fullmv(&x->best_mv.as_fullmv); - cpi->find_fractional_mv_step(x, cm, &ms_params, ¬_used, - &x->pred_sse[ref]); + cpi->find_fractional_mv_step(xd, cm, &ms_params, subpel_start_mv, + &x->best_mv.as_mv, ¬_used, + &x->pred_sse[ref], NULL); } else { // Manually convert from units of pixel to 1/8-pixels if we are not doing // subpel search
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c index a6ab0ce..60e0a85 100644 --- a/av1/encoder/nonrd_pickmode.c +++ b/av1/encoder/nonrd_pickmode.c
@@ -182,7 +182,10 @@ av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize, &ref_mv, cost_list, second_pred, mask, mask_stride, invert_mask, reset_fractional_mv); - cpi->find_fractional_mv_step(x, cm, &ms_params, &dis, &x->pred_sse[ref]); + MV subpel_start_mv = get_mv_from_fullmv(&x->best_mv.as_fullmv); + cpi->find_fractional_mv_step(xd, cm, &ms_params, subpel_start_mv, + &x->best_mv.as_mv, &dis, &x->pred_sse[ref], + NULL); *tmp_mv = x->best_mv; *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmv_vec_cost, @@ -242,8 +245,10 @@ av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize, &ref_mv, cost_list, second_pred, mask, mask_stride, invert_mask, reset_fractional_mv); - cpi->find_fractional_mv_step(x, cm, &ms_params, &dis, - &x->pred_sse[ref_frame]); + MV start_mv = get_mv_from_fullmv(&x->best_mv.as_fullmv); + cpi->find_fractional_mv_step(xd, cm, &ms_params, start_mv, + &x->best_mv.as_mv, &dis, + &x->pred_sse[ref_frame], NULL); frame_mv[NEWMV][ref_frame].as_int = x->best_mv.as_int; } else if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col, &frame_mv[NEWMV][ref_frame], rate_mv,
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c index c0aaa41..d8062f8 100644 --- a/av1/encoder/temporal_filter.c +++ b/av1/encoder/temporal_filter.c
@@ -148,8 +148,10 @@ mask, mask_stride, invert_mask, do_reset_fractional_mv); ms_params.forced_stop = EIGHTH_PEL; ms_params.var_params.subpel_search_type = subpel_search_type; - block_error = cpi->find_fractional_mv_step(mb, &cpi->common, &ms_params, - &distortion, &sse); + MV subpel_start_mv = get_mv_from_fullmv(&mb->best_mv.as_fullmv); + block_error = cpi->find_fractional_mv_step( + &mb->e_mbd, &cpi->common, &ms_params, subpel_start_mv, + &mb->best_mv.as_mv, &distortion, &sse, NULL); mb->e_mbd.mi[0]->mv[0] = mb->best_mv; *ref_mv = mb->best_mv.as_mv; @@ -184,8 +186,10 @@ do_reset_fractional_mv); ms_params.forced_stop = EIGHTH_PEL; ms_params.var_params.subpel_search_type = subpel_search_type; + subpel_start_mv = get_mv_from_fullmv(&mb->best_mv.as_fullmv); subblock_errors[subblock_idx] = cpi->find_fractional_mv_step( - mb, &cpi->common, &ms_params, &distortion, &sse); + &mb->e_mbd, &cpi->common, &ms_params, subpel_start_mv, + &mb->best_mv.as_mv, &distortion, &sse, NULL); subblock_mvs[subblock_idx] = mb->best_mv.as_mv; ++subblock_idx;
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c index f06708c..8ce2b32 100644 --- a/av1/encoder/tpl_model.c +++ b/av1/encoder/tpl_model.c
@@ -167,7 +167,10 @@ ms_params.forced_stop = EIGHTH_PEL; ms_params.var_params.subpel_search_type = USE_2_TAPS; ms_params.mv_cost_params.mv_cost_type = MV_COST_NONE; - bestsme = cpi->find_fractional_mv_step(x, cm, &ms_params, &distortion, &sse); + MV subpel_start_mv = get_mv_from_fullmv(&x->best_mv.as_fullmv); + bestsme = + cpi->find_fractional_mv_step(xd, cm, &ms_params, subpel_start_mv, + &x->best_mv.as_mv, &distortion, &sse, NULL); return bestsme; }