shithub: libvpx

Download patch

ref: 3134a52d26cc8deff4bd197537aca6cfdc597e44
parent: 897543646644410f91d381589ba56aecc28dfa3e
author: Marco <marpan@google.com>
date: Thu Apr 20 05:50:16 EDT 2017

vp9: SVC: Redefine the source downsample filter choice.

Rename the source downsampling filter, and define it
per spatial layers. Used 1 pass CBR SVC.

Change-Id: I8135f2ab89c535c53429b9c58b586f746bb668c7

--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3124,7 +3124,11 @@
                                        uint8_t *dest) {
   VP9_COMMON *const cm = &cpi->common;
   int q = 0, bottom_index = 0, top_index = 0;  // Dummy variables.
-  const int phase_scaler = is_one_pass_cbr_svc(cpi) ? cpi->svc.phase_scaler : 0;
+  const int phase_scaler =
+      (is_one_pass_cbr_svc(cpi) &&
+       cpi->svc.filtertype_downsample_source[cpi->svc.spatial_layer_id])
+          ? 8
+          : 0;
 
   // Flag to check if its valid to compute the source sad (used for
   // scene detection and for superblock content state in CBR mode).
@@ -3144,9 +3148,10 @@
     // For svc, if it is a 1/4x1/4 downscaling, do a two-stage scaling to take
     // advantage of the 1:2 optimized scaler. In the process, the 1/2x1/2
     // result will be saved in scaled_temp and might be used later.
-    cpi->Source =
-        vp9_svc_twostage_scale(cm, cpi->un_scaled_source, &cpi->scaled_source,
-                               &cpi->svc.scaled_temp, phase_scaler);
+    int phase_scaler2 = (cpi->svc.filtertype_downsample_source[1]) ? 8 : 0;
+    cpi->Source = vp9_svc_twostage_scale(
+        cm, cpi->un_scaled_source, &cpi->scaled_source, &cpi->svc.scaled_temp,
+        phase_scaler, phase_scaler2);
     cpi->svc.scaled_one_half = 1;
   } else if (is_one_pass_cbr_svc(cpi) &&
              cpi->un_scaled_source->y_width == cm->width << 1 &&
@@ -3685,25 +3690,23 @@
   }
 }
 
-YV12_BUFFER_CONFIG *vp9_svc_twostage_scale(VP9_COMMON *cm,
-                                           YV12_BUFFER_CONFIG *unscaled,
-                                           YV12_BUFFER_CONFIG *scaled,
-                                           YV12_BUFFER_CONFIG *scaled_temp,
-                                           int phase_scaler) {
+YV12_BUFFER_CONFIG *vp9_svc_twostage_scale(
+    VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled,
+    YV12_BUFFER_CONFIG *scaled_temp, int phase_scaler, int phase_scaler2) {
   if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
       cm->mi_rows * MI_SIZE != unscaled->y_height) {
 #if CONFIG_VP9_HIGHBITDEPTH
     if (cm->bit_depth == VPX_BITS_8) {
-      vp9_scale_and_extend_frame(unscaled, scaled_temp, phase_scaler);
+      vp9_scale_and_extend_frame(unscaled, scaled_temp, phase_scaler2);
       vp9_scale_and_extend_frame(scaled_temp, scaled, phase_scaler);
     } else {
       scale_and_extend_frame(unscaled, scaled_temp, (int)cm->bit_depth,
-                             phase_scaler);
+                             phase_scaler2);
       scale_and_extend_frame(scaled_temp, scaled, (int)cm->bit_depth,
                              phase_scaler);
     }
 #else
-    vp9_scale_and_extend_frame(unscaled, scaled_temp, phase_scaler);
+    vp9_scale_and_extend_frame(unscaled, scaled_temp, phase_scaler2);
     vp9_scale_and_extend_frame(scaled_temp, scaled, phase_scaler);
 #endif  // CONFIG_VP9_HIGHBITDEPTH
     return scaled;
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -844,7 +844,7 @@
                                            YV12_BUFFER_CONFIG *unscaled,
                                            YV12_BUFFER_CONFIG *scaled,
                                            YV12_BUFFER_CONFIG *scaled_temp,
-                                           int phase_scaler);
+                                           int phase_scaler, int phase_scaler2);
 
 YV12_BUFFER_CONFIG *vp9_scale_if_required(VP9_COMMON *cm,
                                           YV12_BUFFER_CONFIG *unscaled,
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -36,7 +36,6 @@
   svc->scaled_temp_is_alloc = 0;
   svc->scaled_one_half = 0;
   svc->current_superframe = 0;
-  svc->phase_scaler = 0;
   for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1;
   for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
     cpi->svc.ext_frame_flags[sl] = 0;
@@ -43,6 +42,7 @@
     cpi->svc.ext_lst_fb_idx[sl] = 0;
     cpi->svc.ext_gld_fb_idx[sl] = 1;
     cpi->svc.ext_alt_fb_idx[sl] = 2;
+    cpi->svc.filtertype_downsample_source[sl] = 0;
   }
 
   if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
@@ -664,8 +664,10 @@
       if ((lc->scaling_factor_num != lc->scaling_factor_den >> 1) &&
           !(lc->scaling_factor_num == lc->scaling_factor_den >> 2 && sl == 0 &&
             cpi->svc.number_spatial_layers == 3)) {
+        int sl2;
         cpi->svc.use_base_mv = 0;
-        cpi->svc.phase_scaler = 0;
+        for (sl2 = 0; sl2 < cpi->svc.number_spatial_layers - 1; ++sl2)
+          cpi->svc.filtertype_downsample_source[sl2] = 0;
         break;
       }
     }
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -88,11 +88,12 @@
   int force_zero_mode_spatial_ref;
   int current_superframe;
   int use_base_mv;
-  // phase_scaler used to control the downscaling filter for source scaling.
-  // phase_scaler = 0 will do sub-sampling (no weighted average),
-  // phase_scaler = 8 will center the target pixel and use the averaging filter,
-  // for eightap regular: {-1, 6, -19, 78, 78, -19, 6, -1 }.
-  int phase_scaler;
+  // Used to control the downscaling filter for source scaling, for 1 pass CBR.
+  // 0 will do sub-sampling (no weighted average), 1 will center the target
+  // pixel and use the averaging filter, for the default eightap_regular:
+  // {-1, 6, -19, 78, 78, -19, 6, -1 }.
+  // TODO(marpan): Add option for bilinear.
+  int filtertype_downsample_source[VPX_SS_MAX_LAYERS];
 } SVC;
 
 struct VP9_COMP;