]> granicus.if.org Git - libvpx/commitdiff
Adapt GOP size threshold to the allowed layer depth
authorJingning Han <jingning@google.com>
Wed, 26 Sep 2018 23:34:16 +0000 (16:34 -0700)
committerJingning Han <jingning@google.com>
Thu, 27 Sep 2018 17:45:26 +0000 (10:45 -0700)
Increase the total prediction error budget linearly with the
allowed ARF layer depth. This in general improves the compression
performance, but does hit corner cases on a few clips at very
low bit-rate range (corresponding to 26 - 28 dB range). To mitigate
such problem, we temporarily work around this problem by limiting
the first GOP size to be ~8 so as to not drain up the bit resource.

The overall compression performance improvements over the current
multi-layer ARF system in speed 0 are:

           overall PSNR      avg PSNR        SSIM
lowres     -0.47%            -0.13%         -1.51%
midres     -1.30%            -1.16%         -2.80%
hdres      -0.91%            -0.84%         -2.15%

Change-Id: Ia4880ab63e98e15a9db99aea6eabfd3d1da9270d

vp9/encoder/vp9_firstpass.c

index 38e98cd1eb354fb791cdd3739db183e5ea3f6018..2391cb7a6d3a45f21f8dbf2eb6f47d3872fd3f2c 100644 (file)
@@ -2485,6 +2485,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   const int is_key_frame = frame_is_intra_only(cm);
   const int arf_active_or_kf = is_key_frame || rc->source_alt_ref_active;
 
+  int gop_intra_factor = 0;
+
   // Reset the GF group data structures unless this is a key
   // frame in which case it will already have been done.
   if (is_key_frame == 0) {
@@ -2537,6 +2539,12 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
     // interval to spread the cost of the GF.
     active_max_gf_interval = 12 + arf_active_or_kf + VPXMIN(4, (int_lbq / 6));
 
+    // TODO(jingning, paulwilkins): Temporary solution to work around
+    // multi-layer ARF rate control issues at extremely low bit-rate cases.
+    // We would deprecate this soon.
+    if (cpi->multi_layer_arf && is_key_frame)
+      active_max_gf_interval = 7 + arf_active_or_kf + VPXMIN(4, (int_lbq / 6));
+
     // We have: active_min_gf_interval <=
     // rc->max_gf_interval + arf_active_or_kf.
     if (active_max_gf_interval < active_min_gf_interval) {
@@ -2552,6 +2560,11 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
       active_max_gf_interval = rc->frames_to_key / 2;
   }
 
+  // Adapt the intra_error factor to active_max_gf_interval limit.
+  for (i = active_max_gf_interval; i > 0; i >>= 1) ++gop_intra_factor;
+
+  gop_intra_factor = VPXMIN(MAX_ARF_LAYERS, gop_intra_factor);
+
   i = 0;
   while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
     ++i;
@@ -2628,7 +2641,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
             (!flash_detected) &&
             ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) ||
              (abs_mv_in_out_accumulator > abs_mv_in_out_thresh) ||
-             (sr_accumulator > next_frame.intra_error)))) {
+             (sr_accumulator > gop_intra_factor * next_frame.intra_error)))) {
       break;
     }