]> granicus.if.org Git - libvpx/commitdiff
vp9-svc: Fix when whole superframe is dropped.
authorMarco Paniconi <marpan@google.com>
Tue, 8 May 2018 05:54:48 +0000 (22:54 -0700)
committerMarco Paniconi <marpan@google.com>
Fri, 11 May 2018 16:39:29 +0000 (09:39 -0700)
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

test/encode_test_driver.cc
test/encode_test_driver.h
test/svc_datarate_test.cc
vp9/encoder/vp9_encoder.c

index 63e972a00ac3f7d946d6af07dce9c2b0613daf21..b2cbc3f05bdf49ba983b4623b6822452ce984640 100644 (file)
@@ -201,7 +201,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
       PreEncodeFrameHook(video, encoder.get());
       encoder->EncodeFrame(video, frame_flags_);
 
-      PostEncodeFrameHook();
+      PostEncodeFrameHook(encoder.get());
 
       CxDataIterator iter = encoder->GetCxData();
 
index a301e21cc9b91de3ab15db97d500f4b9444c1346..03624d110e0c269ee8863022217df51d6c75c8b7 100644 (file)
@@ -226,7 +226,7 @@ class EncoderTest {
   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*/) {}
index be3a1969cd5134f1fc6d01ddcf14179092ff74c1..608f27ebfb3df28d9d0af0e9b256adc0b98ca5b3 100644 (file)
@@ -297,7 +297,10 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest {
     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 @@ TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc2SL3TL4Threads) {
                       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.
index 3384de7eade7f66442bc5b690b9000bdf7f7e796..13f01a3ab35131cc1938d161b011a5163bb8762d 100644 (file)
@@ -4560,8 +4560,18 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
       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;