From 8c196b27b317e8c588e7af82a9a38cd48b4cb08b Mon Sep 17 00:00:00 2001
From: Minghai Shang <minghai@google.com>
Date: Wed, 26 Feb 2014 13:30:50 -0800
Subject: [PATCH] [svc] Add target bitrate settings for each layers.

Change-Id: Ia7677fb436667bc4f76db71f65e4784f433f7826
---
 vp8/vp8_cx_iface.c        |  1 +
 vp9/common/vp9_onyx.h     |  2 ++
 vp9/vp9_cx_iface.c        |  8 ++++++++
 vpx/src/svc_encodeframe.c | 23 +++++++++++++++++++++++
 vpx/vpx_encoder.h         |  7 +++++++
 5 files changed, 41 insertions(+)

diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index ce789e2185..4c896b1d14 100644
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -1265,6 +1265,7 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] =
         "vp8.fpf"           /* first pass filename */
 #endif
         VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */
+        {0},                /* ss_target_bitrate */
         1,                  /* ts_number_layers */
         {0},                /* ts_target_bitrate */
         {0},                /* ts_rate_decimator */
diff --git a/vp9/common/vp9_onyx.h b/vp9/common/vp9_onyx.h
index ab27ca523e..2220868865 100644
--- a/vp9/common/vp9_onyx.h
+++ b/vp9/common/vp9_onyx.h
@@ -149,6 +149,8 @@ extern "C" {
     // Spatial and temporal scalability.
     int ss_number_layers;  // Number of spatial layers.
     int ts_number_layers;  // Number of temporal layers.
+    // Bitrate allocation for spatial layers.
+    int ss_target_bitrate[VPX_SS_MAX_LAYERS];
     // Bitrate allocation (CBR mode) and framerate factor, for temporal layers.
     int ts_target_bitrate[VPX_TS_MAX_LAYERS];
     int ts_rate_decimator[VPX_TS_MAX_LAYERS];
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index a4162e942d..d7713fd3f8 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -355,6 +355,13 @@ static vpx_codec_err_t set_vp9e_config(VP9_CONFIG *oxcf,
 
   oxcf->ss_number_layers = cfg.ss_number_layers;
 
+  if (oxcf->ss_number_layers > 1) {
+    memcpy(oxcf->ss_target_bitrate, cfg.ss_target_bitrate,
+           sizeof(cfg.ss_target_bitrate));
+  } else if (oxcf->ss_number_layers == 1) {
+    oxcf->ss_target_bitrate[0] = oxcf->target_bandwidth;
+  }
+
   oxcf->ts_number_layers = cfg.ts_number_layers;
 
   if (oxcf->ts_number_layers > 1) {
@@ -1160,6 +1167,7 @@ static vpx_codec_enc_cfg_map_t vp9e_usage_cfg_map[] = {
       9999,               /* kf_max_dist */
 
       VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */
+      {0},                /* ss_target_bitrate */
       1,                  /* ts_number_layers */
       {0},                /* ts_target_bitrate */
       {0},                /* ts_rate_decimator */
diff --git a/vpx/src/svc_encodeframe.c b/vpx/src/svc_encodeframe.c
index c12d8a3b09..4badca977b 100644
--- a/vpx/src/svc_encodeframe.c
+++ b/vpx/src/svc_encodeframe.c
@@ -534,6 +534,29 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
   res = parse_options(svc_ctx, si->options);
   if (res != VPX_CODEC_OK) return res;
 
+  // Assign target bitrate for each layer. We calculate the ratio
+  // from the resolution for now.
+  // TODO(Minghai): Optimize the mechanism of allocating bits after
+  // implementing svc two pass rate control.
+  if (si->layers > 1) {
+    int i;
+    float total = 0;
+    float alloc_ratio[VPX_SS_MAX_LAYERS] = {0};
+
+    for (i = 0; i < si->layers; ++i) {
+      int pos = i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers;
+      alloc_ratio[i] = si->scaling_factor_num[pos] * 1.0 /
+                       si->scaling_factor_den[pos];
+      alloc_ratio[i] *= alloc_ratio[i];
+      total += alloc_ratio[i];
+    }
+
+    for (i = 0; i < si->layers; ++i) {
+      enc_cfg->ss_target_bitrate[i] = enc_cfg->rc_target_bitrate *
+          alloc_ratio[i] / total;
+    }
+  }
+
   // modify encoder configuration
   enc_cfg->ss_number_layers = si->layers;
   enc_cfg->ts_number_layers = 1;  // Temporal layers not used in this encoder.
diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h
index 1d9f0c9b7f..851ff1ae8a 100644
--- a/vpx/vpx_encoder.h
+++ b/vpx/vpx_encoder.h
@@ -610,6 +610,13 @@ extern "C" {
      */
     unsigned int           ss_number_layers;
 
+    /*!\brief Target bitrate for each spatial layer.
+     *
+     * These values specify the target coding bitrate to be used for each
+     * spatial layer.
+     */
+    unsigned int           ss_target_bitrate[VPX_SS_MAX_LAYERS];
+
     /*!\brief Number of temporal coding layers.
      *
      * This value specifies the number of temporal layers to be used.
-- 
GitLab