skip the un-necessary motion search in the first pass
This patch allows the VP9 encoder to skip the un-necessary motion search in the first pass. It computes the motion error of 0,0 motion using the last source frame as the reference, and skips the further motion search if this error is small. Borg test shows overall the patch gives PSNR gain (derf -0.001%, yt 0.341%, hd 0.282%). Individual clips may have PSNR gain or loss. The best PSNR performance is 7.347% and the worst is -0.662%. The first pass encoding speedup for slideshow clips is over 30%. Change-Id: I4cac4dbd911f277ee858e161f3ca652c771344fe
This commit is contained in:
Родитель
95fb9008f8
Коммит
cdc954fdc8
|
@ -594,8 +594,9 @@ void vp9_first_pass(VP9_COMP *cpi) {
|
|||
|
||||
// Other than for the first frame do a motion search.
|
||||
if (cm->current_video_frame > 0) {
|
||||
int tmp_err, motion_error;
|
||||
int tmp_err, motion_error, raw_motion_error;
|
||||
int_mv mv, tmp_mv;
|
||||
struct buf_2d unscaled_last_source_buf_2d;
|
||||
|
||||
xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
|
||||
motion_error = get_prediction_error(bsize, &x->plane[0].src,
|
||||
|
@ -603,6 +604,18 @@ void vp9_first_pass(VP9_COMP *cpi) {
|
|||
// Assume 0,0 motion with no mv overhead.
|
||||
mv.as_int = tmp_mv.as_int = 0;
|
||||
|
||||
// Compute the motion error of the 0,0 motion using the last source
|
||||
// frame as the reference. Skip the further motion search on
|
||||
// reconstructed frame if this error is small.
|
||||
unscaled_last_source_buf_2d.buf =
|
||||
cpi->unscaled_last_source->y_buffer + recon_yoffset;
|
||||
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);
|
||||
|
||||
// TODO(pengchong): Replace the hard-coded threshold
|
||||
if (raw_motion_error > 25) {
|
||||
// Test last reference frame using the previous best mv as the
|
||||
// starting point (best reference) for the search.
|
||||
first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv,
|
||||
|
@ -612,12 +625,11 @@ void vp9_first_pass(VP9_COMP *cpi) {
|
|||
motion_error = (int)(motion_error * error_weight);
|
||||
}
|
||||
|
||||
// If the current best reference mv is not centered on 0,0 then do a 0,0
|
||||
// based search as well.
|
||||
// If the current best reference mv is not centered on 0,0 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);
|
||||
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);
|
||||
|
@ -664,6 +676,10 @@ void vp9_first_pass(VP9_COMP *cpi) {
|
|||
} else {
|
||||
sr_coded_error += motion_error;
|
||||
}
|
||||
} else {
|
||||
sr_coded_error += motion_error;
|
||||
}
|
||||
|
||||
// Start by assuming that intra mode is best.
|
||||
best_ref_mv.as_int = 0;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче