From f01c769dc6589790325b297be2d402d555811f5a Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 10 Jul 2015 10:28:51 -0700 Subject: [PATCH] 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 --- vp9/encoder/vp9_encoder.c | 112 +++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 32 deletions(-) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 781204d23..7a41a7e2e 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -2803,43 +2803,65 @@ void vp9_scale_references(VP9_COMP *cpi) { #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,13 +2869,35 @@ void vp9_scale_references(VP9_COMP *cpi) { 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 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, 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))) { -- 2.40.0