diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-02-21 05:49:41 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-02-21 08:10:12 +0400 |
commit | eadd4264ee4319abf9ec2f618ff925d7529f20ed (patch) | |
tree | 4251d4eb25af927cb290e24d1b6957d584638403 /libavcodec/libmp3lame.c | |
parent | a923b6b8f4f90d09c7c39cc8bfab7ee9d30a2843 (diff) | |
parent | 770a5c6d025e9c8eb3f5aba9cf1d7d7938fb918a (diff) |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (36 commits)
adpcmenc: Use correct frame_size for Yamaha ADPCM.
avcodec: add ff_samples_to_time_base() convenience function to internal.h
adx parser: set duration
mlp parser: set duration instead of frame_size
gsm parser: set duration
mpegaudio parser: set duration instead of frame_size
(e)ac3 parser: set duration instead of frame_size
flac parser: set duration instead of frame_size
avcodec: add duration field to AVCodecParserContext
avutil: add av_rescale_q_rnd() to allow different rounding
pnmdec: remove useless .pix_fmts
libmp3lame: support float and s32 sample formats
libmp3lame: renaming, rearrangement, alignment, and comments
libmp3lame: use the LAME default bit rate
libmp3lame: use avpriv_mpegaudio_decode_header() for output frame parsing
libmp3lame: cosmetics: remove some pointless comments
libmp3lame: convert some debugging code to av_dlog()
libmp3lame: remove outdated comment.
libmp3lame: do not set coded_frame->key_frame.
libmp3lame: improve error handling in MP3lame_encode_init()
...
Conflicts:
doc/APIchanges
libavcodec/libmp3lame.c
libavcodec/pcxenc.c
libavcodec/pnmdec.c
libavcodec/pnmenc.c
libavcodec/sgienc.c
libavcodec/utils.c
libavformat/hls.c
libavutil/avutil.h
libswscale/x86/swscale_mmx.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/libmp3lame.c')
-rw-r--r-- | libavcodec/libmp3lame.c | 353 |
1 files changed, 164 insertions, 189 deletions
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index d75183e9c0..e8accedc00 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -24,261 +24,227 @@ * Interface to libmp3lame for mp3 encoding. */ +#include <lame/lame.h> + #include "libavutil/intreadwrite.h" #include "libavutil/log.h" #include "libavutil/opt.h" #include "avcodec.h" +#include "internal.h" #include "mpegaudio.h" -#include <lame/lame.h> +#include "mpegaudiodecheader.h" #define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4+1000) // FIXME: Buffer size to small? Adding 1000 to make up for it. -typedef struct Mp3AudioContext { + +typedef struct LAMEContext { AVClass *class; + AVCodecContext *avctx; lame_global_flags *gfp; - int stereo; uint8_t buffer[BUFFER_SIZE]; int buffer_index; - struct { - int *left; - int *right; - } s32_data; int reservoir; -} Mp3AudioContext; + void *planar_samples[2]; +} LAMEContext; + -static av_cold int MP3lame_encode_init(AVCodecContext *avctx) +static av_cold int mp3lame_encode_close(AVCodecContext *avctx) { - Mp3AudioContext *s = avctx->priv_data; + LAMEContext *s = avctx->priv_data; + av_freep(&avctx->coded_frame); + av_freep(&s->planar_samples[0]); + av_freep(&s->planar_samples[1]); + + lame_close(s->gfp); + return 0; +} + +static av_cold int mp3lame_encode_init(AVCodecContext *avctx) +{ + LAMEContext *s = avctx->priv_data; + int ret; + + s->avctx = avctx; + + /* initialize LAME and get defaults */ + if ((s->gfp = lame_init()) == NULL) + return AVERROR(ENOMEM); + + /* channels */ if (avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "Invalid number of channels %d, must be <= 2\n", avctx->channels); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto error; } + lame_set_num_channels(s->gfp, avctx->channels); + lame_set_mode(s->gfp, avctx->channels > 1 ? JOINT_STEREO : MONO); - s->stereo = avctx->channels > 1 ? 1 : 0; - - if ((s->gfp = lame_init()) == NULL) - goto err; - lame_set_in_samplerate(s->gfp, avctx->sample_rate); + /* sample rate */ + lame_set_in_samplerate (s->gfp, avctx->sample_rate); lame_set_out_samplerate(s->gfp, avctx->sample_rate); - lame_set_num_channels(s->gfp, avctx->channels); - if (avctx->compression_level == FF_COMPRESSION_DEFAULT) { + + /* algorithmic quality */ + if (avctx->compression_level == FF_COMPRESSION_DEFAULT) lame_set_quality(s->gfp, 5); - } else { + else lame_set_quality(s->gfp, avctx->compression_level); - } - lame_set_mode(s->gfp, s->stereo ? JOINT_STEREO : MONO); - lame_set_brate(s->gfp, avctx->bit_rate / 1000); + + /* rate control */ if (avctx->flags & CODEC_FLAG_QSCALE) { - lame_set_brate(s->gfp, 0); lame_set_VBR(s->gfp, vbr_default); lame_set_VBR_quality(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA); + } else { + if (avctx->bit_rate) + lame_set_brate(s->gfp, avctx->bit_rate / 1000); } - lame_set_bWriteVbrTag(s->gfp,0); - lame_set_disable_reservoir(s->gfp, !s->reservoir); - if (lame_init_params(s->gfp) < 0) - goto err_close; - avctx->frame_size = lame_get_framesize(s->gfp); + /* do not get a Xing VBR header frame from LAME */ + lame_set_bWriteVbrTag(s->gfp,0); - if(!(avctx->coded_frame= avcodec_alloc_frame())) { - lame_close(s->gfp); + /* bit reservoir usage */ + lame_set_disable_reservoir(s->gfp, !s->reservoir); - return AVERROR(ENOMEM); + /* set specified parameters */ + if (lame_init_params(s->gfp) < 0) { + ret = -1; + goto error; } - if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt && s->stereo) { - int nelem = 2 * avctx->frame_size; - - if(! (s->s32_data.left = av_malloc(nelem * sizeof(int)))) { - av_freep(&avctx->coded_frame); - lame_close(s->gfp); + avctx->frame_size = lame_get_framesize(s->gfp); + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) { + ret = AVERROR(ENOMEM); + goto error; + } - return AVERROR(ENOMEM); + /* sample format */ + if (avctx->sample_fmt == AV_SAMPLE_FMT_S32 || + avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + int ch; + for (ch = 0; ch < avctx->channels; ch++) { + s->planar_samples[ch] = av_malloc(avctx->frame_size * + av_get_bytes_per_sample(avctx->sample_fmt)); + if (!s->planar_samples[ch]) { + ret = AVERROR(ENOMEM); + goto error; + } } - - s->s32_data.right = s->s32_data.left + avctx->frame_size; } return 0; - -err_close: - lame_close(s->gfp); -err: - return -1; +error: + mp3lame_encode_close(avctx); + return ret; } -static const int sSampleRates[] = { - 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 -}; - -static const int sBitRates[2][3][15] = { - { - { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, - { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, - { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } - }, - { - { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } - }, -}; - -static const int sSamplesPerFrame[2][3] = { - { 384, 1152, 1152 }, - { 384, 1152, 576 } -}; - -static const int sBitsPerSlot[3] = { 32, 8, 8 }; - -static int mp3len(void *data, int *samplesPerFrame, int *sampleRate) +#define DEINTERLEAVE(type, scale) do { \ + int ch, i; \ + for (ch = 0; ch < s->avctx->channels; ch++) { \ + const type *input = samples; \ + type *output = s->planar_samples[ch]; \ + input += ch; \ + for (i = 0; i < s->avctx->frame_size; i++) { \ + output[i] = *input * scale; \ + input += s->avctx->channels; \ + } \ + } \ +} while (0) + +static int encode_frame_int16(LAMEContext *s, void *samples) { - uint32_t header = AV_RB32(data); - int layerID = 3 - ((header >> 17) & 0x03); - int bitRateID = ((header >> 12) & 0x0f); - int sampleRateID = ((header >> 10) & 0x03); - int bitsPerSlot = sBitsPerSlot[layerID]; - int isPadded = ((header >> 9) & 0x01); - static int const mode_tab[4] = { 2, 3, 1, 0 }; - int mode = mode_tab[(header >> 19) & 0x03]; - int mpeg_id = mode > 0; - int temp0, temp1, bitRate; - - if (((header >> 21) & 0x7ff) != 0x7ff || mode == 3 || layerID == 3 || - sampleRateID == 3) { - return -1; + if (s->avctx->channels > 1) { + return lame_encode_buffer_interleaved(s->gfp, samples, + s->avctx->frame_size, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index); + } else { + return lame_encode_buffer(s->gfp, samples, NULL, s->avctx->frame_size, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index); } +} - if (!samplesPerFrame) - samplesPerFrame = &temp0; - if (!sampleRate) - sampleRate = &temp1; +static int encode_frame_int32(LAMEContext *s, void *samples) +{ + DEINTERLEAVE(int32_t, 1); - //*isMono = ((header >> 6) & 0x03) == 0x03; + return lame_encode_buffer_int(s->gfp, + s->planar_samples[0], s->planar_samples[1], + s->avctx->frame_size, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index); +} - *sampleRate = sSampleRates[sampleRateID] >> mode; - bitRate = sBitRates[mpeg_id][layerID][bitRateID] * 1000; - *samplesPerFrame = sSamplesPerFrame[mpeg_id][layerID]; - //av_log(NULL, AV_LOG_DEBUG, - // "sr:%d br:%d spf:%d l:%d m:%d\n", - // *sampleRate, bitRate, *samplesPerFrame, layerID, mode); +static int encode_frame_float(LAMEContext *s, void *samples) +{ + DEINTERLEAVE(float, 32768.0f); - return *samplesPerFrame * bitRate / (bitsPerSlot * *sampleRate) + isPadded; + return lame_encode_buffer_float(s->gfp, + s->planar_samples[0], s->planar_samples[1], + s->avctx->frame_size, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index); } -static int MP3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame, +static int mp3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame, int buf_size, void *data) { - Mp3AudioContext *s = avctx->priv_data; + LAMEContext *s = avctx->priv_data; + MPADecodeHeader hdr; int len; int lame_result; - /* lame 3.91 dies on '1-channel interleaved' data */ - - if (!data){ - lame_result= lame_encode_flush( - s->gfp, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index - ); -#if 2147483647 == INT_MAX - }else if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt){ - if (s->stereo) { - int32_t *rp = data; - int32_t *mp = rp + 2*avctx->frame_size; - int *wpl = s->s32_data.left; - int *wpr = s->s32_data.right; - - while (rp < mp) { - *wpl++ = *rp++; - *wpr++ = *rp++; - } - - lame_result = lame_encode_buffer_int( - s->gfp, - s->s32_data.left, - s->s32_data.right, - avctx->frame_size, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index - ); - } else { - lame_result = lame_encode_buffer_int( - s->gfp, - data, - data, - avctx->frame_size, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index - ); - } -#endif - }else{ - if (s->stereo) { - lame_result = lame_encode_buffer_interleaved( - s->gfp, - data, - avctx->frame_size, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index - ); - } else { - lame_result = lame_encode_buffer( - s->gfp, - data, - data, - avctx->frame_size, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index - ); + if (data) { + switch (avctx->sample_fmt) { + case AV_SAMPLE_FMT_S16: + lame_result = encode_frame_int16(s, data); + break; + case AV_SAMPLE_FMT_S32: + lame_result = encode_frame_int32(s, data); + break; + case AV_SAMPLE_FMT_FLT: + lame_result = encode_frame_float(s, data); + break; + default: + return AVERROR_BUG; } + } else { + lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index); } - if (lame_result < 0) { if (lame_result == -1) { - /* output buffer too small */ av_log(avctx, AV_LOG_ERROR, "lame: output buffer too small (buffer index: %d, free bytes: %d)\n", s->buffer_index, BUFFER_SIZE - s->buffer_index); } return -1; } - s->buffer_index += lame_result; + /* 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. */ if (s->buffer_index < 4) return 0; - - len = mp3len(s->buffer, NULL, NULL); - //av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n", - // avctx->frame_size, len, s->buffer_index); + if (avpriv_mpegaudio_decode_header(&hdr, AV_RB32(s->buffer))) { + av_log(avctx, AV_LOG_ERROR, "free format output not supported\n"); + return -1; + } + len = hdr.frame_size; + 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); s->buffer_index -= len; - memmove(s->buffer, s->buffer + len, s->buffer_index); - // FIXME fix the audio codec API, so we do not need the memcpy() - /*for(i=0; i<len; i++) { - av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]); - }*/ return len; } else return 0; } -static av_cold int MP3lame_encode_close(AVCodecContext *avctx) -{ - Mp3AudioContext *s = avctx->priv_data; - - av_freep(&s->s32_data.left); - av_freep(&avctx->coded_frame); - - lame_close(s->gfp); - return 0; -} - -#define OFFSET(x) offsetof(Mp3AudioContext, x) +#define OFFSET(x) offsetof(LAMEContext, x) #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { { "reservoir", "Use bit reservoir.", OFFSET(reservoir), AV_OPT_TYPE_INT, { 1 }, 0, 1, AE }, @@ -292,21 +258,30 @@ static const AVClass libmp3lame_class = { .version = LIBAVUTIL_VERSION_INT, }; +static const AVCodecDefault libmp3lame_defaults[] = { + { "b", "0" }, + { NULL }, +}; + +static const int libmp3lame_sample_rates[] = { + 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 +}; + AVCodec ff_libmp3lame_encoder = { .name = "libmp3lame", .type = AVMEDIA_TYPE_AUDIO, .id = CODEC_ID_MP3, - .priv_data_size = sizeof(Mp3AudioContext), - .init = MP3lame_encode_init, - .encode = MP3lame_encode_frame, - .close = MP3lame_encode_close, + .priv_data_size = sizeof(LAMEContext), + .init = mp3lame_encode_init, + .encode = mp3lame_encode_frame, + .close = mp3lame_encode_close, .capabilities = CODEC_CAP_DELAY, - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, -#if 2147483647 == INT_MAX - AV_SAMPLE_FMT_S32, -#endif + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32, + AV_SAMPLE_FMT_FLT, + AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, - .supported_samplerates = sSampleRates, + .supported_samplerates = libmp3lame_sample_rates, .long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"), .priv_class = &libmp3lame_class, + .defaults = libmp3lame_defaults, }; |