Refactors motion search in full_pixel_based_split.
The code for motion search is refactored to a different function to be
reused later by motion_search_based_pruner.
Change-Id: Iea168b13f5036201ac61ee1d9397abe3d8cef9a0
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 5f81fd5..ebfc8c2 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -2098,6 +2098,98 @@
active_v_edge(cpi, mi_col, cpi->common.seq_params.mib_size);
}
+// Performs a motion search in SIMPLE_TRANSLATION mode using
+// reference frame ref. Returns the sad of the result
+static void simple_motion_search(AV1_COMP *const cpi, MACROBLOCK *x, int mi_row,
+ int mi_col, BLOCK_SIZE bsize, int ref,
+ int num_planes, int use_subpixel) {
+ AV1_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *xd = &x->e_mbd;
+ MB_MODE_INFO *mbmi = xd->mi[0];
+
+ mbmi->ref_frame[0] = ref;
+ mbmi->ref_frame[1] = NONE_FRAME;
+ mbmi->sb_type = bsize;
+ mbmi->motion_mode = SIMPLE_TRANSLATION;
+
+ YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref);
+ const YV12_BUFFER_CONFIG *scaled_ref_frame =
+ av1_get_scaled_ref_frame(cpi, ref);
+ struct buf_2d backup_yv12;
+ // ref_mv is in units of 1/8-pel whereas ref_mv_full is in units of pel
+ MV ref_mv = { 0, 0 };
+ MV ref_mv_full = { 0, 0 };
+ const int step_param = cpi->mv_step_param;
+ const MvLimits tmp_mv_limits = x->mv_limits;
+ const SEARCH_METHODS search_methods = NSTEP;
+ const int do_mesh_search = 0;
+ const int sadpb = x->sadperbit16;
+ int cost_list[5];
+ const int ref_idx = 0;
+ int var;
+
+ av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, bsize);
+
+ if (scaled_ref_frame) {
+ backup_yv12 = xd->plane[AOM_PLANE_Y].pre[ref_idx];
+ av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL,
+ num_planes);
+ } else {
+ av1_setup_pre_planes(xd, ref_idx, yv12, mi_row, mi_col,
+ &cm->current_frame.frame_refs[ref - LAST_FRAME].sf,
+ num_planes);
+ }
+
+ // This overwrites the mv_limits so we will need to restore it later.
+ av1_set_mv_search_range(&x->mv_limits, &ref_mv);
+ var = av1_full_pixel_search(cpi, x, bsize, &ref_mv_full, step_param,
+ search_methods, do_mesh_search, sadpb,
+ cond_cost_list(cpi, cost_list), &ref_mv, INT_MAX,
+ 1, mi_col * MI_SIZE, mi_row * MI_SIZE, 0);
+ // Restore
+ x->mv_limits = tmp_mv_limits;
+
+ const int use_subpel_search =
+ var < INT_MAX && !cpi->common.cur_frame_force_integer_mv && use_subpixel;
+ if (use_subpel_search) {
+ int not_used = 0;
+ if (cpi->sf.use_accurate_subpel_search) {
+ const int pw = block_size_wide[bsize];
+ const int ph = block_size_high[bsize];
+ cpi->find_fractional_mv_step(
+ x, cm, mi_row, mi_col, &ref_mv, cm->allow_high_precision_mv,
+ x->errorperbit, &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
+ cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
+ x->nmv_vec_cost, x->mv_cost_stack, ¬_used, &x->pred_sse[ref], NULL,
+ NULL, 0, 0, pw, ph, cpi->sf.use_accurate_subpel_search, 1);
+ } else {
+ cpi->find_fractional_mv_step(
+ x, cm, mi_row, mi_col, &ref_mv, cm->allow_high_precision_mv,
+ x->errorperbit, &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
+ cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
+ x->nmv_vec_cost, x->mv_cost_stack, ¬_used, &x->pred_sse[ref], NULL,
+ NULL, 0, 0, 0, 0, 0, 1);
+ }
+ } else {
+ // Manually convert from units of pixel to 1/8-pixels if we are not doing
+ // subpel search
+ x->best_mv.as_mv.row *= 8;
+ x->best_mv.as_mv.col *= 8;
+ }
+
+ mbmi->mv[0].as_mv = x->best_mv.as_mv;
+
+ // Get a copy of the prediction output
+ set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
+ av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, NULL, bsize);
+
+ aom_clear_system_state();
+
+ if (scaled_ref_frame) {
+ xd->plane[AOM_PLANE_Y].pre[ref_idx] = backup_yv12;
+ }
+}
+
// Look at neighboring blocks and set a min and max partition size based on
// what they chose.
static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
@@ -3386,76 +3478,26 @@
// model with the correct data should give better performance.
assert(mi_size_wide[bsize] == mi_size_high[bsize]);
- AV1_COMMON *const cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *mbmi = xd->mi[0];
- mbmi->motion_mode = SIMPLE_TRANSLATION;
-
- mbmi->ref_frame[1] = NONE_FRAME;
- mbmi->sb_type = bsize;
-
- int pred_stride = 128;
DECLARE_ALIGNED(16, uint16_t, pred_buffer[MAX_SB_SQUARE]);
- uint8_t *const pred_buf = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
- ? CONVERT_TO_BYTEPTR(pred_buffer)
- : (uint8_t *)pred_buffer;
+ int pred_stride = 128;
// Perform a single motion search in Y_PLANE to make a prediction
const MV_REFERENCE_FRAME ref =
cpi->rc.is_src_frame_alt_ref ? ALTREF_FRAME : LAST_FRAME;
- YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref);
- const YV12_BUFFER_CONFIG *scaled_ref_frame =
- av1_get_scaled_ref_frame(cpi, ref);
- struct buf_2d backup_yv12;
- // ref_mv is in units of 1/8-pel whereas ref_mv_full is in units of pel
- MV ref_mv = { 0, 0 };
- MV ref_mv_full = { 0, 0 };
- const int step_param = 1;
- const MvLimits tmp_mv_limits = x->mv_limits;
- const SEARCH_METHODS search_methods = NSTEP;
- const int do_mesh_search = 0;
- const int sadpb = x->sadperbit16;
- int cost_list[5];
- int num_planes = 1;
- const int ref_idx = 0;
+ const int use_subpixel = 0;
+ const int num_planes = 1;
- if (scaled_ref_frame) {
- backup_yv12 = xd->plane[AOM_PLANE_Y].pre[ref_idx];
- av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL,
- num_planes);
- } else {
- av1_setup_pre_planes(xd, ref_idx, yv12, mi_row, mi_col,
- &cm->current_frame.frame_refs[ref - LAST_FRAME].sf,
- num_planes);
- }
-
- mbmi->ref_frame[0] = ref;
- av1_set_mv_search_range(&x->mv_limits, &ref_mv);
- av1_full_pixel_search(cpi, x, bsize, &ref_mv_full, step_param, search_methods,
- do_mesh_search, sadpb, cond_cost_list(cpi, cost_list),
- &ref_mv, INT_MAX, 1, mi_col * MI_SIZE, mi_row * MI_SIZE,
- 0);
- // Restore
- x->mv_limits = tmp_mv_limits;
-
- // Convert from units of pixel to 1/8-pixels
- x->best_mv.as_mv.row *= 8;
- x->best_mv.as_mv.col *= 8;
- mbmi->mv[0].as_mv = x->best_mv.as_mv;
-
- // Get a copy of the prediction output
- set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
+ uint8_t *const pred_buf = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
+ ? CONVERT_TO_BYTEPTR(pred_buffer)
+ : (uint8_t *)pred_buffer;
xd->plane[0].dst.buf = pred_buf;
xd->plane[0].dst.stride = pred_stride;
- av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, NULL, bsize);
- aom_clear_system_state();
+ simple_motion_search(cpi, x, mi_row, mi_col, bsize, ref, num_planes,
+ use_subpixel);
- if (scaled_ref_frame) {
- xd->plane[AOM_PLANE_Y].pre[ref_idx] = backup_yv12;
- }
-
- // Now that we have the frame, we can print features out
+ // Start getting the features
int f_idx = 0;
// Q_INDEX
@@ -3463,8 +3505,6 @@
features[f_idx++] = logf(1.0f + (float)(dc_q * dc_q) / 256.0f);
// VARIANCE
- av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes,
- BLOCK_128X128);
const uint8_t *src = x->plane[0].src.buf;
const int src_stride = x->plane[0].src.stride;
unsigned int sse = 0;