Add motion search skipping in first pass

This change added a motion search skipping mechanism similar
to what we did in second pass. For a macroblock that is very
similar to the macroblock at same location on last frame,
we can set its mv to be zero, and skip motion search. This
improves first-pass performance for slide shows and video
conferencing clips with a slight PSNR loss.

Change-Id: Ic73f9ef5604270ddd6d433170091d20361dfe229
This commit is contained in:
Yunqing Wang
2012-03-14 10:03:39 -04:00
parent 6b7cf3077d
commit 6a819ce4fe
6 changed files with 73 additions and 21 deletions

View File

@@ -387,7 +387,11 @@ void vp8_end_first_pass(VP8_COMP *cpi)
output_stats(cpi, cpi->output_pkt_list, &cpi->twopass.total_stats);
}
static void zz_motion_search( VP8_COMP *cpi, MACROBLOCK * x, YV12_BUFFER_CONFIG * recon_buffer, int * best_motion_err, int recon_yoffset )
static void zz_motion_search( VP8_COMP *cpi, MACROBLOCK * x,
YV12_BUFFER_CONFIG * raw_buffer,
int * raw_motion_err,
YV12_BUFFER_CONFIG * recon_buffer,
int * best_motion_err, int recon_yoffset)
{
MACROBLOCKD * const xd = & x->e_mbd;
BLOCK *b = &x->block[0];
@@ -395,15 +399,22 @@ static void zz_motion_search( VP8_COMP *cpi, MACROBLOCK * x, YV12_BUFFER_CONFIG
unsigned char *src_ptr = (*(b->base_src) + b->src);
int src_stride = b->src_stride;
unsigned char *raw_ptr;
int raw_stride = raw_buffer->y_stride;
unsigned char *ref_ptr;
int ref_stride = x->e_mbd.pre.y_stride;
// Set up pointers for this macro block raw buffer
raw_ptr = (unsigned char *)(raw_buffer->y_buffer + recon_yoffset
+ d->offset);
vp8_mse16x16 ( src_ptr, src_stride, raw_ptr, raw_stride,
(unsigned int *)(raw_motion_err));
// Set up pointers for this macro block recon buffer
xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;
ref_ptr = (unsigned char *)(xd->pre.y_buffer + d->offset );
vp8_mse16x16 ( src_ptr, src_stride, ref_ptr, ref_stride, (unsigned int *)(best_motion_err));
vp8_mse16x16 ( src_ptr, src_stride, ref_ptr, ref_stride,
(unsigned int *)(best_motion_err));
}
static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
@@ -595,12 +606,18 @@ void vp8_first_pass(VP8_COMP *cpi)
MV tmp_mv = {0, 0};
int tmp_err;
int motion_error = INT_MAX;
int raw_motion_error = INT_MAX;
// Simple 0,0 motion with no mv overhead
zz_motion_search( cpi, x, lst_yv12, &motion_error, recon_yoffset );
zz_motion_search( cpi, x, cpi->last_frame_unscaled_source,
&raw_motion_error, lst_yv12, &motion_error,
recon_yoffset );
d->bmi.mv.as_mv.row = 0;
d->bmi.mv.as_mv.col = 0;
if (raw_motion_error < cpi->oxcf.encode_breakout)
goto skip_motion_search;
// 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,
@@ -648,6 +665,7 @@ void vp8_first_pass(VP8_COMP *cpi)
xd->pre.v_buffer = lst_yv12->v_buffer + recon_uvoffset;
}
skip_motion_search:
/* Intra assumed best */
best_ref_mv.as_int = 0;