* 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"
}
#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)
{
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);
}
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);
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);
}
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);
}
}
-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,
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);
* Deinterleave input samples.
* Channels are reordered from Libav's default order to AAC order.
*/
-static void deinterleave_input_samples(AACEncContext *s,
- const float *samples, int nb_samples)
+static void deinterleave_input_samples(AACEncContext *s, const AVFrame *frame)
{
int ch, i;
const int sinc = s->channels;
/* deinterleave and remap input samples */
for (ch = 0; ch < sinc; ch++) {
- const float *sptr = samples + channel_map[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 */
- for (i = 2048; i < 2048 + nb_samples; i++) {
- s->planar_samples[ch][i] = *sptr;
- sptr += sinc;
+ i = 2048;
+ 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;
+ }
}
memset(&s->planar_samples[ch][i], 0,
(3072 - i) * 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, *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 == 2)
return 0;
- deinterleave_input_samples(s, data, data ? avctx->frame_size : 0);
+ /* add current frame to queue */
+ if (frame) {
+ if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
+ return ret;
+ }
+
+ deinterleave_input_samples(s, frame);
if (s->psypp)
ff_psy_preprocess(s->psypp, s->planar_samples, s->channels);
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;
}
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);
+
+ 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);
start_ch = 0;
s->lambda = FFMIN(s->lambda, 65536.f);
}
- if (!data)
+ if (!frame)
s->last_frame++;
- return put_bits_count(&s->pb)>>3;
+ ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
+ &avpkt->duration);
+
+ avpkt->size = put_bits_count(&s->pb) >> 3;
+ *got_packet_ptr = 1;
+ return 0;
}
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);
+#if FF_API_OLD_ENCODE_AUDIO
+ av_freep(&avctx->coded_frame);
+#endif
return 0;
}
{
int ret = 0;
- dsputil_init(&s->dsp, avctx);
+ 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);
for(ch = 0; ch < s->channels; ch++)
s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch;
+#if FF_API_OLD_ENCODE_AUDIO
+ if (!(avctx->coded_frame = avcodec_alloc_frame()))
+ goto alloc_fail;
+#endif
+
return 0;
alloc_fail:
return AVERROR(ENOMEM);
for (i = 0; i < 428; i++)
ff_aac_pow34sf_tab[i] = sqrt(ff_aac_pow2sf_tab[i] * sqrt(ff_aac_pow2sf_tab[i]));
+ avctx->delay = 1024;
+ ff_af_queue_init(avctx, &s->afq);
+
return 0;
fail:
aac_encode_end(avctx);
.id = 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 = 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,
};