ref: f01c769dc6589790325b297be2d402d555811f5a
parent: d4657a7efb368acd29d6f3ac3b92fb020b72e0a9
author: Marco <[email protected]>
date: Fri Jul 10 06:28:51 EDT 2015
Dynamic resize for real-time: reference scaling. Avoid scaling the references if they have already been scaled. Change only affects 1 pass non-svc mode for now. Change-Id: I204f4079c026cba7adce7a7f855d072f6139ccec
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2803,43 +2803,65 @@
#if CONFIG_VP9_HIGHBITDEPTH
if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
- const int new_fb = get_free_fb(cm);
RefCntBuffer *new_fb_ptr = NULL;
- if (cm->new_fb_idx == INVALID_IDX)
+ int force_scaling = 0;
+ int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
+ if (new_fb == INVALID_IDX) {
+ new_fb = get_free_fb(cm);
+ force_scaling = 1;
+ }
+ if (new_fb == INVALID_IDX)
return;
new_fb_ptr = &pool->frame_bufs[new_fb];
- cm->cur_frame = &pool->frame_bufs[new_fb];
- vp9_realloc_frame_buffer(&pool->frame_bufs[new_fb].buf,
- cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
- cm->use_highbitdepth,
- VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
- NULL, NULL, NULL);
- scale_and_extend_frame(ref, &new_fb_ptr->buf, (int)cm->bit_depth);
+ if (force_scaling ||
+ new_fb_ptr->buf.y_crop_width != cm->width ||
+ new_fb_ptr->buf.y_crop_height != cm->height) {
+ vp9_realloc_frame_buffer(&new_fb_ptr->buf,
+ cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
+ cm->use_highbitdepth,
+ VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
+ NULL, NULL, NULL);
+ scale_and_extend_frame(ref, &new_fb_ptr->buf, (int)cm->bit_depth);
+ cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
+ alloc_frame_mvs(cm, new_fb);
+ }
#else
if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
- const int new_fb = get_free_fb(cm);
RefCntBuffer *new_fb_ptr = NULL;
- if (cm->new_fb_idx == INVALID_IDX)
+ int force_scaling = 0;
+ int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
+ if (new_fb == INVALID_IDX) {
+ new_fb = get_free_fb(cm);
+ force_scaling = 1;
+ }
+ if (new_fb == INVALID_IDX)
return;
new_fb_ptr = &pool->frame_bufs[new_fb];
- vp9_realloc_frame_buffer(&new_fb_ptr->buf,
- cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
- VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
- NULL, NULL, NULL);
- scale_and_extend_frame(ref, &new_fb_ptr->buf);
+ if (force_scaling ||
+ new_fb_ptr->buf.y_crop_width != cm->width ||
+ new_fb_ptr->buf.y_crop_height != cm->height) {
+ vp9_realloc_frame_buffer(&new_fb_ptr->buf,
+ cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
+ VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
+ NULL, NULL, NULL);
+ scale_and_extend_frame(ref, &new_fb_ptr->buf);
+ cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
+ alloc_frame_mvs(cm, new_fb);
+ }
#endif // CONFIG_VP9_HIGHBITDEPTH
- cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
-
- alloc_frame_mvs(cm, new_fb);
} else {
const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
+ RefCntBuffer *const buf = &pool->frame_bufs[buf_idx];
+ buf->buf.y_crop_width = ref->y_crop_width;
+ buf->buf.y_crop_height = ref->y_crop_height;
cpi->scaled_ref_idx[ref_frame - 1] = buf_idx;
- ++pool->frame_bufs[buf_idx].ref_count;
+ ++buf->ref_count;
}
} else {
- cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
+ if (cpi->oxcf.pass != 0 || cpi->use_svc)
+ cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
}
}
}
@@ -2847,14 +2869,36 @@
static void release_scaled_references(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
int i;
- for (i = 0; i < MAX_REF_FRAMES; ++i) {
- const int idx = cpi->scaled_ref_idx[i];
- RefCntBuffer *const buf = idx != INVALID_IDX ?
- &cm->buffer_pool->frame_bufs[idx] : NULL;
- if (buf != NULL) {
- --buf->ref_count;
- cpi->scaled_ref_idx[i] = INVALID_IDX;
+ if (cpi->oxcf.pass == 0 && !cpi->use_svc) {
+ // Only release scaled references under certain conditions:
+ // if reference will be updated, or if scaled reference has same resolution.
+ int refresh[3];
+ refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
+ refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0;
+ refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
+ for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
+ const int idx = cpi->scaled_ref_idx[i - 1];
+ RefCntBuffer *const buf = idx != INVALID_IDX ?
+ &cm->buffer_pool->frame_bufs[idx] : NULL;
+ const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, i);
+ if (buf != NULL &&
+ (refresh[i - 1] ||
+ (buf->buf.y_crop_width == ref->y_crop_width &&
+ buf->buf.y_crop_height == ref->y_crop_height))) {
+ --buf->ref_count;
+ cpi->scaled_ref_idx[i -1] = INVALID_IDX;
+ }
}
+ } else {
+ for (i = 0; i < MAX_REF_FRAMES; ++i) {
+ const int idx = cpi->scaled_ref_idx[i];
+ RefCntBuffer *const buf = idx != INVALID_IDX ?
+ &cm->buffer_pool->frame_bufs[idx] : NULL;
+ if (buf != NULL) {
+ --buf->ref_count;
+ cpi->scaled_ref_idx[i] = INVALID_IDX;
+ }
+ }
}
}
@@ -4249,8 +4293,12 @@
set_frame_size(cpi);
}
- for (i = 0; i < MAX_REF_FRAMES; ++i)
- cpi->scaled_ref_idx[i] = INVALID_IDX;
+ if (cpi->oxcf.pass != 0 ||
+ cpi->use_svc ||
+ frame_is_intra_only(cm) == 1) {
+ for (i = 0; i < MAX_REF_FRAMES; ++i)
+ cpi->scaled_ref_idx[i] = INVALID_IDX;
+ }
if (oxcf->pass == 1 &&
(!cpi->use_svc || is_two_pass_svc(cpi))) {