Merge "Make last frame source available in current frame encoding"

This commit is contained in:
Yunqing Wang 2014-04-01 15:54:13 -07:00 committed by Gerrit Code Review
commit 2b99fcbc58
4 changed files with 83 additions and 18 deletions

View File

@ -28,8 +28,8 @@ struct lookahead_ctx {
/* Return the buffer at the given absolute index and increment the index */
static struct lookahead_entry * pop(struct lookahead_ctx *ctx,
unsigned int *idx) {
static struct lookahead_entry *pop(struct lookahead_ctx *ctx,
unsigned int *idx) {
unsigned int index = *idx;
struct lookahead_entry *buf = ctx->buf + index;
@ -55,16 +55,19 @@ void vp9_lookahead_destroy(struct lookahead_ctx *ctx) {
}
struct lookahead_ctx * vp9_lookahead_init(unsigned int width,
unsigned int height,
unsigned int subsampling_x,
unsigned int subsampling_y,
unsigned int depth) {
struct lookahead_ctx *vp9_lookahead_init(unsigned int width,
unsigned int height,
unsigned int subsampling_x,
unsigned int subsampling_y,
unsigned int depth) {
struct lookahead_ctx *ctx = NULL;
// Clamp the lookahead queue depth
depth = clamp(depth, 1, MAX_LAG_BUFFERS);
// Allocate memory to keep previous source frames available.
depth += MAX_PRE_FRAMES;
// Allocate the lookahead structures
ctx = calloc(1, sizeof(*ctx));
if (ctx) {
@ -96,7 +99,7 @@ int vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
int mb_cols = (src->y_width + 15) >> 4;
#endif
if (ctx->sz + 1 > ctx->max_sz)
if (ctx->sz + 1 + MAX_PRE_FRAMES > ctx->max_sz)
return 1;
ctx->sz++;
buf = pop(ctx, &ctx->write_idx);
@ -159,11 +162,11 @@ int vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
}
struct lookahead_entry * vp9_lookahead_pop(struct lookahead_ctx *ctx,
int drain) {
struct lookahead_entry *vp9_lookahead_pop(struct lookahead_ctx *ctx,
int drain) {
struct lookahead_entry *buf = NULL;
if (ctx->sz && (drain || ctx->sz == ctx->max_sz)) {
if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
buf = pop(ctx, &ctx->read_idx);
ctx->sz--;
}
@ -171,16 +174,28 @@ struct lookahead_entry * vp9_lookahead_pop(struct lookahead_ctx *ctx,
}
struct lookahead_entry * vp9_lookahead_peek(struct lookahead_ctx *ctx,
int index) {
struct lookahead_entry *vp9_lookahead_peek(struct lookahead_ctx *ctx,
int index) {
struct lookahead_entry *buf = NULL;
if (index < (int)ctx->sz) {
index += ctx->read_idx;
if (index >= (int)ctx->max_sz)
index -= ctx->max_sz;
buf = ctx->buf + index;
if (index >= 0) {
// Forward peek
if (index < (int)ctx->sz) {
index += ctx->read_idx;
if (index >= (int)ctx->max_sz)
index -= ctx->max_sz;
buf = ctx->buf + index;
}
} else if (index < 0) {
// Backward peek
if (-index <= MAX_PRE_FRAMES) {
index += ctx->read_idx;
if (index < 0)
index += ctx->max_sz;
buf = ctx->buf + index;
}
}
return buf;
}

View File

@ -20,6 +20,9 @@ extern "C" {
#define MAX_LAG_BUFFERS 25
// The max of past frames we want to keep in the queue.
#define MAX_PRE_FRAMES 1
struct lookahead_entry {
YV12_BUFFER_CONFIG img;
int64_t ts_start;

View File

@ -189,6 +189,7 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
vp9_free_frame_buffer(&cpi->last_frame_uf);
vp9_free_frame_buffer(&cpi->scaled_source);
vp9_free_frame_buffer(&cpi->scaled_last_source);
vp9_free_frame_buffer(&cpi->alt_ref_buffer);
vp9_lookahead_destroy(cpi->lookahead);
@ -595,6 +596,13 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) {
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate scaled source buffer");
if (vp9_alloc_frame_buffer(&cpi->scaled_last_source,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9_ENC_BORDER_IN_PIXELS))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate scaled last source buffer");
vpx_free(cpi->tok);
{
@ -636,6 +644,13 @@ static void update_frame_size(VP9_COMP *cpi) {
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to reallocate scaled source buffer");
if (vp9_realloc_frame_buffer(&cpi->scaled_last_source,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to reallocate scaled last source buffer");
{
int y_stride = cpi->scaled_source.y_stride;
@ -2554,6 +2569,19 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
} else {
cpi->Source = cpi->un_scaled_source;
}
// Scale the last source buffer, if required.
if (cpi->unscaled_last_source != NULL) {
if (cm->mi_cols * MI_SIZE != cpi->unscaled_last_source->y_width ||
cm->mi_rows * MI_SIZE != cpi->unscaled_last_source->y_height) {
scale_and_extend_frame_nonnormative(cpi->unscaled_last_source,
&cpi->scaled_last_source);
cpi->Last_Source = &cpi->scaled_last_source;
} else {
cpi->Last_Source = cpi->unscaled_last_source;
}
}
vp9_scale_references(cpi);
vp9_clear_system_state();
@ -2985,6 +3013,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
vpx_usec_timer_start(&cmptimer);
cpi->source = NULL;
cpi->last_source = NULL;
set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV);
@ -3047,6 +3076,13 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
#if CONFIG_MULTIPLE_ARF
int i;
#endif
// Get last frame source.
if (cm->current_video_frame > 0) {
if ((cpi->last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL)
return -1;
}
if ((cpi->source = vp9_lookahead_pop(cpi->lookahead, flush))) {
cm->show_frame = 1;
cm->intra_only = 0;
@ -3085,6 +3121,13 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if (cpi->source) {
cpi->un_scaled_source = cpi->Source = force_src_buffer ? force_src_buffer
: &cpi->source->img;
if (cpi->last_source != NULL) {
cpi->unscaled_last_source = &cpi->last_source->img;
} else {
cpi->unscaled_last_source = NULL;
}
*time_stamp = cpi->source->ts_start;
*time_end = cpi->source->ts_end;
*frame_flags = cpi->source->flags;

View File

@ -307,10 +307,14 @@ typedef struct VP9_COMP {
#else
struct lookahead_entry *alt_ref_source;
#endif
struct lookahead_entry *last_source;
YV12_BUFFER_CONFIG *Source;
YV12_BUFFER_CONFIG *Last_Source; // NULL for first frame and alt_ref frames
YV12_BUFFER_CONFIG *un_scaled_source;
YV12_BUFFER_CONFIG scaled_source;
YV12_BUFFER_CONFIG *unscaled_last_source;
YV12_BUFFER_CONFIG scaled_last_source;
int key_frame_frequency;