X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Faacenc.c;h=d2df65bb6950804845b0ad53fb6fbde6f50d2249;hb=49623f531972be5dc2dd8c1b4b8748cad7c424ff;hp=742fee9cd18514b62ccd48e265101d121b4f5879;hpb=9b8e2a870957293898998209c6e9bed290cc9bef;p=ffmpeg diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 742fee9cd18..d2df65bb695 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -30,10 +30,11 @@ * add temporal noise shaping ***********************************/ +#include "libavutil/float_dsp.h" #include "libavutil/opt.h" #include "avcodec.h" #include "put_bits.h" -#include "dsputil.h" +#include "internal.h" #include "mpeg4audio.h" #include "kbdwin.h" #include "sinewin.h" @@ -180,47 +181,85 @@ static void put_audio_specific_config(AVCodecContext *avctx) flush_put_bits(&pb); } +#define WINDOW_FUNC(type) \ +static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \ + SingleChannelElement *sce, \ + const float *audio) + +WINDOW_FUNC(only_long) +{ + const float *lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024; + const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024; + float *out = sce->ret_buf; + + fdsp->vector_fmul (out, audio, lwindow, 1024); + fdsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024); +} + +WINDOW_FUNC(long_start) +{ + const float *lwindow = sce->ics.use_kb_window[1] ? 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; + float *out = sce->ret_buf; + + fdsp->vector_fmul(out, audio, lwindow, 1024); + memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448); + fdsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128); + memset(out + 1024 + 576, 0, sizeof(out[0]) * 448); +} + +WINDOW_FUNC(long_stop) +{ + 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[1] ? ff_aac_kbd_short_128 : ff_sine_128; + float *out = sce->ret_buf; + + memset(out, 0, sizeof(out[0]) * 448); + fdsp->vector_fmul(out + 448, audio + 448, swindow, 128); + memcpy(out + 576, audio + 576, sizeof(out[0]) * 448); + fdsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024); +} + +WINDOW_FUNC(eight_short) +{ + 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; + const float *in = audio + 448; + float *out = sce->ret_buf; + int w; + + for (w = 0; w < 8; w++) { + fdsp->vector_fmul (out, in, w ? pwindow : swindow, 128); + out += 128; + in += 128; + fdsp->vector_fmul_reverse(out, in, swindow, 128); + out += 128; + } +} + +static void (*const apply_window[4])(AVFloatDSPContext *fdsp, + SingleChannelElement *sce, + const float *audio) = { + [ONLY_LONG_SEQUENCE] = apply_only_long_window, + [LONG_START_SEQUENCE] = apply_long_start_window, + [EIGHT_SHORT_SEQUENCE] = apply_eight_short_window, + [LONG_STOP_SEQUENCE] = apply_long_stop_window +}; + static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce, float *audio) { - int i, k; - 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(output, sce->saved, sizeof(output[0])*1024); - if (sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE) { - memset(output, 0, sizeof(output[0]) * 448); - for (i = 448; i < 576; i++) - output[i] = sce->saved[i] * pwindow[i - 448]; - } - if (sce->ics.window_sequence[0] != LONG_START_SEQUENCE) { - for (i = 0; i < 1024; i++) { - output[i+1024] = audio[i] * lwindow[1024 - i - 1]; - sce->saved[i] = audio[i] * lwindow[i]; - } - } else { - memcpy(output + 1024, audio, sizeof(output[0]) * 448); - for (; i < 576; i++) - output[i+1024] = audio[i] * swindow[576 - i - 1]; - memset(output+1024+576, 0, sizeof(output[0]) * 448); - memcpy(sce->saved, audio, sizeof(sce->saved[0]) * 1024); - } + int i; + float *output = sce->ret_buf; + + apply_window[sce->ics.window_sequence[0]](&s->fdsp, sce, audio); + + if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output); - } else { - for (k = 0; k < 1024; k += 128) { - for (i = 448 + k; i < 448 + k + 256; i++) - output[i - 448 - k] = (i < 1024) - ? sce->saved[i] - : audio[i-1024]; - 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); - } - memcpy(sce->saved, audio, sizeof(sce->saved[0]) * 1024); - } + else + for (i = 0; i < 1024; i += 128) + s->mdct128.mdct_calc(&s->mdct128, sce->coeffs + i, output + i*2); + memcpy(audio, audio + 1024, sizeof(audio[0]) * 1024); } /** @@ -262,7 +301,7 @@ static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe) /** * Produce integer coefficients from scalefactors provided by the model. */ -static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans) +static void adjust_frame_information(ChannelElement *cpe, int chans) { int i, w, w2, g, ch; int start, maxsfb, cmaxsfb; @@ -420,8 +459,7 @@ static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, /** * Write some auxiliary information about the created AAC file. */ -static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, - const char *name) +static void put_bitstream_info(AACEncContext *s, const char *name) { int i, namelen, padbits; @@ -429,9 +467,9 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, put_bits(&s->pb, 3, TYPE_FIL); put_bits(&s->pb, 4, FFMIN(namelen, 15)); if (namelen >= 15) - put_bits(&s->pb, 8, namelen - 16); + put_bits(&s->pb, 8, namelen - 14); put_bits(&s->pb, 4, 0); //extension type - filler - padbits = 8 - (put_bits_count(&s->pb) & 7); + padbits = -put_bits_count(&s->pb) & 7; avpriv_align_put_bits(&s->pb); for (i = 0; i < namelen - 2; i++) put_bits(&s->pb, 8, name[i]); @@ -439,50 +477,54 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, } /* - * Deinterleave input samples. + * Copy input samples. * Channels are reordered from Libav's default order to AAC order. */ -static void deinterleave_input_samples(AACEncContext *s, - const float *samples) +static void copy_input_samples(AACEncContext *s, const AVFrame *frame) { - int ch, i; - const int sinc = s->channels; - const uint8_t *channel_map = aac_chan_maps[sinc - 1]; - - /* deinterleave and remap input samples */ - for (ch = 0; ch < sinc; ch++) { - const float *sptr = samples + channel_map[ch]; + int ch; + int end = 2048 + (frame ? frame->nb_samples : 0); + const uint8_t *channel_map = aac_chan_maps[s->channels - 1]; + /* copy and remap input samples */ + for (ch = 0; ch < s->channels; ch++) { /* copy last 1024 samples of previous frame to the start of the current frame */ - memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][1024], 1024 * sizeof(s->planar_samples[0][0])); + memcpy(&s->planar_samples[ch][1024], &s->planar_samples[ch][2048], 1024 * sizeof(s->planar_samples[0][0])); - /* deinterleave */ - for (i = 1024; i < 1024 * 2; i++) { - s->planar_samples[ch][i] = *sptr; - sptr += sinc; + /* copy new samples and zero any remaining samples */ + if (frame) { + memcpy(&s->planar_samples[ch][2048], + frame->extended_data[channel_map[ch]], + frame->nb_samples * sizeof(s->planar_samples[0][0])); } + memset(&s->planar_samples[ch][end], 0, + (3072 - end) * sizeof(s->planar_samples[0][0])); } } -static int aac_encode_frame(AVCodecContext *avctx, - uint8_t *frame, int buf_size, void *data) +static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) { AACEncContext *s = avctx->priv_data; - float **samples = s->planar_samples, *samples2, *la; + float **samples = s->planar_samples, *samples2, *la, *overlap; ChannelElement *cpe; - int i, ch, w, g, chans, tag, start_ch; + int i, ch, w, g, chans, tag, start_ch, ret; int chan_el_counter[4]; FFPsyWindowInfo windows[AAC_MAX_CHANNELS]; - if (s->last_frame) + if (s->last_frame == 2) return 0; - if (data) { - deinterleave_input_samples(s, data); - if (s->psypp) - ff_psy_preprocess(s->psypp, s->planar_samples, s->channels); + /* add current frame to queue */ + if (frame) { + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) + return ret; } + copy_input_samples(s, frame); + if (s->psypp) + ff_psy_preprocess(s->psypp, s->planar_samples, s->channels); + if (!avctx->frame_number) return 0; @@ -495,9 +537,10 @@ static int aac_encode_frame(AVCodecContext *avctx, for (ch = 0; ch < chans; ch++) { IndividualChannelStream *ics = &cpe->ch[ch].ics; int cur_channel = start_ch + ch; - samples2 = &samples[cur_channel][0]; + overlap = &samples[cur_channel][0]; + samples2 = overlap + 1024; la = samples2 + (448+64); - if (!data) + if (!frame) la = NULL; if (tag == TYPE_LFE) { wi[ch].window_type[0] = ONLY_LONG_SEQUENCE; @@ -524,15 +567,22 @@ static int aac_encode_frame(AVCodecContext *avctx, for (w = 0; w < ics->num_windows; w++) ics->group_len[w] = wi[ch].grouping[w]; - apply_window_and_mdct(s, &cpe->ch[ch], samples2); + apply_window_and_mdct(s, &cpe->ch[ch], overlap); } start_ch += chans; } + if ((ret = ff_alloc_packet(avpkt, 768 * s->channels))) { + av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n"); + return ret; + } + 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); + + init_put_bits(&s->pb, avpkt->data, avpkt->size); + + if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & AV_CODEC_FLAG_BITEXACT)) + put_bitstream_info(s, LIBAVCODEC_IDENT); start_ch = 0; memset(chan_el_counter, 0, sizeof(chan_el_counter)); for (i = 0; i < s->chan_map[0]; i++) { @@ -547,7 +597,7 @@ static int aac_encode_frame(AVCodecContext *avctx, 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->cur_channel = start_ch + ch; s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda); } cpe->common_window = 0; @@ -563,7 +613,7 @@ static int aac_encode_frame(AVCodecContext *avctx, } } } - s->cur_channel = start_ch * 2; + s->cur_channel = start_ch; if (s->options.stereo_mode && cpe->common_window) { if (s->options.stereo_mode > 0) { IndividualChannelStream *ics = &cpe->ch[0].ics; @@ -574,7 +624,7 @@ static int aac_encode_frame(AVCodecContext *avctx, s->coder->search_for_ms(s, cpe, s->lambda); } } - adjust_frame_information(s, cpe, chans); + adjust_frame_information(cpe, chans); if (chans == 2) { put_bits(&s->pb, 1, cpe->common_window); if (cpe->common_window) { @@ -604,16 +654,21 @@ static int aac_encode_frame(AVCodecContext *avctx, avctx->frame_bits = put_bits_count(&s->pb); // rate control stuff - if (!(avctx->flags & CODEC_FLAG_QSCALE)) { + if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) { float ratio = avctx->bit_rate * 1024.0f / avctx->sample_rate / avctx->frame_bits; s->lambda *= ratio; s->lambda = FFMIN(s->lambda, 65536.f); } - if (!data) - s->last_frame = 1; + if (!frame) + s->last_frame++; + + ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts, + &avpkt->duration); - return put_bits_count(&s->pb)>>3; + avpkt->size = put_bits_count(&s->pb) >> 3; + *got_packet_ptr = 1; + return 0; } static av_cold int aac_encode_end(AVCodecContext *avctx) @@ -627,6 +682,7 @@ static av_cold int aac_encode_end(AVCodecContext *avctx) ff_psy_preprocess_end(s->psypp); av_freep(&s->buffer.samples); av_freep(&s->cpe); + ff_af_queue_close(&s->afq); return 0; } @@ -634,7 +690,7 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) { int ret = 0; - dsputil_init(&s->dsp, avctx); + avpriv_float_dsp_init(&s->fdsp, avctx->flags & AV_CODEC_FLAG_BITEXACT); // window init ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); @@ -652,12 +708,13 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s) { - FF_ALLOCZ_OR_GOTO(avctx, s->buffer.samples, 2 * 1024 * s->channels * sizeof(s->buffer.samples[0]), alloc_fail); + int ch; + FF_ALLOCZ_OR_GOTO(avctx, s->buffer.samples, 3 * 1024 * s->channels * sizeof(s->buffer.samples[0]), alloc_fail); FF_ALLOCZ_OR_GOTO(avctx, s->cpe, sizeof(ChannelElement) * s->chan_map[0], alloc_fail); - FF_ALLOCZ_OR_GOTO(avctx, avctx->extradata, 5 + FF_INPUT_BUFFER_PADDING_SIZE, alloc_fail); + FF_ALLOCZ_OR_GOTO(avctx, avctx->extradata, 5 + AV_INPUT_BUFFER_PADDING_SIZE, alloc_fail); - for(int ch = 0; ch < s->channels; ch++) - s->planar_samples[ch] = s->buffer.samples + 2 * 1024 * ch; + for(ch = 0; ch < s->channels; ch++) + s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch; return 0; alloc_fail: @@ -693,10 +750,10 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) s->chan_map = aac_chan_configs[s->channels-1]; - if (ret = dsp_init(avctx, s)) + if ((ret = dsp_init(avctx, s)) < 0) goto fail; - if (ret = alloc_buffers(avctx, s)) + if ((ret = alloc_buffers(avctx, s)) < 0) goto fail; avctx->extradata_size = 5; @@ -708,7 +765,8 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) lengths[1] = ff_aac_num_swb_128[i]; for (i = 0; i < s->chan_map[0]; i++) grouping[i] = s->chan_map[i + 1] == TYPE_CPE; - if (ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping)) + if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, + s->chan_map[0], grouping)) < 0) goto fail; s->psypp = ff_psy_preprocess_init(avctx); s->coder = &ff_aac_coders[2]; @@ -720,6 +778,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) for (i = 0; i < 428; i++) ff_aac_pow34sf_tab[i] = sqrt(ff_aac_pow2sf_tab[i] * sqrt(ff_aac_pow2sf_tab[i])); + avctx->initial_padding = 1024; + ff_af_queue_init(avctx, &s->afq); + return 0; fail: aac_encode_end(avctx); @@ -728,10 +789,10 @@ fail: #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"}, + {"stereo_mode", "Stereo coding method", offsetof(AACEncContext, options.stereo_mode), AV_OPT_TYPE_INT, {.i64 = 0}, -1, 1, AACENC_FLAGS, "stereo_mode"}, + {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, + {"ms_off", "Disable Mid/Side coding", 0, AV_OPT_TYPE_CONST, {.i64 = 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, {.i64 = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, {NULL} }; @@ -744,14 +805,16 @@ static const AVClass aacenc_class = { AVCodec ff_aac_encoder = { .name = "aac", + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_AAC, + .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACEncContext), .init = aac_encode_init, - .encode = aac_encode_frame, + .encode2 = 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_FLT,AV_SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"), - .priv_class = &aacenc_class, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | + AV_CODEC_CAP_EXPERIMENTAL, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, + .priv_class = &aacenc_class, };