summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorDeb Mukherjee <debargha@google.com>2013-06-13 15:10:42 -0700
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2013-06-13 17:25:23 -0700
commit4ad96115cde5d18aaa274909f46742e3ceede034 (patch)
tree842c0e0c48263dd22363f84ae88d1617c14a1688 /vp9
parent5616daf93e09246c92eb29670e16e837832c4096 (diff)
downloadlibvpx-4ad96115cde5d18aaa274909f46742e3ceede034.tar
libvpx-4ad96115cde5d18aaa274909f46742e3ceede034.tar.gz
libvpx-4ad96115cde5d18aaa274909f46742e3ceede034.tar.bz2
libvpx-4ad96115cde5d18aaa274909f46742e3ceede034.zip
Some cleanups in rd motion search
No bitstream or output change - only cosmetics. Change-Id: Ic8c1d7ad010a87dcf27d12a38cd7dd5adba683a7
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_rdopt.c283
1 files changed, 152 insertions, 131 deletions
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 7eff2d04d..4e485e9f1 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1007,6 +1007,17 @@ void vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) {
x->e_mbd.mode_info_context->mbmi.mv[0].as_int = mv->as_int;
}
+static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
+ BLOCK_SIZE_TYPE bsize,
+ int_mv *frame_mv,
+ int mi_row, int mi_col,
+ int_mv single_newmv[MAX_REF_FRAMES],
+ int *rate_mv);
+static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
+ BLOCK_SIZE_TYPE bsize,
+ int mi_row, int mi_col,
+ int_mv *tmp_mv, int *rate_mv);
+
static int labels2mode(MACROBLOCK *x, int i,
MB_PREDICTION_MODE this_mode,
int_mv *this_mv, int_mv *this_second_mv,
@@ -1268,13 +1279,6 @@ static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
x->e_mbd.plane[0].pre[1] = orig_pre[1];
}
-static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
- BLOCK_SIZE_TYPE bsize,
- int_mv *frame_mv,
- YV12_BUFFER_CONFIG **scaled_ref_frame,
- int mi_row, int mi_col,
- int_mv single_newmv[MAX_REF_FRAMES]);
-
static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
BEST_SEG_INFO *bsi,
int_mv seg_mvs[4][MAX_REF_FRAMES],
@@ -1295,7 +1299,6 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
int bhl = b_height_log2(bsize), bh = 1 << bhl;
int idx, idy;
vp9_variance_fn_ptr_t *v_fn_ptr;
- YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL};
ENTROPY_CONTEXT t_above[4], t_left[4];
ENTROPY_CONTEXT t_above_b[4], t_left_b[4];
@@ -1431,9 +1434,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
// adjust src pointers
mi_buf_shift(x, i);
if (cpi->sf.comp_inter_joint_search_thresh < bsize) {
- iterative_motion_search(cpi, x, bsize, frame_mv[this_mode],
- scaled_ref_frame,
- mi_row, mi_col, seg_mvs[i]);
+ int rate_mv;
+ joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
+ mi_row, mi_col, seg_mvs[i],
+ &rate_mv);
seg_mvs[i][mbmi->ref_frame[0]].as_int =
frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
seg_mvs[i][mbmi->ref_frame[1]].as_int =
@@ -1790,6 +1794,14 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
frame_type, block_size);
}
+static YV12_BUFFER_CONFIG *get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) {
+ YV12_BUFFER_CONFIG *scaled_ref_frame = NULL;
+ int fb = get_ref_frame_idx(cpi, ref_frame);
+ if (cpi->scaled_ref_idx[fb] != cpi->common.ref_frame_map[fb])
+ scaled_ref_frame = &cpi->common.yv12_fb[cpi->scaled_ref_idx[fb]];
+ return scaled_ref_frame;
+}
+
static void model_rd_from_var_lapndz(int var, int n, int qstep,
int *rate, int *dist) {
// This function models the rate and distortion for a Laplacian
@@ -1881,17 +1893,98 @@ static INLINE int get_switchable_rate(VP9_COMMON *cm, MACROBLOCK *x) {
return SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs[c][m];
}
-static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
- BLOCK_SIZE_TYPE bsize,
- int_mv *frame_mv,
- YV12_BUFFER_CONFIG **scaled_ref_frame,
- int mi_row, int mi_col,
- int_mv single_newmv[MAX_REF_FRAMES]) {
+static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
+ BLOCK_SIZE_TYPE bsize,
+ int mi_row, int mi_col,
+ int_mv *tmp_mv, int *rate_mv) {
+ MACROBLOCKD *xd = &x->e_mbd;
+ MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
+ struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
+ int bestsme = INT_MAX;
+ int further_steps, step_param = cpi->sf.first_step;
+ int sadpb = x->sadperbit16;
+ int_mv mvp_full;
+ int ref = mbmi->ref_frame[0];
+ int_mv ref_mv = mbmi->ref_mvs[ref][0];
+ int sr = 0;
+ const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]);
+
+ int tmp_col_min = x->mv_col_min;
+ int tmp_col_max = x->mv_col_max;
+ int tmp_row_min = x->mv_row_min;
+ int tmp_row_max = x->mv_row_max;
+
+ YV12_BUFFER_CONFIG *scaled_ref_frame = get_scaled_ref_frame(cpi, ref);
+
+ if (scaled_ref_frame) {
+ int i;
+ // Swap out the reference frame for a version that's been scaled to
+ // match the resolution of the current frame, allowing the existing
+ // motion search code to be used without additional modifications.
+ for (i = 0; i < MAX_MB_PLANE; i++)
+ backup_yv12[i] = xd->plane[i].pre[0];
+
+ setup_pre_planes(xd, scaled_ref_frame, NULL, mi_row, mi_col,
+ NULL, NULL);
+ }
+
+ vp9_clamp_mv_min_max(x, &ref_mv);
+
+ sr = vp9_init_search_range(cpi->common.width, cpi->common.height);
+
+ // mvp_full.as_int = ref_mv[0].as_int;
+ mvp_full.as_int =
+ mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_int;
+
+ mvp_full.as_mv.col >>= 3;
+ mvp_full.as_mv.row >>= 3;
+
+ // adjust search range according to sr from mv prediction
+ step_param = MAX(step_param, sr);
+
+ // Further step/diamond searches as necessary
+ further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
+
+ bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
+ sadpb, further_steps, 1,
+ &cpi->fn_ptr[block_size],
+ &ref_mv, tmp_mv);
+
+ x->mv_col_min = tmp_col_min;
+ x->mv_col_max = tmp_col_max;
+ x->mv_row_min = tmp_row_min;
+ x->mv_row_max = tmp_row_max;
+
+ if (bestsme < INT_MAX) {
+ int dis; /* TODO: use dis in distortion calculation later. */
+ unsigned int sse;
+ cpi->find_fractional_mv_step(x, tmp_mv, &ref_mv,
+ x->errorperbit,
+ &cpi->fn_ptr[block_size],
+ x->nmvjointcost, x->mvcost,
+ &dis, &sse);
+ }
+ *rate_mv = vp9_mv_bit_cost(tmp_mv, &ref_mv,
+ x->nmvjointcost, x->mvcost,
+ 96, xd->allow_high_precision_mv);
+ if (scaled_ref_frame) {
+ int i;
+ for (i = 0; i < MAX_MB_PLANE; i++)
+ xd->plane[i].pre[0] = backup_yv12[i];
+ }
+}
+
+static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
+ BLOCK_SIZE_TYPE bsize,
+ int_mv *frame_mv,
+ int mi_row, int mi_col,
+ int_mv single_newmv[MAX_REF_FRAMES],
+ int *rate_mv) {
int pw = 4 << b_width_log2(bsize), ph = 4 << b_height_log2(bsize);
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
int refs[2] = { mbmi->ref_frame[0],
- (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
+ (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
int_mv ref_mv[2];
const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]);
int ite;
@@ -1903,6 +1996,9 @@ static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
struct buf_2d backup_second_yv12[MAX_MB_PLANE] = {{0}};
struct buf_2d scaled_first_yv12;
int last_besterr[2] = {INT_MAX, INT_MAX};
+ YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL};
+ scaled_ref_frame[0] = get_scaled_ref_frame(cpi, mbmi->ref_frame[0]);
+ scaled_ref_frame[1] = get_scaled_ref_frame(cpi, mbmi->ref_frame[1]);
ref_mv[0] = mbmi->ref_mvs[refs[0]][0];
ref_mv[1] = mbmi->ref_mvs[refs[1]][0];
@@ -1928,9 +2024,9 @@ static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
}
xd->scale_factor[0].set_scaled_offsets(&xd->scale_factor[0],
- mi_row, mi_col);
+ mi_row, mi_col);
xd->scale_factor[1].set_scaled_offsets(&xd->scale_factor[1],
- mi_row, mi_col);
+ mi_row, mi_col);
scaled_first_yv12 = xd->plane[0].pre[0];
// Initialize mv using single prediction mode result.
@@ -2025,6 +2121,14 @@ static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
for (i = 0; i < MAX_MB_PLANE; i++)
xd->plane[i].pre[1] = backup_second_yv12[i];
}
+ *rate_mv = vp9_mv_bit_cost(&frame_mv[refs[0]],
+ &mbmi->ref_mvs[refs[0]][0],
+ x->nmvjointcost, x->mvcost, 96,
+ x->e_mbd.allow_high_precision_mv);
+ *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]],
+ &mbmi->ref_mvs[refs[1]][0],
+ x->nmvjointcost, x->mvcost, 96,
+ x->e_mbd.allow_high_precision_mv);
vpx_free(second_pred);
}
@@ -2038,7 +2142,6 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int *mode_excluded, int *disable_skip,
INTERPOLATIONFILTERTYPE *best_filter,
int_mv *frame_mv,
- YV12_BUFFER_CONFIG **scaled_ref_frame,
int mi_row, int mi_col,
int_mv single_newmv[MAX_REF_FRAMES]) {
const int bw = 1 << mi_width_log2(bsize), bh = 1 << mi_height_log2(bsize);
@@ -2054,9 +2157,8 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
const int this_mode = mbmi->mode;
int i;
int refs[2] = { mbmi->ref_frame[0],
- (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
+ (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
int_mv cur_mv[2];
- int_mv ref_mv[2];
int64_t this_rd = 0;
unsigned char tmp_buf[MAX_MB_PLANE][64 * 64];
int pred_exists = 0;
@@ -2065,108 +2167,39 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int64_t rd, best_rd = INT64_MAX;
switch (this_mode) {
+ int rate_mv;
case NEWMV:
- ref_mv[0] = mbmi->ref_mvs[refs[0]][0];
- ref_mv[1] = mbmi->ref_mvs[refs[1]][0];
-
if (is_comp_pred) {
// Initialize mv using single prediction mode result.
frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
- if (cpi->sf.comp_inter_joint_search_thresh < bsize)
- iterative_motion_search(cpi, x, bsize, frame_mv, scaled_ref_frame,
- mi_row, mi_col, single_newmv);
-
+ if (cpi->sf.comp_inter_joint_search_thresh < bsize) {
+ joint_motion_search(cpi, x, bsize, frame_mv,
+ mi_row, mi_col, single_newmv, &rate_mv);
+ } else {
+ rate_mv = vp9_mv_bit_cost(&frame_mv[refs[0]],
+ &mbmi->ref_mvs[refs[0]][0],
+ x->nmvjointcost, x->mvcost, 96,
+ x->e_mbd.allow_high_precision_mv);
+ rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]],
+ &mbmi->ref_mvs[refs[1]][0],
+ x->nmvjointcost, x->mvcost, 96,
+ x->e_mbd.allow_high_precision_mv);
+ }
if (frame_mv[refs[0]].as_int == INVALID_MV ||
frame_mv[refs[1]].as_int == INVALID_MV)
return INT64_MAX;
- *rate2 += vp9_mv_bit_cost(&frame_mv[refs[0]],
- &ref_mv[0],
- x->nmvjointcost, x->mvcost, 96,
- x->e_mbd.allow_high_precision_mv);
- *rate2 += vp9_mv_bit_cost(&frame_mv[refs[1]],
- &ref_mv[1],
- x->nmvjointcost, x->mvcost, 96,
- x->e_mbd.allow_high_precision_mv);
- } else {
- struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
- int bestsme = INT_MAX;
- int further_steps, step_param = cpi->sf.first_step;
- int sadpb = x->sadperbit16;
- int_mv mvp_full, tmp_mv;
- int sr = 0;
-
- int tmp_col_min = x->mv_col_min;
- int tmp_col_max = x->mv_col_max;
- int tmp_row_min = x->mv_row_min;
- int tmp_row_max = x->mv_row_max;
-
- if (scaled_ref_frame[0]) {
- int i;
-
- // Swap out the reference frame for a version that's been scaled to
- // match the resolution of the current frame, allowing the existing
- // motion search code to be used without additional modifications.
- for (i = 0; i < MAX_MB_PLANE; i++)
- backup_yv12[i] = xd->plane[i].pre[0];
-
- setup_pre_planes(xd, scaled_ref_frame[0], NULL, mi_row, mi_col,
- NULL, NULL);
- }
-
- vp9_clamp_mv_min_max(x, &ref_mv[0]);
-
- sr = vp9_init_search_range(cpi->common.width, cpi->common.height);
+ *rate2 += rate_mv;
- // mvp_full.as_int = ref_mv[0].as_int;
- mvp_full.as_int =
- mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]].as_int;
-
- mvp_full.as_mv.col >>= 3;
- mvp_full.as_mv.row >>= 3;
-
- // adjust search range according to sr from mv prediction
- step_param = MAX(step_param, sr);
-
- // Further step/diamond searches as necessary
- further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
-
- bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
- sadpb, further_steps, 1,
- &cpi->fn_ptr[block_size],
- &ref_mv[0], &tmp_mv);
-
- x->mv_col_min = tmp_col_min;
- x->mv_col_max = tmp_col_max;
- x->mv_row_min = tmp_row_min;
- x->mv_row_max = tmp_row_max;
-
- if (bestsme < INT_MAX) {
- int dis; /* TODO: use dis in distortion calculation later. */
- unsigned int sse;
- cpi->find_fractional_mv_step(x, &tmp_mv,
- &ref_mv[0],
- x->errorperbit,
- &cpi->fn_ptr[block_size],
- x->nmvjointcost, x->mvcost,
- &dis, &sse);
- }
- frame_mv[refs[0]].as_int = tmp_mv.as_int;
+ } else {
+ int_mv tmp_mv;
+ single_motion_search(cpi, x, bsize, mi_row, mi_col,
+ &tmp_mv, &rate_mv);
+ *rate2 += rate_mv;
+ frame_mv[refs[0]].as_int =
+ xd->mode_info_context->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
single_newmv[refs[0]].as_int = tmp_mv.as_int;
-
- // Add the new motion vector cost to our rolling cost variable
- *rate2 += vp9_mv_bit_cost(&tmp_mv, &ref_mv[0],
- x->nmvjointcost, x->mvcost,
- 96, xd->allow_high_precision_mv);
-
- // restore the predictor, if required
- if (scaled_ref_frame[0]) {
- int i;
-
- for (i = 0; i < MAX_MB_PLANE; i++)
- xd->plane[i].pre[0] = backup_yv12[i];
- }
}
break;
case NEARMV:
@@ -2188,7 +2221,6 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->mv[i].as_int = cur_mv[i].as_int;
}
-
/* We don't include the cost of the second reference here, because there
* are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
* words if you present them in that order, the second one is always known
@@ -2200,10 +2232,10 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
interpolating_intpel_seen = 0;
// Are all MVs integer pel for Y and UV
intpel_mv = (mbmi->mv[0].as_mv.row & 15) == 0 &&
- (mbmi->mv[0].as_mv.col & 15) == 0;
+ (mbmi->mv[0].as_mv.col & 15) == 0;
if (is_comp_pred)
intpel_mv &= (mbmi->mv[1].as_mv.row & 15) == 0 &&
- (mbmi->mv[1].as_mv.col & 15) == 0;
+ (mbmi->mv[1].as_mv.col & 15) == 0;
// Search for best switchable filter by checking the variance of
// pred error irrespective of whether the filter will be used
if (cpi->speed > 4) {
@@ -2215,7 +2247,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int rs = 0;
const INTERPOLATIONFILTERTYPE filter = vp9_switchable_interp[i];
const int is_intpel_interp = intpel_mv &&
- vp9_is_interpolating_filter[filter];
+ vp9_is_interpolating_filter[filter];
mbmi->interp_filter = filter;
vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
@@ -2263,7 +2295,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
// Set the appripriate filter
mbmi->interp_filter = cm->mcomp_filter_type != SWITCHABLE ?
- cm->mcomp_filter_type : *best_filter;
+ cm->mcomp_filter_type : *best_filter;
vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
@@ -2876,17 +2908,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
compmode_cost = vp9_cost_bit(comp_mode_p, is_comp_pred);
} else {
- YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL};
- int fb = get_ref_frame_idx(cpi, mbmi->ref_frame[0]);
- if (cpi->scaled_ref_idx[fb] != cm->ref_frame_map[fb])
- scaled_ref_frame[0] = &cm->yv12_fb[cpi->scaled_ref_idx[fb]];
-
- if (comp_pred) {
- fb = get_ref_frame_idx(cpi, mbmi->ref_frame[1]);
- if (cpi->scaled_ref_idx[fb] != cm->ref_frame_map[fb])
- scaled_ref_frame[1] = &cm->yv12_fb[cpi->scaled_ref_idx[fb]];
- }
-
compmode_cost = vp9_cost_bit(comp_mode_p,
mbmi->ref_frame[1] > INTRA_FRAME);
this_rd = handle_inter_mode(cpi, x, bsize,
@@ -2896,7 +2917,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
&rate_uv, &distortion_uv,
&mode_excluded, &disable_skip,
&tmp_best_filter, frame_mv[this_mode],
- scaled_ref_frame, mi_row, mi_col,
+ mi_row, mi_col,
single_newmv);
if (this_rd == INT64_MAX)
continue;