X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Faacenc.c;h=e9f6e2ffbfeb93b6d76437e1930943dc6e505a2b;hb=9a07c1332cfe092b57b5758f22b686ca58806c60;hp=952b6149f1d4832b126d75df508cd8bfa2a7b9ef;hpb=ad95307f9251aa8c0e8773727589d3c1986655fc;p=ffmpeg diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 952b6149f1d..e9f6e2ffbfe 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -30,6 +30,7 @@ * add temporal noise shaping ***********************************/ +#include "libavutil/float_dsp.h" #include "libavutil/opt.h" #include "avcodec.h" #include "put_bits.h" @@ -182,7 +183,9 @@ static void put_audio_specific_config(AVCodecContext *avctx) } #define WINDOW_FUNC(type) \ -static void apply_ ##type ##_window(DSPContext *dsp, SingleChannelElement *sce, const float *audio) +static void apply_ ##type ##_window(DSPContext *dsp, AVFloatDSPContext *fdsp, \ + SingleChannelElement *sce, \ + const float *audio) WINDOW_FUNC(only_long) { @@ -190,7 +193,7 @@ WINDOW_FUNC(only_long) const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024; float *out = sce->ret; - dsp->vector_fmul (out, audio, lwindow, 1024); + fdsp->vector_fmul (out, audio, lwindow, 1024); dsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024); } @@ -200,7 +203,7 @@ WINDOW_FUNC(long_start) const float *swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; float *out = sce->ret; - dsp->vector_fmul(out, audio, lwindow, 1024); + fdsp->vector_fmul(out, audio, lwindow, 1024); memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448); dsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128); memset(out + 1024 + 576, 0, sizeof(out[0]) * 448); @@ -213,7 +216,7 @@ WINDOW_FUNC(long_stop) float *out = sce->ret; memset(out, 0, sizeof(out[0]) * 448); - dsp->vector_fmul(out + 448, audio + 448, swindow, 128); + fdsp->vector_fmul(out + 448, audio + 448, swindow, 128); memcpy(out + 576, audio + 576, sizeof(out[0]) * 448); dsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024); } @@ -227,7 +230,7 @@ WINDOW_FUNC(eight_short) int w; for (w = 0; w < 8; w++) { - dsp->vector_fmul (out, in, w ? pwindow : swindow, 128); + fdsp->vector_fmul (out, in, w ? pwindow : swindow, 128); out += 128; in += 128; dsp->vector_fmul_reverse(out, in, swindow, 128); @@ -235,7 +238,9 @@ WINDOW_FUNC(eight_short) } } -static void (*const apply_window[4])(DSPContext *dsp, SingleChannelElement *sce, const float *audio) = { +static void (*const apply_window[4])(DSPContext *dsp, 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, @@ -248,7 +253,7 @@ static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce, int i; float *output = sce->ret; - apply_window[sce->ics.window_sequence[0]](&s->dsp, sce, audio); + apply_window[sce->ics.window_sequence[0]](&s->dsp, &s->fdsp, sce, audio); if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output); @@ -297,7 +302,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; @@ -455,8 +460,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; @@ -474,31 +478,28 @@ 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, AVFrame *frame) +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]; + int ch; + int end = 2048 + (frame ? frame->nb_samples : 0); + const uint8_t *channel_map = aac_chan_maps[s->channels - 1]; - /* deinterleave and remap input samples */ - for (ch = 0; ch < sinc; ch++) { + /* 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][1024], &s->planar_samples[ch][2048], 1024 * sizeof(s->planar_samples[0][0])); - /* deinterleave */ - i = 2048; + /* copy new samples and zero any remaining samples */ if (frame) { - const float *sptr = ((const float *)frame->data[0]) + channel_map[ch]; - for (; i < 2048 + frame->nb_samples; i++) { - s->planar_samples[ch][i] = *sptr; - sptr += sinc; - } + 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][i], 0, - (3072 - i) * sizeof(s->planar_samples[0][0])); + memset(&s->planar_samples[ch][end], 0, + (3072 - end) * sizeof(s->planar_samples[0][0])); } } @@ -521,7 +522,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return ret; } - deinterleave_input_samples(s, frame); + copy_input_samples(s, frame); if (s->psypp) ff_psy_preprocess(s->psypp, s->planar_samples, s->channels); @@ -571,17 +572,18 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } 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; - if ((ret = ff_alloc_packet(avpkt, 768 * s->channels))) { - av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n"); - return ret; - } init_put_bits(&s->pb, avpkt->data, avpkt->size); if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT)) - put_bitstream_info(avctx, s, LIBAVCODEC_IDENT); + 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++) { @@ -623,7 +625,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 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) { @@ -693,6 +695,7 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) int ret = 0; ff_dsputil_init(&s->dsp, avctx); + avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); // window init ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); @@ -795,10 +798,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} }; @@ -812,13 +815,15 @@ static const AVClass aacenc_class = { AVCodec ff_aac_encoder = { .name = "aac", .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_AAC, + .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACEncContext), .init = aac_encode_init, .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 = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | + CODEC_CAP_EXPERIMENTAL, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), + .priv_class = &aacenc_class, };