ref: f362bf981c4648b426aa2a0735d4fb6bda4136c0
parent: af355dacd568dfe5c109ae2d6d22104f94cdcf7f
author: Marco Paniconi <marpan@google.com>
date: Mon May 7 18:54:48 EDT 2018
vp9-svc: Fix when whole superframe is dropped. When the whole superframe is dropped (due to rate control), don't increment the temporal layer counter. This is a temporary fix to prevent an issue where temporal prediction pattern is possibly broken. Updated svc_datarate tests to handle this case. Change-Id: Icac44fdc9d0f08a957776c937584db4b2c7927c7
--- a/test/encode_test_driver.cc
+++ b/test/encode_test_driver.cc
@@ -201,7 +201,7 @@
PreEncodeFrameHook(video, encoder.get());
encoder->EncodeFrame(video, frame_flags_);
- PostEncodeFrameHook();
+ PostEncodeFrameHook(encoder.get());
CxDataIterator iter = encoder->GetCxData();
--- a/test/encode_test_driver.h
+++ b/test/encode_test_driver.h
@@ -226,7 +226,7 @@
virtual void PreEncodeFrameHook(VideoSource * /*video*/,
Encoder * /*encoder*/) {}
- virtual void PostEncodeFrameHook() {}
+ virtual void PostEncodeFrameHook(Encoder * /*encoder*/) {}
// Hook to be called on every compressed data packet.
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
--- a/test/svc_datarate_test.cc
+++ b/test/svc_datarate_test.cc
@@ -297,7 +297,10 @@
duration_ = 0;
}
- virtual void PostEncodeFrameHook() {
+ virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) {
+ vpx_svc_layer_id_t layer_id;
+ encoder->Control(VP9E_GET_SVC_LAYER_ID, &layer_id);
+ temporal_layer_id_ = layer_id.temporal_layer_id;
for (int sl = 0; sl < number_spatial_layers_; ++sl) {
for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) {
const int layer = sl * number_temporal_layers_ + tl;
@@ -848,7 +851,7 @@
layer_target_avg_bandwidth_, bits_in_buffer_model_);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
CheckLayerRateTargeting(&cfg_, number_spatial_layers_,
- number_temporal_layers_, file_datarate_, 0.75, 1.2);
+ number_temporal_layers_, file_datarate_, 0.75, 1.45);
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -4560,8 +4560,18 @@
if (cpi->use_svc) {
cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 1;
cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id] = 1;
- vp9_inc_frame_in_layer(cpi);
cpi->svc.skip_enhancement_layer = 1;
+ if (cpi->svc.framedrop_mode != CONSTRAINED_LAYER_DROP ||
+ cpi->svc.drop_spatial_layer[0] == 0) {
+ // For the case of CONSTRAINED_LAYER_DROP where the base is dropped
+ // (drop_spatial_layer[0] == 1), which means full superframe dropped,
+ // we don't increment the svc frame counters. In particular temporal
+ // layer counter (which is incremented in vp9_inc_frame_in_layer())
+ // won't be incremented, so on a dropped frame we try the same
+ // temporal_layer_id on next incoming frame. This is to avoid an
+ // issue with temporal alignement with full superframe dropping.
+ vp9_inc_frame_in_layer(cpi);
+ }
if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
int i;
int all_layers_drop = 1;