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];
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,
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,
xd->pre.v_buffer = lst_yv12->v_buffer + recon_uvoffset;
}
+skip_motion_search:
/* Intra assumed best */
best_ref_mv.as_int = 0;
else if(depth > MAX_LAG_BUFFERS)
depth = MAX_LAG_BUFFERS;
+ /* Keep last frame in lookahead buffer by increasing depth by 1.*/
+ depth += 1;
+
/* Align the buffer dimensions */
width = (width + 15) & ~15;
height = (height + 15) & ~15;
int mb_rows = (src->y_height + 15) >> 4;
int mb_cols = (src->y_width + 15) >> 4;
- if(ctx->sz + 1 > ctx->max_sz)
+ if(ctx->sz + 2 > ctx->max_sz)
return 1;
ctx->sz++;
buf = pop(ctx, &ctx->write_idx);
{
struct lookahead_entry* buf = NULL;
- if(ctx->sz && (drain || ctx->sz == ctx->max_sz))
+ if(ctx->sz && (drain || ctx->sz == ctx->max_sz - 1))
{
buf = pop(ctx, &ctx->read_idx);
ctx->sz--;
struct lookahead_entry*
vp8_lookahead_peek(struct lookahead_ctx *ctx,
- unsigned int index)
+ unsigned int index,
+ int direction)
{
struct lookahead_entry* buf = NULL;
- assert(index < ctx->max_sz);
- if(index < ctx->sz)
+ if (direction == PEEK_FORWARD)
+ {
+ assert(index < ctx->max_sz - 1);
+ if(index < ctx->sz)
+ {
+ index += ctx->read_idx;
+ if(index >= ctx->max_sz)
+ index -= ctx->max_sz;
+ buf = ctx->buf + index;
+ }
+ }
+ else if (direction == PEEK_BACKWARD)
{
- index += ctx->read_idx;
- if(index >= ctx->max_sz)
- index -= ctx->max_sz;
+ assert(index == 1);
+
+ if(ctx->read_idx == 0)
+ index = ctx->max_sz - 1;
+ else
+ index = ctx->read_idx - index;
buf = ctx->buf + index;
}
+
return buf;
}
int drain);
+#define PEEK_FORWARD 1
+#define PEEK_BACKWARD -1
/**\brief Get a future source buffer to encode
*
* \param[in] ctx Pointer to the lookahead context
*/
struct lookahead_entry*
vp8_lookahead_peek(struct lookahead_ctx *ctx,
- unsigned int index);
+ unsigned int index,
+ int direction);
/**\brief Get the number of frames currently in the lookahead queue
width, height, VP8BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate scaled source buffer");
-
-
- vpx_free(cpi->tok);
-
{
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
unsigned int tokens = 8 * 24 * 16; /* one MB for each thread */
(void) frame_flags;
vp8_set_quantizer(cpi, 26);
- scale_and_extend_source(cpi->un_scaled_source, cpi);
vp8_first_pass(cpi);
}
#endif
cpi->source_alt_ref_pending)
{
if ((cpi->source = vp8_lookahead_peek(cpi->lookahead,
- cpi->frames_till_gf_update_due)))
+ cpi->frames_till_gf_update_due,
+ PEEK_FORWARD)))
{
cpi->alt_ref_source = cpi->source;
if (cpi->oxcf.arnr_max_frames > 0)
if (!cpi->source)
{
+ /* Read last frame source if we are encoding first pass. */
+ if (cpi->pass == 1 && cm->current_video_frame > 0)
+ {
+ if((cpi->last_source = vp8_lookahead_peek(cpi->lookahead, 1,
+ PEEK_BACKWARD)) == NULL)
+ return -1;
+ }
+
+
if ((cpi->source = vp8_lookahead_pop(cpi->lookahead, flush)))
{
cm->show_frame = 1;
*time_stamp = cpi->source->ts_start;
*time_end = cpi->source->ts_end;
*frame_flags = cpi->source->flags;
+
+ if (cpi->pass == 1 && cm->current_video_frame > 0)
+ {
+ cpi->last_frame_unscaled_source = &cpi->last_source->img;
+ }
}
else
{
struct lookahead_ctx *lookahead;
struct lookahead_entry *source;
struct lookahead_entry *alt_ref_source;
+ struct lookahead_entry *last_source;
YV12_BUFFER_CONFIG *Source;
YV12_BUFFER_CONFIG *un_scaled_source;
YV12_BUFFER_CONFIG scaled_source;
+ YV12_BUFFER_CONFIG *last_frame_unscaled_source;
int source_alt_ref_pending; // frame in src_buffers has been identified to be encoded as an alt ref
int source_alt_ref_active; // an alt ref frame has been encoded and is usable
{
int which_buffer = start_frame - frame;
struct lookahead_entry* buf = vp8_lookahead_peek(cpi->lookahead,
- which_buffer);
+ which_buffer,
+ PEEK_FORWARD);
cpi->frames[frames_to_blur-1-frame] = &buf->img;
}