X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Faacenc.c;h=b112fa855547c7c3e4338a3462afa2c0ed5be579;hb=9f51c682ee83ecf0995648d4574ac09b52bbcb24;hp=93dbadc2bf11425f7ff49fbba66e55dbb92e11ce;hpb=5962f6b0da037da30fcc848331afa6a081a4eb09;p=ffmpeg diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 93dbadc2bf1..b112fa85554 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -2,25 +2,25 @@ * AAC encoder * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file libavcodec/aacenc.c + * @file * AAC encoder */ @@ -30,10 +30,13 @@ * add temporal noise shaping ***********************************/ +#include "libavutil/opt.h" #include "avcodec.h" #include "put_bits.h" #include "dsputil.h" #include "mpeg4audio.h" +#include "kbdwin.h" +#include "sinewin.h" #include "aac.h" #include "aactab.h" @@ -41,6 +44,8 @@ #include "psymodel.h" +#define AAC_MAX_CHANNELS 6 + static const uint8_t swb_size_1024_96[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, @@ -147,6 +152,11 @@ static void put_audio_specific_config(AVCodecContext *avctx) put_bits(&pb, 1, 0); //frame length - 1024 samples put_bits(&pb, 1, 0); //does not depend on core coder put_bits(&pb, 1, 0); //is not extension + + //Explicitly Mark SBR absent + put_bits(&pb, 11, 0x2b7); //sync extension + put_bits(&pb, 5, AOT_SBR); + put_bits(&pb, 1, 0); flush_put_bits(&pb); } @@ -155,21 +165,30 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) AACEncContext *s = avctx->priv_data; int i; const uint8_t *sizes[2]; + uint8_t grouping[AAC_MAX_CHANNELS]; int lengths[2]; avctx->frame_size = 1024; for (i = 0; i < 16; i++) - if (avctx->sample_rate == ff_mpeg4audio_sample_rates[i]) + if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i]) break; if (i == 16) { av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate); return -1; } - if (avctx->channels > 6) { + if (avctx->channels > AAC_MAX_CHANNELS) { av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", avctx->channels); return -1; } + if (avctx->profile != FF_PROFILE_UNKNOWN && avctx->profile != FF_PROFILE_AAC_LOW) { + av_log(avctx, AV_LOG_ERROR, "Unsupported profile %d\n", avctx->profile); + return -1; + } + if (1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "Too many bits per frame requested\n"); + return -1; + } s->samplerate_index = i; dsputil_init(&s->dsp, avctx); @@ -178,85 +197,79 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) // window init ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); - ff_sine_window_init(ff_sine_1024, 1024); - ff_sine_window_init(ff_sine_128, 128); + ff_init_ff_sine_windows(10); + ff_init_ff_sine_windows(7); + s->chan_map = aac_chan_configs[avctx->channels-1]; s->samples = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0])); - s->cpe = av_mallocz(sizeof(ChannelElement) * aac_chan_configs[avctx->channels-1][0]); - avctx->extradata = av_malloc(2); - avctx->extradata_size = 2; + s->cpe = av_mallocz(sizeof(ChannelElement) * s->chan_map[0]); + avctx->extradata = av_mallocz(5 + FF_INPUT_BUFFER_PADDING_SIZE); + avctx->extradata_size = 5; put_audio_specific_config(avctx); sizes[0] = swb_size_1024[i]; sizes[1] = swb_size_128[i]; lengths[0] = ff_aac_num_swb_1024[i]; lengths[1] = ff_aac_num_swb_128[i]; - ff_psy_init(&s->psy, avctx, 2, sizes, lengths); + for (i = 0; i < s->chan_map[0]; i++) + grouping[i] = s->chan_map[i + 1] == TYPE_CPE; + ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping); s->psypp = ff_psy_preprocess_init(avctx); - s->coder = &ff_aac_coders[0]; + s->coder = &ff_aac_coders[2]; s->lambda = avctx->global_quality ? avctx->global_quality : 120; -#if !CONFIG_HARDCODED_TABLES - for (i = 0; i < 428; i++) - ff_aac_pow2sf_tab[i] = pow(2, (i - 200)/4.); -#endif /* CONFIG_HARDCODED_TABLES */ - if (avctx->channels > 5) - av_log(avctx, AV_LOG_ERROR, "This encoder does not yet enforce the restrictions on LFEs. " - "The output will most likely be an illegal bitstream.\n"); + ff_aac_tableinit(); return 0; } static void apply_window_and_mdct(AVCodecContext *avctx, AACEncContext *s, - SingleChannelElement *sce, short *audio, int channel) + SingleChannelElement *sce, short *audio) { - int i, j, k; + int i, k; + const int chans = avctx->channels; const float * lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024; const float * swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; const float * pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128; + float *output = sce->ret; if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { - memcpy(s->output, sce->saved, sizeof(float)*1024); + memcpy(output, sce->saved, sizeof(float)*1024); if (sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE) { - memset(s->output, 0, sizeof(s->output[0]) * 448); + memset(output, 0, sizeof(output[0]) * 448); for (i = 448; i < 576; i++) - s->output[i] = sce->saved[i] * pwindow[i - 448]; + output[i] = sce->saved[i] * pwindow[i - 448]; for (i = 576; i < 704; i++) - s->output[i] = sce->saved[i]; + output[i] = sce->saved[i]; } if (sce->ics.window_sequence[0] != LONG_START_SEQUENCE) { - j = channel; - for (i = 0; i < 1024; i++, j += avctx->channels) { - s->output[i+1024] = audio[j] * lwindow[1024 - i - 1]; - sce->saved[i] = audio[j] * lwindow[i]; + for (i = 0; i < 1024; i++) { + output[i+1024] = audio[i * chans] * lwindow[1024 - i - 1]; + sce->saved[i] = audio[i * chans] * lwindow[i]; } } else { - j = channel; - for (i = 0; i < 448; i++, j += avctx->channels) - s->output[i+1024] = audio[j]; - for (i = 448; i < 576; i++, j += avctx->channels) - s->output[i+1024] = audio[j] * swindow[576 - i - 1]; - memset(s->output+1024+576, 0, sizeof(s->output[0]) * 448); - j = channel; - for (i = 0; i < 1024; i++, j += avctx->channels) - sce->saved[i] = audio[j]; + for (i = 0; i < 448; i++) + output[i+1024] = audio[i * chans]; + for (; i < 576; i++) + output[i+1024] = audio[i * chans] * swindow[576 - i - 1]; + memset(output+1024+576, 0, sizeof(output[0]) * 448); + for (i = 0; i < 1024; i++) + sce->saved[i] = audio[i * chans]; } - ff_mdct_calc(&s->mdct1024, sce->coeffs, s->output); + s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output); } else { - j = channel; for (k = 0; k < 1024; k += 128) { for (i = 448 + k; i < 448 + k + 256; i++) - s->output[i - 448 - k] = (i < 1024) + output[i - 448 - k] = (i < 1024) ? sce->saved[i] - : audio[channel + (i-1024)*avctx->channels]; - s->dsp.vector_fmul (s->output, k ? swindow : pwindow, 128); - s->dsp.vector_fmul_reverse(s->output+128, s->output+128, swindow, 128); - ff_mdct_calc(&s->mdct128, sce->coeffs + k, s->output); + : audio[(i-1024)*chans]; + s->dsp.vector_fmul (output, output, k ? swindow : pwindow, 128); + s->dsp.vector_fmul_reverse(output+128, output+128, swindow, 128); + s->mdct128.mdct_calc(&s->mdct128, sce->coeffs + k, output); } - j = channel; - for (i = 0; i < 1024; i++, j += avctx->channels) - sce->saved[i] = audio[j]; + for (i = 0; i < 1024; i++) + sce->saved[i] = audio[i * chans]; } } @@ -302,7 +315,7 @@ static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe) static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans) { int i, w, w2, g, ch; - int start, sum, maxsfb, cmaxsfb; + int start, maxsfb, cmaxsfb; for (ch = 0; ch < chans; ch++) { IndividualChannelStream *ics = &cpe->ch[ch].ics; @@ -311,9 +324,8 @@ static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, in cpe->ch[ch].pulse.num_pulse = 0; for (w = 0; w < ics->num_windows*16; w += 16) { for (g = 0; g < ics->num_swb; g++) { - sum = 0; //apply M/S - if (!ch && cpe->ms_mask[w + g]) { + if (cpe->common_window && !ch && cpe->ms_mask[w + g]) { for (i = 0; i < ics->swb_sizes[g]; i++) { cpe->ch[0].coeffs[start+i] = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0; cpe->ch[1].coeffs[start+i] = cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i]; @@ -355,7 +367,7 @@ static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, in if (msc == 0 || ics0->max_sfb == 0) cpe->ms_mode = 0; else - cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2; + cpe->ms_mode = msc < ics0->max_sfb * ics0->num_windows ? 1 : 2; } } @@ -470,7 +482,7 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, put_bits(&s->pb, 8, namelen - 16); put_bits(&s->pb, 4, 0); //extension type - filler padbits = 8 - (put_bits_count(&s->pb) & 7); - align_put_bits(&s->pb); + avpriv_align_put_bits(&s->pb); for (i = 0; i < namelen - 2; i++) put_bits(&s->pb, 8, name[i]); put_bits(&s->pb, 12 - padbits, 0); @@ -482,10 +494,9 @@ static int aac_encode_frame(AVCodecContext *avctx, AACEncContext *s = avctx->priv_data; int16_t *samples = s->samples, *samples2, *la; ChannelElement *cpe; - int i, j, chans, tag, start_ch; - const uint8_t *chan_map = aac_chan_configs[avctx->channels-1]; + int i, ch, w, g, chans, tag, start_ch; int chan_el_counter[4]; - FFPsyWindowInfo windows[avctx->channels]; + FFPsyWindowInfo windows[AAC_MAX_CHANNELS]; if (s->last_frame) return 0; @@ -496,8 +507,8 @@ static int aac_encode_frame(AVCodecContext *avctx, } else { start_ch = 0; samples2 = s->samples + 1024 * avctx->channels; - for (i = 0; i < chan_map[0]; i++) { - tag = chan_map[i+1]; + for (i = 0; i < s->chan_map[0]; i++) { + tag = s->chan_map[i+1]; chans = tag == TYPE_CPE ? 2 : 1; ff_psy_preprocess(s->psypp, (uint16_t*)data + start_ch, samples2 + start_ch, start_ch, chans); @@ -512,79 +523,117 @@ static int aac_encode_frame(AVCodecContext *avctx, } start_ch = 0; - for (i = 0; i < chan_map[0]; i++) { + for (i = 0; i < s->chan_map[0]; i++) { FFPsyWindowInfo* wi = windows + start_ch; - tag = chan_map[i+1]; + tag = s->chan_map[i+1]; chans = tag == TYPE_CPE ? 2 : 1; cpe = &s->cpe[i]; - samples2 = samples + start_ch; - la = samples2 + 1024 * avctx->channels + start_ch; - if (!data) - la = NULL; - for (j = 0; j < chans; j++) { - IndividualChannelStream *ics = &cpe->ch[j].ics; - int k; - wi[j] = ff_psy_suggest_window(&s->psy, samples2, la, start_ch + j, ics->window_sequence[0]); + for (ch = 0; ch < chans; ch++) { + IndividualChannelStream *ics = &cpe->ch[ch].ics; + int cur_channel = start_ch + ch; + samples2 = samples + cur_channel; + la = samples2 + (448+64) * avctx->channels; + if (!data) + la = NULL; + if (tag == TYPE_LFE) { + wi[ch].window_type[0] = ONLY_LONG_SEQUENCE; + wi[ch].window_shape = 0; + wi[ch].num_windows = 1; + wi[ch].grouping[0] = 1; + + /* Only the lowest 12 coefficients are used in a LFE channel. + * The expression below results in only the bottom 8 coefficients + * being used for 11.025kHz to 16kHz sample rates. + */ + ics->num_swb = s->samplerate_index >= 8 ? 1 : 3; + } else { + wi[ch] = s->psy.model->window(&s->psy, samples2, la, cur_channel, + ics->window_sequence[0]); + } ics->window_sequence[1] = ics->window_sequence[0]; - ics->window_sequence[0] = wi[j].window_type[0]; + ics->window_sequence[0] = wi[ch].window_type[0]; ics->use_kb_window[1] = ics->use_kb_window[0]; - ics->use_kb_window[0] = wi[j].window_shape; - ics->num_windows = wi[j].num_windows; + ics->use_kb_window[0] = wi[ch].window_shape; + ics->num_windows = wi[ch].num_windows; ics->swb_sizes = s->psy.bands [ics->num_windows == 8]; - ics->num_swb = s->psy.num_bands[ics->num_windows == 8]; - for (k = 0; k < ics->num_windows; k++) - ics->group_len[k] = wi[j].grouping[k]; + ics->num_swb = tag == TYPE_LFE ? ics->num_swb : s->psy.num_bands[ics->num_windows == 8]; + for (w = 0; w < ics->num_windows; w++) + ics->group_len[w] = wi[ch].grouping[w]; - s->cur_channel = start_ch + j; - apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j); + apply_window_and_mdct(avctx, s, &cpe->ch[ch], samples2); } start_ch += chans; } - init_put_bits(&s->pb, frame, buf_size*8); - if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT)) - put_bitstream_info(avctx, s, LIBAVCODEC_IDENT); - start_ch = 0; - memset(chan_el_counter, 0, sizeof(chan_el_counter)); - for (i = 0; i < chan_map[0]; i++) { - FFPsyWindowInfo* wi = windows + start_ch; - tag = chan_map[i+1]; - chans = tag == TYPE_CPE ? 2 : 1; - cpe = &s->cpe[i]; - for (j = 0; j < chans; j++) { - s->coder->search_for_quantizers(avctx, s, &cpe->ch[j], s->lambda); - } - cpe->common_window = 0; - if (chans > 1 - && wi[0].window_type[0] == wi[1].window_type[0] - && wi[0].window_shape == wi[1].window_shape) { - - cpe->common_window = 1; - for (j = 0; j < wi[0].num_windows; j++) { - if (wi[0].grouping[j] != wi[1].grouping[j]) { - cpe->common_window = 0; - break; + do { + int frame_bits; + init_put_bits(&s->pb, frame, buf_size*8); + if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT)) + put_bitstream_info(avctx, s, LIBAVCODEC_IDENT); + start_ch = 0; + memset(chan_el_counter, 0, sizeof(chan_el_counter)); + for (i = 0; i < s->chan_map[0]; i++) { + FFPsyWindowInfo* wi = windows + start_ch; + const float *coeffs[2]; + tag = s->chan_map[i+1]; + chans = tag == TYPE_CPE ? 2 : 1; + cpe = &s->cpe[i]; + put_bits(&s->pb, 3, tag); + put_bits(&s->pb, 4, chan_el_counter[tag]++); + for (ch = 0; ch < chans; ch++) + coeffs[ch] = cpe->ch[ch].coeffs; + s->psy.model->analyze(&s->psy, start_ch, coeffs, wi); + for (ch = 0; ch < chans; ch++) { + s->cur_channel = start_ch * 2 + ch; + s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda); + } + cpe->common_window = 0; + if (chans > 1 + && wi[0].window_type[0] == wi[1].window_type[0] + && wi[0].window_shape == wi[1].window_shape) { + + cpe->common_window = 1; + for (w = 0; w < wi[0].num_windows; w++) { + if (wi[0].grouping[w] != wi[1].grouping[w]) { + cpe->common_window = 0; + break; + } } } - } - if (cpe->common_window && s->coder->search_for_ms) - s->coder->search_for_ms(s, cpe, s->lambda); - adjust_frame_information(s, cpe, chans); - put_bits(&s->pb, 3, tag); - put_bits(&s->pb, 4, chan_el_counter[tag]++); - if (chans == 2) { - put_bits(&s->pb, 1, cpe->common_window); - if (cpe->common_window) { - put_ics_info(s, &cpe->ch[0].ics); - encode_ms_info(&s->pb, cpe); + s->cur_channel = start_ch * 2; + if (s->options.stereo_mode && cpe->common_window) { + if (s->options.stereo_mode > 0) { + IndividualChannelStream *ics = &cpe->ch[0].ics; + for (w = 0; w < ics->num_windows; w += ics->group_len[w]) + for (g = 0; g < ics->num_swb; g++) + cpe->ms_mask[w*16+g] = 1; + } else if (s->coder->search_for_ms) { + s->coder->search_for_ms(s, cpe, s->lambda); + } + } + adjust_frame_information(s, cpe, chans); + if (chans == 2) { + put_bits(&s->pb, 1, cpe->common_window); + if (cpe->common_window) { + put_ics_info(s, &cpe->ch[0].ics); + encode_ms_info(&s->pb, cpe); + } + } + for (ch = 0; ch < chans; ch++) { + s->cur_channel = start_ch + ch; + encode_individual_channel(avctx, s, &cpe->ch[ch], cpe->common_window); } + start_ch += chans; } - for (j = 0; j < chans; j++) { - s->cur_channel = start_ch + j; - ff_psy_set_band_info(&s->psy, s->cur_channel, cpe->ch[j].coeffs, &wi[j]); - encode_individual_channel(avctx, s, &cpe->ch[j], cpe->common_window); + + frame_bits = put_bits_count(&s->pb); + if (frame_bits <= 6144 * avctx->channels - 3) { + s->psy.bitres.bits = frame_bits / avctx->channels; + break; } - start_ch += chans; - } + + s->lambda *= avctx->bit_rate * 1024.0f / avctx->sample_rate / frame_bits; + + } while (1); put_bits(&s->pb, 3, TYPE_END); flush_put_bits(&s->pb); @@ -594,13 +643,9 @@ static int aac_encode_frame(AVCodecContext *avctx, if (!(avctx->flags & CODEC_FLAG_QSCALE)) { float ratio = avctx->bit_rate * 1024.0f / avctx->sample_rate / avctx->frame_bits; s->lambda *= ratio; - s->lambda = fminf(s->lambda, 65536.f); + s->lambda = FFMIN(s->lambda, 65536.f); } - if (avctx->frame_bits > 6144*avctx->channels) - av_log(avctx, AV_LOG_ERROR, "input buffer violation %d > %d.\n", - avctx->frame_bits, 6144*avctx->channels); - if (!data) s->last_frame = 1; memcpy(s->samples, s->samples + 1024 * avctx->channels, @@ -621,15 +666,32 @@ static av_cold int aac_encode_end(AVCodecContext *avctx) return 0; } -AVCodec aac_encoder = { - "aac", - CODEC_TYPE_AUDIO, - CODEC_ID_AAC, - sizeof(AACEncContext), - aac_encode_init, - aac_encode_frame, - aac_encode_end, - .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, - .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, +#define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM +static const AVOption aacenc_options[] = { + {"stereo_mode", "Stereo coding method", offsetof(AACEncContext, options.stereo_mode), AV_OPT_TYPE_INT, {.dbl = 0}, -1, 1, AACENC_FLAGS, "stereo_mode"}, + {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, + {"ms_off", "Disable Mid/Side coding", 0, AV_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, + {"ms_force", "Force Mid/Side for the whole frame if possible", 0, AV_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, + {NULL} +}; + +static const AVClass aacenc_class = { + "AAC encoder", + av_default_item_name, + aacenc_options, + LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_aac_encoder = { + .name = "aac", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_AAC, + .priv_data_size = sizeof(AACEncContext), + .init = aac_encode_init, + .encode = aac_encode_frame, + .close = aac_encode_end, + .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, + .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"), + .priv_class = &aacenc_class, };