only call av1_alloc_layer_context() w/num_layers > 1
this avoids an unnecessary allocation when not doing SVC encoding; saves
~13K
Change-Id: I3804c27f67d0f6fb639c3f003a2aceccdc1de0bd
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index d1f027f..c5f9f1e 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -2896,7 +2896,9 @@
const int num_layers =
cpi->svc.number_spatial_layers * cpi->svc.number_temporal_layers;
- if (!av1_alloc_layer_context(cpi, num_layers)) return AOM_CODEC_MEM_ERROR;
+ if (num_layers > 1 && !av1_alloc_layer_context(cpi, num_layers)) {
+ return AOM_CODEC_MEM_ERROR;
+ }
// Set up internal flags
if (ctx->base.init_flags & AOM_CODEC_USE_PSNR) ppi->b_calculate_psnr = 1;
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 9518480..45d6818 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -3068,19 +3068,21 @@
if (qindex <= 120 * p_rc->last_q[INTER_FRAME] / 100)
p_rc->rate_correction_factors[INTER_NORMAL] *= 1.5;
}
- // Apply the same rate control reset to all temporal layers.
- for (int tl = 0; tl < svc->number_temporal_layers; tl++) {
- LAYER_CONTEXT *lc = NULL;
- lc = &svc->layer_context[svc->spatial_layer_id *
- svc->number_temporal_layers +
- tl];
- lc->rc.resize_state = rc->resize_state;
- lc->p_rc.buffer_level = lc->p_rc.optimal_buffer_level;
- lc->p_rc.bits_off_target = lc->p_rc.optimal_buffer_level;
- lc->p_rc.rate_correction_factors[INTER_NORMAL] =
- p_rc->rate_correction_factors[INTER_NORMAL];
- lc->p_rc.avg_frame_qindex[INTER_FRAME] =
- p_rc->avg_frame_qindex[INTER_FRAME];
+ if (svc->number_temporal_layers > 1) {
+ // Apply the same rate control reset to all temporal layers.
+ for (int tl = 0; tl < svc->number_temporal_layers; tl++) {
+ LAYER_CONTEXT *lc = NULL;
+ lc = &svc->layer_context[svc->spatial_layer_id *
+ svc->number_temporal_layers +
+ tl];
+ lc->rc.resize_state = rc->resize_state;
+ lc->p_rc.buffer_level = lc->p_rc.optimal_buffer_level;
+ lc->p_rc.bits_off_target = lc->p_rc.optimal_buffer_level;
+ lc->p_rc.rate_correction_factors[INTER_NORMAL] =
+ p_rc->rate_correction_factors[INTER_NORMAL];
+ lc->p_rc.avg_frame_qindex[INTER_FRAME] =
+ p_rc->avg_frame_qindex[INTER_FRAME];
+ }
}
}
diff --git a/av1/encoder/svc_layercontext.c b/av1/encoder/svc_layercontext.c
index d31f55d..919bc89 100644
--- a/av1/encoder/svc_layercontext.c
+++ b/av1/encoder/svc_layercontext.c
@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <assert.h>
#include <math.h>
#include "av1/encoder/encoder.h"
@@ -84,6 +85,7 @@
bool av1_alloc_layer_context(AV1_COMP *cpi, int num_layers) {
SVC *const svc = &cpi->svc;
if (svc->layer_context == NULL || svc->num_allocated_layers < num_layers) {
+ assert(num_layers > 1);
aom_free(svc->layer_context);
svc->num_allocated_layers = 0;
svc->layer_context =
diff --git a/av1/ratectrl_rtc.cc b/av1/ratectrl_rtc.cc
index 6cf53f0..4bd861d 100644
--- a/av1/ratectrl_rtc.cc
+++ b/av1/ratectrl_rtc.cc
@@ -69,7 +69,9 @@
rc_api->cpi_->common.seq_params = &rc_api->cpi_->ppi->seq_params;
av1_zero(*rc_api->cpi_->common.seq_params);
const int num_layers = cfg.ss_number_layers * cfg.ts_number_layers;
- if (!av1_alloc_layer_context(rc_api->cpi_, num_layers)) return nullptr;
+ if (num_layers > 1 && !av1_alloc_layer_context(rc_api->cpi_, num_layers)) {
+ return nullptr;
+ }
rc_api->InitRateControl(cfg);
if (cfg.aq_mode) {
AV1_COMP *const cpi = rc_api->cpi_;
@@ -180,29 +182,31 @@
cpi_->svc.number_temporal_layers = rc_cfg.ts_number_layers;
set_primary_rc_buffer_sizes(oxcf, cpi_->ppi);
enc_set_mb_mi(&cm->mi_params, cm->width, cm->height, BLOCK_8X8);
- int64_t target_bandwidth_svc = 0;
- for (int sl = 0; sl < cpi_->svc.number_spatial_layers; ++sl) {
- for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) {
- const int layer =
- LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers);
- LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
- RATE_CONTROL *const lrc = &lc->rc;
- lc->layer_target_bitrate = 1000 * rc_cfg.layer_target_bitrate[layer];
- lc->max_q = rc_cfg.max_quantizers[layer];
- lc->min_q = rc_cfg.min_quantizers[layer];
- lrc->worst_quality =
- av1_quantizer_to_qindex(rc_cfg.max_quantizers[layer]);
- lrc->best_quality = av1_quantizer_to_qindex(rc_cfg.min_quantizers[layer]);
- lc->scaling_factor_num = rc_cfg.scaling_factor_num[sl];
- lc->scaling_factor_den = rc_cfg.scaling_factor_den[sl];
- lc->framerate_factor = rc_cfg.ts_rate_decimator[tl];
- if (tl == cpi_->svc.number_temporal_layers - 1)
- target_bandwidth_svc += lc->layer_target_bitrate;
- }
- }
av1_new_framerate(cpi_, cpi_->framerate);
if (cpi_->svc.number_temporal_layers > 1 ||
cpi_->svc.number_spatial_layers > 1) {
+ int64_t target_bandwidth_svc = 0;
+ for (int sl = 0; sl < cpi_->svc.number_spatial_layers; ++sl) {
+ for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) {
+ const int layer =
+ LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers);
+ LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
+ RATE_CONTROL *const lrc = &lc->rc;
+ lc->layer_target_bitrate = 1000 * rc_cfg.layer_target_bitrate[layer];
+ lc->max_q = rc_cfg.max_quantizers[layer];
+ lc->min_q = rc_cfg.min_quantizers[layer];
+ lrc->worst_quality =
+ av1_quantizer_to_qindex(rc_cfg.max_quantizers[layer]);
+ lrc->best_quality =
+ av1_quantizer_to_qindex(rc_cfg.min_quantizers[layer]);
+ lc->scaling_factor_num = rc_cfg.scaling_factor_num[sl];
+ lc->scaling_factor_den = rc_cfg.scaling_factor_den[sl];
+ lc->framerate_factor = rc_cfg.ts_rate_decimator[tl];
+ if (tl == cpi_->svc.number_temporal_layers - 1)
+ target_bandwidth_svc += lc->layer_target_bitrate;
+ }
+ }
+
if (cm->current_frame.frame_number == 0) av1_init_layer_context(cpi_);
// This is needed to initialize external RC flag in layer context structure.
cpi_->rc.rtc_external_ratectrl = 1;