From e358cf0a438b946b6cb39236c366a9c95cca90cc Mon Sep 17 00:00:00 2001 From: Marco Paniconi Date: Wed, 28 Mar 2018 12:09:54 -0700 Subject: [PATCH] vp9-svc: Modify logic for frame dropping with spatial layers. In the constrained framedrop mode for svc: modify the buffer check condition relative to (non-zero) dropmark to include uppper spatial layers, in addition to the current spatial layer. But keep the single layer check if the buffer goes below zero, since in this case (buffer underflow) we should force drop of that layer regardless of upper layers. Change-Id: Id277f0b4a3ae6275effdd5f5f0c80e3229c17424 --- vp9/encoder/vp9_ratectrl.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index ced42fbdc..d6d5db47e 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -393,6 +393,29 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2; } +static int check_buffer(VP9_COMP *cpi, int drop_mark) { + SVC *svc = &cpi->svc; + if (!cpi->use_svc || !cpi->svc.framedrop_mode) { + RATE_CONTROL *const rc = &cpi->rc; + return (rc->buffer_level <= drop_mark); + } else { + int i; + // For SVC in the constrained framedrop mode (svc->framedrop_mode = 1): + // the condition on buffer (to drop frame) is checked on current and + // upper spatial layers. + for (i = svc->spatial_layer_id; i < svc->number_spatial_layers; ++i) { + const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id, + svc->number_temporal_layers); + LAYER_CONTEXT *lc = &svc->layer_context[layer]; + RATE_CONTROL *lrc = &lc->rc; + const int drop_mark_layer = + (int)(cpi->svc.framedrop_thresh[i] * lrc->optimal_buffer_level / 100); + if (!(lrc->buffer_level <= drop_mark_layer)) return 0; + } + return 1; + } +} + int vp9_rc_drop_frame(VP9_COMP *cpi) { const VP9EncoderConfig *oxcf = &cpi->oxcf; RATE_CONTROL *const rc = &cpi->rc; @@ -413,7 +436,7 @@ int vp9_rc_drop_frame(VP9_COMP *cpi) { (int)(drop_frames_water_mark * rc->optimal_buffer_level / 100); if ((rc->buffer_level > drop_mark) && (rc->decimation_factor > 0)) { --rc->decimation_factor; - } else if (rc->buffer_level <= drop_mark && rc->decimation_factor == 0) { + } else if (check_buffer(cpi, drop_mark) && rc->decimation_factor == 0) { rc->decimation_factor = 1; } if (rc->decimation_factor > 0) {