diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-03-22 02:47:44 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-03-22 03:40:11 +0400 |
commit | 967facb6950549d0cc4e0ba79a056ebc6f93a049 (patch) | |
tree | 872266e5d486be0ab8cf9e378bf567c191fba71a /libavcodec/libmp3lame.c | |
parent | f1fdd208cc0a1fce7aaaf6b0fe72b013525f49e0 (diff) | |
parent | 6aba117f1273c7704312c6d892c9f552fa0661bb (diff) |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (26 commits)
adxenc: use AVCodec.encode2()
adxenc: Use the AVFrame in ADXContext for coded_frame
indeo4: fix out-of-bounds function call.
configure: Restructure help output.
configure: Internal-only components should not be command-line selectable.
vorbisenc: use AVCodec.encode2()
libvorbis: use AVCodec.encode2()
libopencore-amrnbenc: use AVCodec.encode2()
ra144enc: use AVCodec.encode2()
nellymoserenc: use AVCodec.encode2()
roqaudioenc: use AVCodec.encode2()
libspeex: use AVCodec.encode2()
libvo_amrwbenc: use AVCodec.encode2()
libvo_aacenc: use AVCodec.encode2()
wmaenc: use AVCodec.encode2()
mpegaudioenc: use AVCodec.encode2()
libmp3lame: use AVCodec.encode2()
libgsmenc: use AVCodec.encode2()
libfaac: use AVCodec.encode2()
g726enc: use AVCodec.encode2()
...
Conflicts:
configure
libavcodec/Makefile
libavcodec/ac3enc.c
libavcodec/adxenc.c
libavcodec/libgsm.c
libavcodec/libvorbis.c
libavcodec/vorbisenc.c
libavcodec/wmaenc.c
tests/ref/acodec/g722
tests/ref/lavf/asf
tests/ref/lavf/ffm
tests/ref/lavf/mkv
tests/ref/lavf/mpg
tests/ref/lavf/rm
tests/ref/lavf/ts
tests/ref/seek/lavf_asf
tests/ref/seek/lavf_ffm
tests/ref/seek/lavf_mkv
tests/ref/seek/lavf_mpg
tests/ref/seek/lavf_rm
tests/ref/seek/lavf_ts
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/libmp3lame.c')
-rw-r--r-- | libavcodec/libmp3lame.c | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index e8accedc00..686dfc2bb3 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -30,6 +30,7 @@ #include "libavutil/log.h" #include "libavutil/opt.h" #include "avcodec.h" +#include "audio_frame_queue.h" #include "internal.h" #include "mpegaudio.h" #include "mpegaudiodecheader.h" @@ -44,6 +45,7 @@ typedef struct LAMEContext { int buffer_index; int reservoir; void *planar_samples[2]; + AudioFrameQueue afq; } LAMEContext; @@ -51,10 +53,14 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx) { LAMEContext *s = avctx->priv_data; +#if FF_API_OLD_ENCODE_AUDIO av_freep(&avctx->coded_frame); +#endif av_freep(&s->planar_samples[0]); av_freep(&s->planar_samples[1]); + ff_af_queue_close(&s->afq); + lame_close(s->gfp); return 0; } @@ -111,12 +117,19 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) goto error; } + /* get encoder delay */ + avctx->delay = lame_get_encoder_delay(s->gfp) + 528 + 1; + ff_af_queue_init(avctx, &s->afq); + avctx->frame_size = lame_get_framesize(s->gfp); + +#if FF_API_OLD_ENCODE_AUDIO avctx->coded_frame = avcodec_alloc_frame(); if (!avctx->coded_frame) { ret = AVERROR(ENOMEM); goto error; } +#endif /* sample format */ if (avctx->sample_fmt == AV_SAMPLE_FMT_S32 || @@ -144,67 +157,67 @@ error: const type *input = samples; \ type *output = s->planar_samples[ch]; \ input += ch; \ - for (i = 0; i < s->avctx->frame_size; i++) { \ + for (i = 0; i < nb_samples; i++) { \ output[i] = *input * scale; \ input += s->avctx->channels; \ } \ } \ } while (0) -static int encode_frame_int16(LAMEContext *s, void *samples) +static int encode_frame_int16(LAMEContext *s, void *samples, int nb_samples) { if (s->avctx->channels > 1) { return lame_encode_buffer_interleaved(s->gfp, samples, - s->avctx->frame_size, + nb_samples, s->buffer + s->buffer_index, BUFFER_SIZE - s->buffer_index); } else { - return lame_encode_buffer(s->gfp, samples, NULL, s->avctx->frame_size, + return lame_encode_buffer(s->gfp, samples, NULL, nb_samples, s->buffer + s->buffer_index, BUFFER_SIZE - s->buffer_index); } } -static int encode_frame_int32(LAMEContext *s, void *samples) +static int encode_frame_int32(LAMEContext *s, void *samples, int nb_samples) { DEINTERLEAVE(int32_t, 1); return lame_encode_buffer_int(s->gfp, s->planar_samples[0], s->planar_samples[1], - s->avctx->frame_size, + nb_samples, s->buffer + s->buffer_index, BUFFER_SIZE - s->buffer_index); } -static int encode_frame_float(LAMEContext *s, void *samples) +static int encode_frame_float(LAMEContext *s, void *samples, int nb_samples) { DEINTERLEAVE(float, 32768.0f); return lame_encode_buffer_float(s->gfp, s->planar_samples[0], s->planar_samples[1], - s->avctx->frame_size, + nb_samples, s->buffer + s->buffer_index, BUFFER_SIZE - s->buffer_index); } -static int mp3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame, - int buf_size, void *data) +static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) { LAMEContext *s = avctx->priv_data; MPADecodeHeader hdr; - int len; + int len, ret; int lame_result; - if (data) { + if (frame) { switch (avctx->sample_fmt) { case AV_SAMPLE_FMT_S16: - lame_result = encode_frame_int16(s, data); + lame_result = encode_frame_int16(s, frame->data[0], frame->nb_samples); break; case AV_SAMPLE_FMT_S32: - lame_result = encode_frame_int32(s, data); + lame_result = encode_frame_int32(s, frame->data[0], frame->nb_samples); break; case AV_SAMPLE_FMT_FLT: - lame_result = encode_frame_float(s, data); + lame_result = encode_frame_float(s, frame->data[0], frame->nb_samples); break; default: return AVERROR_BUG; @@ -223,6 +236,12 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame, } s->buffer_index += lame_result; + /* add current frame to the queue */ + if (frame) { + if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) + return ret; + } + /* Move 1 frame from the LAME buffer to the output packet, if available. We have to parse the first frame header in the output buffer to determine the frame size. */ @@ -236,12 +255,22 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame, av_dlog(avctx, "in:%d packet-len:%d index:%d\n", avctx->frame_size, len, s->buffer_index); if (len <= s->buffer_index) { - memcpy(frame, s->buffer, len); + if ((ret = ff_alloc_packet(avpkt, len))) { + av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n"); + return ret; + } + memcpy(avpkt->data, s->buffer, len); s->buffer_index -= len; memmove(s->buffer, s->buffer + len, s->buffer_index); - return len; - } else - return 0; + + /* Get the next frame pts/duration */ + ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts, + &avpkt->duration); + + avpkt->size = len; + *got_packet_ptr = 1; + } + return 0; } #define OFFSET(x) offsetof(LAMEContext, x) @@ -273,9 +302,9 @@ AVCodec ff_libmp3lame_encoder = { .id = CODEC_ID_MP3, .priv_data_size = sizeof(LAMEContext), .init = mp3lame_encode_init, - .encode = mp3lame_encode_frame, + .encode2 = mp3lame_encode_frame, .close = mp3lame_encode_close, - .capabilities = CODEC_CAP_DELAY, + .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, |