VP9 SVC: Add control to disable inter layer prediction.
authorJerome Jiang <jianj@google.com>
Tue, 20 Mar 2018 18:12:16 +0000 (11:12 -0700)
committerJerome Jiang <jianj@google.com>
Wed, 21 Mar 2018 02:28:12 +0000 (19:28 -0700)
Add VP9E_SET_SVC_INTER_LAYER_PRED to disable inter layer (spatial)
prediction.
0: prediction on
1: prediction off for all frames
2: prediction off for non key frames

Bump up ABI version.

Change-Id: I5ab2a96b47e6bef202290fe726bed5f99bd4951f

examples/vp9_spatial_svc_encoder.c
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_svc_layercontext.c
vp9/encoder/vp9_svc_layercontext.h
vp9/vp9_cx_iface.c
vpx/vp8cx.h
vpx/vpx_encoder.h

index e93f063..ccc9ebd 100644 (file)
@@ -721,6 +721,8 @@ int main(int argc, const char **argv) {
     vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
   vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, 900);
 
+  vpx_codec_control(&codec, VP9E_SET_SVC_INTER_LAYER_PRED, 0);
+
   // Encode frames
   while (!end_of_stream) {
     vpx_codec_iter_t iter = NULL;
index 128574a..a0feb8e 100644 (file)
@@ -3751,20 +3751,26 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
 
   suppress_active_map(cpi);
 
-  // For SVC on non-zero spatial layer: if the previous spatial layer
-  // was dropped then disable the prediciton from this (scaled) reference.
-  if (cpi->use_svc && cpi->svc.spatial_layer_id > 0 &&
-      cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1]) {
-    MV_REFERENCE_FRAME ref_frame;
-    static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
-                                      VP9_ALT_FLAG };
-    for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
-      const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
-      if (yv12 != NULL && (cpi->ref_frame_flags & flag_list[ref_frame])) {
-        const struct scale_factors *const scale_fac =
-            &cm->frame_refs[ref_frame - 1].sf;
-        if (vp9_is_scaled(scale_fac))
-          cpi->ref_frame_flags &= (~flag_list[ref_frame]);
+  // For SVC on non-zero spatial layer: check for disabling inter-layer
+  // (spatial) prediction, if svc.disable_inter_layer_pred is set.
+  // if the previous spatial layer was dropped then disable the prediction from
+  // this (scaled) reference.
+  if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
+    if ((cpi->svc.disable_inter_layer_pred == INTER_LAYER_PRED_OFF_NONKEY &&
+         !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame) ||
+        cpi->svc.disable_inter_layer_pred == INTER_LAYER_PRED_OFF ||
+        cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1]) {
+      MV_REFERENCE_FRAME ref_frame;
+      static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
+                                        VP9_ALT_FLAG };
+      for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
+        const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
+        if (yv12 != NULL && (cpi->ref_frame_flags & flag_list[ref_frame])) {
+          const struct scale_factors *const scale_fac =
+              &cm->frame_refs[ref_frame - 1].sf;
+          if (vp9_is_scaled(scale_fac))
+            cpi->ref_frame_flags &= (~flag_list[ref_frame]);
+        }
       }
     }
   }
index 1957bb9..1588860 100644 (file)
@@ -38,6 +38,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) {
   svc->current_superframe = 0;
   svc->non_reference_frame = 0;
   svc->skip_enhancement_layer = 0;
+  svc->disable_inter_layer_pred = INTER_LAYER_PRED_ON;
 
   for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1;
   for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
index 9bf62ee..f180747 100644 (file)
 extern "C" {
 #endif
 
+typedef enum {
+  INTER_LAYER_PRED_ON,
+  INTER_LAYER_PRED_OFF,
+  INTER_LAYER_PRED_OFF_NONKEY
+} INTER_LAYER_PRED;
+
 typedef struct {
   RATE_CONTROL rc;
   int target_bandwidth;
@@ -108,6 +114,8 @@ typedef struct SVC {
 
   int last_layer_dropped[VPX_MAX_LAYERS];
   int drop_spatial_layer[VPX_MAX_LAYERS];
+
+  INTER_LAYER_PRED disable_inter_layer_pred;
 } SVC;
 
 struct VP9_COMP;
index a2c5dc8..b33d578 100644 (file)
@@ -1516,6 +1516,14 @@ static vpx_codec_err_t ctrl_set_svc_ref_frame_config(vpx_codec_alg_priv_t *ctx,
   return VPX_CODEC_OK;
 }
 
+static vpx_codec_err_t ctrl_set_svc_inter_layer_pred(vpx_codec_alg_priv_t *ctx,
+                                                     va_list args) {
+  const int data = va_arg(args, int);
+  VP9_COMP *const cpi = ctx->cpi;
+  cpi->svc.disable_inter_layer_pred = data;
+  return VPX_CODEC_OK;
+}
+
 static vpx_codec_err_t ctrl_register_cx_callback(vpx_codec_alg_priv_t *ctx,
                                                  va_list args) {
   vpx_codec_priv_output_cx_pkt_cb_pair_t *cbp =
@@ -1599,6 +1607,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
   { VP9E_SET_TARGET_LEVEL, ctrl_set_target_level },
   { VP9E_SET_ROW_MT, ctrl_set_row_mt },
   { VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
+  { VP9E_SET_SVC_INTER_LAYER_PRED, ctrl_set_svc_inter_layer_pred },
 
   // Getters
   { VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer },
index 261ed86..3452fde 100644 (file)
@@ -602,6 +602,15 @@ enum vp8e_enc_control_id {
    * Supported in codecs: VP9
    */
   VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST,
+
+  /*!\brief Codec control function to constrain the inter-layer prediction
+   * (prediction of lower spatial resolution) in VP9 SVC.
+   *
+   * 0 : inter-layer prediction on, 1 : off, 2 : off only on non-key frames
+   *
+   * Supported in codecs: VP9
+   */
+  VP9E_SET_SVC_INTER_LAYER_PRED,
 };
 
 /*!\brief vpx 1-D scaling mode
@@ -879,6 +888,9 @@ VPX_CTRL_USE_TYPE(VP9E_GET_LEVEL, int *)
 VPX_CTRL_USE_TYPE(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, unsigned int)
 #define VPX_CTRL_VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST
 
+VPX_CTRL_USE_TYPE(VP9E_SET_SVC_INTER_LAYER_PRED, unsigned int)
+#define VPX_CTRL_VP9E_SET_SVC_INTER_LAYER_PRED
+
 /*!\endcond */
 /*! @} - end defgroup vp8_encoder */
 #ifdef __cplusplus
index 26eb054..191d115 100644 (file)
@@ -63,7 +63,7 @@ extern "C" {
  * fields to structures
  */
 #define VPX_ENCODER_ABI_VERSION \
-  (9 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
+  (10 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
 
 /*! \brief Encoder capabilities bitfield
  *