Commit 096d8ace authored by Hui Su's avatar Hui Su Committed by Gerrit Code Review

Merge "Extra round of subpel MV search around second best full-pixel MV" into nextgenv2

parents 3c13124e 9a470241
...@@ -660,7 +660,7 @@ specialize qw/vp10_full_search_sad sse3 sse4_1/; ...@@ -660,7 +660,7 @@ specialize qw/vp10_full_search_sad sse3 sse4_1/;
$vp10_full_search_sad_sse3=vp10_full_search_sadx3; $vp10_full_search_sad_sse3=vp10_full_search_sadx3;
$vp10_full_search_sad_sse4_1=vp10_full_search_sadx8; $vp10_full_search_sad_sse4_1=vp10_full_search_sadx8;
add_proto qw/int vp10_diamond_search_sad/, "const struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp10_variance_vtable *fn_ptr, const struct mv *center_mv"; add_proto qw/int vp10_diamond_search_sad/, "struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp10_variance_vtable *fn_ptr, const struct mv *center_mv";
specialize qw/vp10_diamond_search_sad/; specialize qw/vp10_diamond_search_sad/;
add_proto qw/int vp10_full_range_search/, "const struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp10_variance_vtable *fn_ptr, const struct mv *center_mv"; add_proto qw/int vp10_full_range_search/, "const struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp10_variance_vtable *fn_ptr, const struct mv *center_mv";
......
...@@ -164,6 +164,8 @@ struct macroblock { ...@@ -164,6 +164,8 @@ struct macroblock {
// Store the best motion vector during motion search // Store the best motion vector during motion search
int_mv best_mv; int_mv best_mv;
// Store the second best motion vector during full-pixel motion search
int_mv second_best_mv;
// Strong color activity detection. Used in RTC coding mode to enhance // Strong color activity detection. Used in RTC coding mode to enhance
// the visual quality at the boundary of moving color objects. // the visual quality at the boundary of moving color objects.
......
...@@ -1479,7 +1479,7 @@ static int fast_dia_search(MACROBLOCK *x, ...@@ -1479,7 +1479,7 @@ static int fast_dia_search(MACROBLOCK *x,
// Exhuastive motion search around a given centre position with a given // Exhuastive motion search around a given centre position with a given
// step size. // step size.
static int exhuastive_mesh_search(const MACROBLOCK *x, static int exhuastive_mesh_search(MACROBLOCK *x,
MV *ref_mv, MV *best_mv, MV *ref_mv, MV *best_mv,
int range, int step, int sad_per_bit, int range, int step, int sad_per_bit,
const vp10_variance_fn_ptr_t *fn_ptr, const vp10_variance_fn_ptr_t *fn_ptr,
...@@ -1517,6 +1517,7 @@ static int exhuastive_mesh_search(const MACROBLOCK *x, ...@@ -1517,6 +1517,7 @@ static int exhuastive_mesh_search(const MACROBLOCK *x,
sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit); sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
if (sad < best_sad) { if (sad < best_sad) {
best_sad = sad; best_sad = sad;
x->second_best_mv.as_mv = *best_mv;
*best_mv = mv; *best_mv = mv;
} }
} }
...@@ -1539,6 +1540,7 @@ static int exhuastive_mesh_search(const MACROBLOCK *x, ...@@ -1539,6 +1540,7 @@ static int exhuastive_mesh_search(const MACROBLOCK *x,
mvsad_err_cost(x, &mv, ref_mv, sad_per_bit); mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
if (sad < best_sad) { if (sad < best_sad) {
best_sad = sad; best_sad = sad;
x->second_best_mv.as_mv = *best_mv;
*best_mv = mv; *best_mv = mv;
} }
} }
...@@ -1552,6 +1554,7 @@ static int exhuastive_mesh_search(const MACROBLOCK *x, ...@@ -1552,6 +1554,7 @@ static int exhuastive_mesh_search(const MACROBLOCK *x,
sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit); sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
if (sad < best_sad) { if (sad < best_sad) {
best_sad = sad; best_sad = sad;
x->second_best_mv.as_mv = *best_mv;
*best_mv = mv; *best_mv = mv;
} }
} }
...@@ -1564,7 +1567,7 @@ static int exhuastive_mesh_search(const MACROBLOCK *x, ...@@ -1564,7 +1567,7 @@ static int exhuastive_mesh_search(const MACROBLOCK *x,
return best_sad; return best_sad;
} }
int vp10_diamond_search_sad_c(const MACROBLOCK *x, int vp10_diamond_search_sad_c(MACROBLOCK *x,
const search_site_config *cfg, const search_site_config *cfg,
MV *ref_mv, MV *best_mv, int search_param, MV *ref_mv, MV *best_mv, int search_param,
int sad_per_bit, int *num00, int sad_per_bit, int *num00,
...@@ -1673,6 +1676,7 @@ int vp10_diamond_search_sad_c(const MACROBLOCK *x, ...@@ -1673,6 +1676,7 @@ int vp10_diamond_search_sad_c(const MACROBLOCK *x,
} }
} }
if (best_site != last_site) { if (best_site != last_site) {
x->second_best_mv.as_mv = *best_mv;
best_mv->row += ss[best_site].mv.row; best_mv->row += ss[best_site].mv.row;
best_mv->col += ss[best_site].mv.col; best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset; best_address += ss[best_site].offset;
...@@ -2234,11 +2238,11 @@ int vp10_full_search_sadx8(const MACROBLOCK *x, const MV *ref_mv, ...@@ -2234,11 +2238,11 @@ int vp10_full_search_sadx8(const MACROBLOCK *x, const MV *ref_mv,
return best_sad; return best_sad;
} }
int vp10_refining_search_sad(const MACROBLOCK *x, int vp10_refining_search_sad(MACROBLOCK *x,
MV *ref_mv, int error_per_bit, MV *ref_mv, int error_per_bit,
int search_range, int search_range,
const vp10_variance_fn_ptr_t *fn_ptr, const vp10_variance_fn_ptr_t *fn_ptr,
const MV *center_mv) { const MV *center_mv) {
const MACROBLOCKD *const xd = &x->e_mbd; const MACROBLOCKD *const xd = &x->e_mbd;
const MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}}; const MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}};
const struct buf_2d *const what = &x->plane[0].src; const struct buf_2d *const what = &x->plane[0].src;
...@@ -2302,6 +2306,7 @@ int vp10_refining_search_sad(const MACROBLOCK *x, ...@@ -2302,6 +2306,7 @@ int vp10_refining_search_sad(const MACROBLOCK *x,
if (best_site == -1) { if (best_site == -1) {
break; break;
} else { } else {
x->second_best_mv.as_mv = *ref_mv;
ref_mv->row += neighbors[best_site].row; ref_mv->row += neighbors[best_site].row;
ref_mv->col += neighbors[best_site].col; ref_mv->col += neighbors[best_site].col;
best_address = get_buf_from_mv(in_what, ref_mv); best_address = get_buf_from_mv(in_what, ref_mv);
......
...@@ -66,11 +66,11 @@ struct SPEED_FEATURES; ...@@ -66,11 +66,11 @@ struct SPEED_FEATURES;
int vp10_init_search_range(int size); int vp10_init_search_range(int size);
int vp10_refining_search_sad(const struct macroblock *x, int vp10_refining_search_sad(struct macroblock *x,
struct mv *ref_mv, struct mv *ref_mv,
int sad_per_bit, int distance, int sad_per_bit, int distance,
const vp10_variance_fn_ptr_t *fn_ptr, const vp10_variance_fn_ptr_t *fn_ptr,
const struct mv *center_mv); const struct mv *center_mv);
// Runs sequence of diamond searches in smaller steps for RD. // Runs sequence of diamond searches in smaller steps for RD.
int vp10_full_pixel_diamond(const struct VP10_COMP *cpi, MACROBLOCK *x, int vp10_full_pixel_diamond(const struct VP10_COMP *cpi, MACROBLOCK *x,
...@@ -122,7 +122,7 @@ typedef int (*vp10_full_search_fn_t)(const MACROBLOCK *x, ...@@ -122,7 +122,7 @@ typedef int (*vp10_full_search_fn_t)(const MACROBLOCK *x,
const vp10_variance_fn_ptr_t *fn_ptr, const vp10_variance_fn_ptr_t *fn_ptr,
const MV *center_mv, MV *best_mv); const MV *center_mv, MV *best_mv);
typedef int (*vp10_diamond_search_fn_t)(const MACROBLOCK *x, typedef int (*vp10_diamond_search_fn_t)(MACROBLOCK *x,
const search_site_config *cfg, const search_site_config *cfg,
MV *ref_mv, MV *best_mv, MV *ref_mv, MV *best_mv,
int search_param, int sad_per_bit, int search_param, int sad_per_bit,
......
...@@ -5239,6 +5239,8 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -5239,6 +5239,8 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
vp10_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv); vp10_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
#if CONFIG_REF_MV #if CONFIG_REF_MV
vp10_set_mvcost(x, mbmi->ref_frame[0]); vp10_set_mvcost(x, mbmi->ref_frame[0]);
#endif #endif
...@@ -5250,6 +5252,10 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -5250,6 +5252,10 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
if (bestsme < INT_MAX) { if (bestsme < INT_MAX) {
int distortion; int distortion;
if (cpi->sf.use_upsampled_references) { if (cpi->sf.use_upsampled_references) {
int best_mv_var;
const int try_second =
x->second_best_mv.as_int != INVALID_MV &&
x->second_best_mv.as_int != x->best_mv.as_int;
const int pw = 4 * num_4x4_blocks_wide_lookup[bsize]; const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
const int ph = 4 * num_4x4_blocks_high_lookup[bsize]; const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
// Use up-sampled reference frames. // Use up-sampled reference frames.
...@@ -5271,17 +5277,52 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -5271,17 +5277,52 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
&pd->pre[0].buf[(vp10_raster_block_offset(BLOCK_8X8, i, &pd->pre[0].buf[(vp10_raster_block_offset(BLOCK_8X8, i,
pd->pre[0].stride)) << 3]; pd->pre[0].stride)) << 3];
cpi->find_fractional_mv_step( best_mv_var =
x, &bsi->ref_mv[0]->as_mv, cpi->find_fractional_mv_step(x, &bsi->ref_mv[0]->as_mv,
cm->allow_high_precision_mv, cm->allow_high_precision_mv,
x->errorperbit, &cpi->fn_ptr[bsize], x->errorperbit,
cpi->sf.mv.subpel_force_stop, &cpi->fn_ptr[bsize],
cpi->sf.mv.subpel_iters_per_step, cpi->sf.mv.subpel_force_stop,
cond_cost_list(cpi, cost_list), cpi->sf.mv.subpel_iters_per_step,
x->nmvjointcost, x->mvcost, cond_cost_list(cpi, cost_list),
&distortion, x->nmvjointcost, x->mvcost,
&x->pred_sse[mbmi->ref_frame[0]], &distortion,
NULL, pw, ph, 1); &x->pred_sse[mbmi->ref_frame[0]],
NULL, pw, ph, 1);
if (try_second) {
int this_var;
MV best_mv = x->best_mv.as_mv;
const MV ref_mv = bsi->ref_mv[0]->as_mv;
const int minc = VPXMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
const int maxc = VPXMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
const int minr = VPXMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
const int maxr = VPXMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
x->best_mv = x->second_best_mv;
if (x->best_mv.as_mv.row * 8 <= maxr &&
x->best_mv.as_mv.row * 8 >= minr &&
x->best_mv.as_mv.col * 8 <= maxc &&
x->best_mv.as_mv.col * 8 >= minc) {
this_var =
cpi->find_fractional_mv_step(x, &bsi->ref_mv[0]->as_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->nmvjointcost, x->mvcost,
&distortion,
&x->pred_sse[mbmi->
ref_frame[0]],
NULL, pw, ph, 1);
if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
x->best_mv.as_mv = best_mv;
}
}
// Restore the reference frames. // Restore the reference frames.
pd->pre[0] = backup_pred; pd->pre[0] = backup_pred;
...@@ -5983,6 +6024,8 @@ static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -5983,6 +6024,8 @@ static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
mvp_full.col >>= 3; mvp_full.col >>= 3;
mvp_full.row >>= 3; mvp_full.row >>= 3;
x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
bestsme = vp10_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb, bestsme = vp10_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
cond_cost_list(cpi, cost_list), cond_cost_list(cpi, cost_list),
&ref_mv, INT_MAX, 1); &ref_mv, INT_MAX, 1);
...@@ -5995,6 +6038,10 @@ static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -5995,6 +6038,10 @@ static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
if (bestsme < INT_MAX) { if (bestsme < INT_MAX) {
int dis; /* TODO: use dis in distortion calculation later. */ int dis; /* TODO: use dis in distortion calculation later. */
if (cpi->sf.use_upsampled_references) { if (cpi->sf.use_upsampled_references) {
int best_mv_var;
const int try_second =
x->second_best_mv.as_int != INVALID_MV &&
x->second_best_mv.as_int != x->best_mv.as_int;
const int pw = 4 * num_4x4_blocks_wide_lookup[bsize]; const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
const int ph = 4 * num_4x4_blocks_high_lookup[bsize]; const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
// Use up-sampled reference frames. // Use up-sampled reference frames.
...@@ -6009,16 +6056,46 @@ static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x, ...@@ -6009,16 +6056,46 @@ static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3),
NULL, pd->subsampling_x, pd->subsampling_y); NULL, pd->subsampling_x, pd->subsampling_y);
bestsme = cpi->find_fractional_mv_step(x, &ref_mv, best_mv_var =
cm->allow_high_precision_mv, cpi->find_fractional_mv_step(x, &ref_mv,
x->errorperbit, cm->allow_high_precision_mv,
&cpi->fn_ptr[bsize], x->errorperbit,
cpi->sf.mv.subpel_force_stop, &cpi->fn_ptr[bsize],
cpi->sf.mv.subpel_iters_per_step, cpi->sf.mv.subpel_force_stop,
cond_cost_list(cpi, cost_list), cpi->sf.mv.subpel_iters_per_step,
x->nmvjointcost, x->mvcost, cond_cost_list(cpi, cost_list),
&dis, &x->pred_sse[ref], NULL, x->nmvjointcost, x->mvcost,
pw, ph, 1); &dis, &x->pred_sse[ref], NULL,
pw, ph, 1);
if (try_second) {
const int minc = VPXMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
const int maxc = VPXMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
const int minr = VPXMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
const int maxr = VPXMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
int this_var;
MV best_mv = x->best_mv.as_mv;
x->best_mv = x->second_best_mv;
if (x->best_mv.as_mv.row * 8 <= maxr &&
x->best_mv.as_mv.row * 8 >= minr &&
x->best_mv.as_mv.col * 8 <= maxc &&
x->best_mv.as_mv.col * 8 >= minc) {
this_var =
cpi->find_fractional_mv_step(x, &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->nmvjointcost, x->mvcost,
&dis, &x->pred_sse[ref], NULL,
pw, ph, 1);
if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
x->best_mv.as_mv = best_mv;
}
}
// Restore the reference frames. // Restore the reference frames.
pd->pre[ref_idx] = backup_pred; pd->pre[ref_idx] = backup_pred;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment