Merge "Make last frame source available in current frame encoding"
This commit is contained in:
commit
2b99fcbc58
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user