Merge "skip un-neccessary motion search in the first pass"

This commit is contained in:
Yunqing Wang 2014-06-12 09:43:47 -07:00 committed by Gerrit Code Review
commit f9d1e66f6a

@ -597,73 +597,91 @@ void vp9_first_pass(VP9_COMP *cpi) {
if (cm->current_video_frame > 0) { if (cm->current_video_frame > 0) {
int tmp_err, motion_error; int tmp_err, motion_error;
int_mv mv, tmp_mv; int_mv mv, tmp_mv;
int raw_motion_error;
struct buf_2d unscaled_last_source_buf_2d;
xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset; xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
motion_error = get_prediction_error(bsize, &x->plane[0].src, motion_error = get_prediction_error(bsize, &x->plane[0].src,
&xd->plane[0].pre[0]); &xd->plane[0].pre[0]);
// Assume 0,0 motion with no mv overhead.
mv.as_int = tmp_mv.as_int = 0;
// Test last reference frame using the previous best mv as the // compute the motion error of the zero motion vector using the last
// starting point (best reference) for the search. // source frame as the reference
first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv, // skip the further motion search on reconstructed frame
&motion_error); // if this error is small
if (cpi->oxcf.aq_mode == VARIANCE_AQ) { unscaled_last_source_buf_2d.buf = cpi->unscaled_last_source->y_buffer
vp9_clear_system_state(); + recon_yoffset;
motion_error = (int)(motion_error * error_weight); unscaled_last_source_buf_2d.stride =
} cpi->unscaled_last_source->y_stride;
raw_motion_error = get_prediction_error(bsize, &x->plane[0].src,
&unscaled_last_source_buf_2d);
// If the current best reference mv is not centered on 0,0 then do a 0,0 // TODO(pengchong): Replace the hard-coded threshold
// based search as well. if (raw_motion_error > 25) {
if (best_ref_mv.as_int) {
tmp_err = INT_MAX;
first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
&tmp_err);
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_clear_system_state();
tmp_err = (int)(tmp_err * error_weight);
}
if (tmp_err < motion_error) {
motion_error = tmp_err;
mv.as_int = tmp_mv.as_int;
}
}
// Search in an older reference frame.
if (cm->current_video_frame > 1 && gld_yv12 != NULL) {
// Assume 0,0 motion with no mv overhead. // Assume 0,0 motion with no mv overhead.
int gf_motion_error; mv.as_int = tmp_mv.as_int = 0;
xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset; // Test last reference frame using the previous best mv as the
gf_motion_error = get_prediction_error(bsize, &x->plane[0].src, // starting point (best reference) for the search.
&xd->plane[0].pre[0]); first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv,
&motion_error);
first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
&gf_motion_error);
if (cpi->oxcf.aq_mode == VARIANCE_AQ) { if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_clear_system_state(); vp9_clear_system_state();
gf_motion_error = (int)(gf_motion_error * error_weight); motion_error = (int)(motion_error * error_weight);
} }
if (gf_motion_error < motion_error && gf_motion_error < this_error) // If the current best reference mv is not centered on 0,0
++second_ref_count; // then do a 0,0
// based search as well.
if (best_ref_mv.as_int) {
tmp_err = INT_MAX;
first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
&tmp_err);
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_clear_system_state();
tmp_err = (int)(tmp_err * error_weight);
}
// Reset to last frame as reference buffer. if (tmp_err < motion_error) {
xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset; motion_error = tmp_err;
xd->plane[1].pre[0].buf = first_ref_buf->u_buffer + recon_uvoffset; mv.as_int = tmp_mv.as_int;
xd->plane[2].pre[0].buf = first_ref_buf->v_buffer + recon_uvoffset; }
}
// In accumulating a score for the older reference frame take the // Search in an older reference frame.
// best of the motion predicted score and the intra coded error if (cm->current_video_frame > 1 && gld_yv12 != NULL) {
// (just as will be done for) accumulation of "coded_error" for // Assume 0,0 motion with no mv overhead.
// the last frame. int gf_motion_error;
if (gf_motion_error < this_error)
sr_coded_error += gf_motion_error; xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset;
else gf_motion_error = get_prediction_error(bsize, &x->plane[0].src,
sr_coded_error += this_error; &xd->plane[0].pre[0]);
} else {
sr_coded_error += motion_error; first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
&gf_motion_error);
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_clear_system_state();
gf_motion_error = (int)(gf_motion_error * error_weight);
}
if (gf_motion_error < motion_error && gf_motion_error < this_error)
++second_ref_count;
// Reset to last frame as reference buffer.
xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
xd->plane[1].pre[0].buf = first_ref_buf->u_buffer + recon_uvoffset;
xd->plane[2].pre[0].buf = first_ref_buf->v_buffer + recon_uvoffset;
// In accumulating a score for the older reference frame take the
// best of the motion predicted score and the intra coded error
// (just as will be done for) accumulation of "coded_error" for
// the last frame.
if (gf_motion_error < this_error)
sr_coded_error += gf_motion_error;
else
sr_coded_error += this_error;
} else {
sr_coded_error += motion_error;
}
} }
// Start by assuming that intra mode is best. // Start by assuming that intra mode is best.
best_ref_mv.as_int = 0; best_ref_mv.as_int = 0;