From 4fb2ba2861fffd8fca7dffbaf761d2bf2998df4f Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 27 Oct 2015 13:02:02 -0700 Subject: [PATCH] VP9-SVC: Allow frame dropping due to overshoot for spatial layers. For 1 pass CBR mode. Change-Id: I8bceb489a850ec26f05382eecb5c0c32a1bb8883 --- vp9/encoder/vp9_encoder.c | 7 +++++-- vp9/encoder/vp9_ratectrl.c | 5 +++-- vp9/encoder/vp9_svc_layercontext.c | 4 ++++ vp9/encoder/vp9_svc_layercontext.h | 1 + vpx/src/svc_encodeframe.c | 1 + 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 72eafec40..8cc99cd74 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3797,14 +3797,17 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } // For 1 pass CBR, check if we are dropping this frame. - // Never drop on key frame. + // For spatial layers, for now only check for frame-dropping on first spatial + // layer, and if decision is to drop, we drop whole super-frame. if (oxcf->pass == 0 && oxcf->rc_mode == VPX_CBR && cm->frame_type != KEY_FRAME) { - if (vp9_rc_drop_frame(cpi)) { + if (vp9_rc_drop_frame(cpi) || + (is_one_pass_cbr_svc(cpi) && cpi->svc.rc_drop_superframe == 1)) { vp9_rc_postencode_update_drop_frame(cpi); ++cm->current_video_frame; cpi->ext_refresh_frame_flags_pending = 0; + cpi->svc.rc_drop_superframe = 1; return; } } diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index d70068570..93cf2ccdd 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -370,8 +370,9 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { int vp9_rc_drop_frame(VP9_COMP *cpi) { const VP9EncoderConfig *oxcf = &cpi->oxcf; RATE_CONTROL *const rc = &cpi->rc; - - if (!oxcf->drop_frames_water_mark) { + if (!oxcf->drop_frames_water_mark || + (is_one_pass_cbr_svc(cpi) && + cpi->svc.spatial_layer_id > cpi->svc.first_spatial_layer_to_encode)) { return 0; } else { if (rc->buffer_level < 0) { diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index 8a6818c86..1dfc45cf6 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -31,6 +31,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { svc->spatial_layer_id = 0; svc->temporal_layer_id = 0; svc->first_spatial_layer_to_encode = 0; + svc->rc_drop_superframe = 0; if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) { if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, @@ -568,6 +569,9 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { } } + if (cpi->svc.spatial_layer_id == cpi->svc.first_spatial_layer_to_encode) + cpi->svc.rc_drop_superframe = 0; + lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id * cpi->svc.number_temporal_layers + cpi->svc.temporal_layer_id]; diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index 694b5abdc..5dbf9b418 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -56,6 +56,7 @@ typedef struct { int spatial_layer_to_encode; int first_spatial_layer_to_encode; + int rc_drop_superframe; // Workaround for multiple frame contexts enum { diff --git a/vpx/src/svc_encodeframe.c b/vpx/src/svc_encodeframe.c index ff600830e..ff7c10afc 100644 --- a/vpx/src/svc_encodeframe.c +++ b/vpx/src/svc_encodeframe.c @@ -485,6 +485,7 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, enc_cfg->rc_buf_initial_sz = 500; enc_cfg->rc_buf_optimal_sz = 600; enc_cfg->rc_buf_sz = 1000; + enc_cfg->rc_dropframe_thresh = 0; } if (enc_cfg->g_error_resilient == 0 && si->use_multiple_frame_contexts == 0)