[FFmpeg-cvslog] aacenc: make a better estimate for the audio bitrate if not provided

Rostislav Pehlivanov git at videolan.org
Fri Feb 12 19:42:37 CET 2016


ffmpeg | branch: master | Rostislav Pehlivanov <atomnuker at gmail.com> | Fri Feb 12 18:34:18 2016 +0000| [f0a8212436c47afca997c4ce3af2da09cc30a4e4] | committer: Rostislav Pehlivanov

aacenc: make a better estimate for the audio bitrate if not provided

Takes into account whether there's pairing and if there's an LFE channel.
An SCE has more bits than CPE/2 since IS and M/S save quite a lot of bits
when channels are paired. And most of the SCEs we have are in surround
layouts which map it to the center channel, which usually carries all of
the dialogue and compression artifacts there are easily audiable.

Also refactors the init function a little bit and labels some parts of it.

Fixes bug #5233

Signed-off-by: Rostislav Pehlivanov <atomnuker at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f0a8212436c47afca997c4ce3af2da09cc30a4e4
---

 libavcodec/aacenc.c |   46 +++++++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 553a5ae..1de266d 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -908,40 +908,50 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
     uint8_t grouping[AAC_MAX_CHANNELS];
     int lengths[2];
 
-    s->channels = avctx->channels;
-    s->chan_map = aac_chan_configs[s->channels-1];
-    s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120;
+    /* Constants */
     s->last_frame_pb_count = 0;
     avctx->extradata_size = 5;
     avctx->frame_size = 1024;
     avctx->initial_padding = 1024;
-    avctx->bit_rate = (int)FFMIN(
-        6144 * s->channels / 1024.0 * avctx->sample_rate,
-        avctx->bit_rate);
-    avctx->profile = avctx->profile == FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW :
-                     avctx->profile;
+    s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120;
+
+    /* Channel map and unspecified bitrate guessing */
+    s->channels = avctx->channels;
+    ERROR_IF(s->channels > AAC_MAX_CHANNELS || s->channels == 7,
+             "Unsupported number of channels: %d\n", s->channels);
+    s->chan_map = aac_chan_configs[s->channels-1];
+    if (!avctx->bit_rate) {
+        for (i = 1; i <= s->chan_map[0]; i++) {
+            avctx->bit_rate += s->chan_map[i] == TYPE_CPE ? 128000 : /* Pair */
+                               s->chan_map[i] == TYPE_LFE ? 16000  : /* LFE  */
+                                                            69000  ; /* SCE  */
+        }
+    }
 
+    /* Samplerate */
     for (i = 0; i < 16; i++)
         if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])
             break;
     s->samplerate_index = i;
-
     ERROR_IF(s->samplerate_index == 16 ||
              s->samplerate_index >= ff_aac_swb_size_1024_len ||
              s->samplerate_index >= ff_aac_swb_size_128_len,
              "Unsupported sample rate %d\n", avctx->sample_rate);
-    ERROR_IF(s->channels > AAC_MAX_CHANNELS || s->channels == 7,
-             "Unsupported number of channels: %d\n", s->channels);
+
+    /* Bitrate limiting */
     WARN_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels,
              "Too many bits %f > %d per frame requested, clamping to max\n",
              1024.0 * avctx->bit_rate / avctx->sample_rate,
              6144 * s->channels);
+    avctx->bit_rate = (int64_t)FFMIN(6144 * s->channels / 1024.0 * avctx->sample_rate,
+                                     avctx->bit_rate);
 
+    /* Profile and option setting */
+    avctx->profile = avctx->profile == FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW :
+                     avctx->profile;
     for (i = 0; i < FF_ARRAY_ELEMS(aacenc_profiles); i++)
         if (avctx->profile == aacenc_profiles[i])
             break;
-    ERROR_IF(i == FF_ARRAY_ELEMS(aacenc_profiles),
-             "Unsupported encoding profile: %d\n", avctx->profile);
     if (avctx->profile == FF_PROFILE_MPEG2_AAC_LOW) {
         avctx->profile = FF_PROFILE_AAC_LOW;
         ERROR_IF(s->options.pred,
@@ -973,15 +983,15 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
                  "LTP prediction unavailable in the \"aac_main\" profile\n");
     }
     s->profile = avctx->profile;
-    s->coder = &ff_aac_coders[s->options.coder];
 
+    /* Coder limitations */
+    s->coder = &ff_aac_coders[s->options.coder];
     if (s->options.coder != AAC_CODER_TWOLOOP) {
         ERROR_IF(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL,
                  "Coders other than twoloop require -strict -2 and some may be removed in the future\n");
         s->options.intensity_stereo = 0;
         s->options.pns = 0;
     }
-
     ERROR_IF(s->options.ltp && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL,
              "The LPT profile requires experimental compliance, add -strict -2 to enable!\n");
 
@@ -1042,6 +1052,11 @@ static const AVClass aacenc_class = {
     LIBAVUTIL_VERSION_INT,
 };
 
+static const AVCodecDefault aac_encode_defaults[] = {
+    { "b", "0" },
+    { NULL }
+};
+
 AVCodec ff_aac_encoder = {
     .name           = "aac",
     .long_name      = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
@@ -1051,6 +1066,7 @@ AVCodec ff_aac_encoder = {
     .init           = aac_encode_init,
     .encode2        = aac_encode_frame,
     .close          = aac_encode_end,
+    .defaults       = aac_encode_defaults,
     .supported_samplerates = mpeg4audio_sample_rates,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .capabilities   = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,



More information about the ffmpeg-cvslog mailing list