From bb06546d56a82a4953666dfae91d52881e896075 Mon Sep 17 00:00:00 2001 From: Marco Paniconi Date: Tue, 8 May 2018 11:05:03 -0700 Subject: [PATCH] vp9-svc: Fix to SVC for frame dropping. When the previous frame is dropped, for the current spatial layer make sure the lst_fb_idx corresponds to the buffer index last updated on the (last) encoded TL0 frame(for same spatial layer). This is needed to preserve the temporal prediction pattern for fixed/non-flexible mode under frame dropping. Change-Id: Ifc8e257beb025654a81580c4da0a181235724508 --- vp9/encoder/vp9_encoder.c | 10 ++++++++++ vp9/encoder/vp9_svc_layercontext.c | 9 +++++++++ vp9/encoder/vp9_svc_layercontext.h | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 9ae5dc03d..3384de7ea 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -4593,6 +4593,16 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, cpi->last_frame_dropped = 0; cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 0; + // Keep track of the frame buffer index updated/refreshed for the + // current encoded TL0 superframe. + if (cpi->svc.temporal_layer_id == 0) { + if (cpi->refresh_last_frame) + cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->lst_fb_idx; + else if (cpi->refresh_golden_frame) + cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->gld_fb_idx; + else if (cpi->refresh_alt_ref_frame) + cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->alt_fb_idx; + } // Disable segmentation if it decrease rate/distortion ratio if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index 84e47c6be..07d1995a8 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -786,6 +786,15 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { if (cpi->svc.spatial_layer_id == 0) cpi->svc.high_source_sad_superframe = 0; + if (cpi->svc.temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && + cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id]) { + // For fixed/non-flexible mode, if the previous frame (same spatial layer + // from previous superframe) was dropped, make sure the lst_fb_idx + // for this frame corresponds to the buffer index updated on (last) encoded + // TL0 frame (with same spatial layer). + cpi->lst_fb_idx = cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id]; + } + if (vp9_set_size_literal(cpi, width, height) != 0) return VPX_CODEC_INVALID_PARAM; diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index fb3127687..617717049 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -138,6 +138,10 @@ typedef struct SVC { uint8_t reference_last[VPX_SS_MAX_LAYERS]; uint8_t reference_golden[VPX_SS_MAX_LAYERS]; uint8_t reference_altref[VPX_SS_MAX_LAYERS]; + + // Keep track of the frame buffer index updated/refreshed on the base + // temporal superframe. + uint8_t fb_idx_upd_tl0[VPX_SS_MAX_LAYERS]; } SVC; struct VP9_COMP; -- 2.40.0