]> granicus.if.org Git - libvpx/commitdiff
Fix per frame qp for temporal layers
authorJerome Jiang <jianj@google.com>
Thu, 26 Jan 2023 00:25:12 +0000 (19:25 -0500)
committerJerome Jiang <jianj@google.com>
Tue, 31 Jan 2023 23:58:26 +0000 (18:58 -0500)
Also add tests with fixed temporal layering mode.

Change-Id: If516fe94e3fb7f5a745821d1788bfe6cf90edaac
(cherry picked from commit db69ce6aea278bee88668fd9cc2af2e544516fdb)

test/vp9_datarate_test.cc
vp9/encoder/vp9_svc_layercontext.c

index eccb0010717fc1edc418108b9eeb1f2abc3cd97b..7e918074925391ba54f09fd5bb32ef0a55a1a39b 100644 (file)
@@ -148,14 +148,16 @@ class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
       if (video->frame() == 0) {
         encoder->Control(VP9E_SET_SVC, 1);
       }
-      vpx_svc_layer_id_t layer_id;
-      layer_id.spatial_layer_id = 0;
-      frame_flags_ = GetFrameFlags(video->frame(), cfg_.ts_number_layers);
-      layer_id.temporal_layer_id =
-          SetLayerId(video->frame(), cfg_.ts_number_layers);
-      layer_id.temporal_layer_id_per_spatial[0] =
-          SetLayerId(video->frame(), cfg_.ts_number_layers);
-      encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
+      if (cfg_.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
+        vpx_svc_layer_id_t layer_id;
+        frame_flags_ = GetFrameFlags(video->frame(), cfg_.ts_number_layers);
+        layer_id.spatial_layer_id = 0;
+        layer_id.temporal_layer_id =
+            SetLayerId(video->frame(), cfg_.ts_number_layers);
+        layer_id.temporal_layer_id_per_spatial[0] =
+            SetLayerId(video->frame(), cfg_.ts_number_layers);
+        encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
+      }
     }
     const vpx_rational_t tb = video->timebase();
     timebase_ = static_cast<double>(tb.num) / tb.den;
@@ -830,25 +832,37 @@ class DatarateTestVP9FrameQp
                                   ::libvpx_test::Encoder *encoder) {
     set_cpu_used_ = 7;
     DatarateTestVP9::PreEncodeFrameHook(video, encoder);
-    ACMRandom rnd;
-    frame_qp_ = static_cast<int>(rnd.RandRange(64));
+    frame_qp_ = static_cast<int>(rnd_.RandRange(64));
     encoder->Control(VP9E_SET_QUANTIZER_ONE_PASS, frame_qp_);
     frame_++;
   }
 
   virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) {
     int qp = 0;
+    vpx_svc_layer_id_t layer_id;
     if (frame_ >= total_frame_) return;
     encoder->Control(VP8E_GET_LAST_QUANTIZER_64, &qp);
     ASSERT_EQ(frame_qp_, qp);
+    encoder->Control(VP9E_GET_SVC_LAYER_ID, &layer_id);
+    temporal_layer_id_ = layer_id.temporal_layer_id;
+  }
+
+  virtual void MismatchHook(const vpx_image_t * /*img1*/,
+                            const vpx_image_t * /*img2*/) {
+    if (frame_ >= total_frame_) return;
+    ASSERT_TRUE(cfg_.temporal_layering_mode ==
+                    VP9E_TEMPORAL_LAYERING_MODE_0212 &&
+                temporal_layer_id_ == 2);
   }
 
  protected:
   int total_frame_;
 
  private:
+  ACMRandom rnd_;
   int frame_qp_;
   int frame_;
+  int temporal_layer_id_;
 };
 
 TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp) {
@@ -868,7 +882,7 @@ TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp) {
   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
 }
 
-TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp3TemporalLayers) {
+TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp3TemporalLayersBypass) {
   cfg_.rc_buf_initial_sz = 500;
   cfg_.rc_buf_optimal_sz = 500;
   cfg_.rc_buf_sz = 1000;
@@ -897,6 +911,36 @@ TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp3TemporalLayers) {
   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
 }
 
+TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp3TemporalLayersFixedMode) {
+  cfg_.rc_buf_initial_sz = 500;
+  cfg_.rc_buf_optimal_sz = 500;
+  cfg_.rc_buf_sz = 1000;
+  cfg_.rc_dropframe_thresh = 0;
+  cfg_.rc_max_quantizer = 63;
+  cfg_.rc_min_quantizer = 0;
+  cfg_.rc_end_usage = VPX_CBR;
+  cfg_.g_lag_in_frames = 0;
+
+  // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
+  cfg_.ss_number_layers = 1;
+  cfg_.ts_number_layers = 3;
+  cfg_.ts_rate_decimator[0] = 4;
+  cfg_.ts_rate_decimator[1] = 2;
+  cfg_.ts_rate_decimator[2] = 1;
+
+  cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_0212;
+  cfg_.rc_target_bitrate = 200;
+  cfg_.g_error_resilient = 1;
+  total_frame_ = 400;
+  ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
+                                       0, total_frame_);
+  ResetModel();
+  cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
+  cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
+  cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+}
+
 #if CONFIG_VP9_TEMPORAL_DENOISING
 // Params: speed setting.
 class DatarateTestVP9RealTimeDenoiser : public DatarateTestVP9RealTime {
index 518c00b34a157f64467b38d37bbb0fe62bd06cac..7e9435fb5fe5e283f1c8c38cfd5d4a983616319b 100644 (file)
@@ -894,6 +894,10 @@ int vp9_one_pass_svc_start_layer(VP9_COMP *const cpi) {
     RATE_CONTROL *const lrc = &lc->rc;
     lrc->worst_quality = vp9_quantizer_to_qindex(lc->max_q);
     lrc->best_quality = vp9_quantizer_to_qindex(lc->min_q);
+    if (cpi->fixed_qp_onepass) {
+      lrc->worst_quality = cpi->rc.worst_quality;
+      lrc->best_quality = cpi->rc.best_quality;
+    }
   }
 
   if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && svc->single_layer_svc == 1 &&