diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index ce789e218..4c896b1d1 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 ab27ca523..222086886 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 a4162e942..d7713fd3f 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 edc18dbd3..5537fb508 100644 --- a/vpx/src/svc_encodeframe.c +++ b/vpx/src/svc_encodeframe.c @@ -537,6 +537,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 1d9f0c9b7..851ff1ae8 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.