diff options
author | nicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2005-05-07 14:50:14 +0000 |
---|---|---|
committer | nicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2005-05-07 14:50:14 +0000 |
commit | 5bb432dbbe51cb1f046fb6bdf62203605f1ca795 (patch) | |
tree | 23c0709acf68e47f650d8fd7205258b7445e2096 /libmpcodecs | |
parent | 08e479c3c65fb364974621721c16253e409e31e5 (diff) | |
download | mpv-5bb432dbbe51cb1f046fb6bdf62203605f1ca795.tar.bz2 mpv-5bb432dbbe51cb1f046fb6bdf62203605f1ca795.tar.xz |
added twolame mp2 audio encoder
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@15360 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r-- | libmpcodecs/Makefile | 4 | ||||
-rw-r--r-- | libmpcodecs/ae.c | 9 | ||||
-rw-r--r-- | libmpcodecs/ae.h | 1 | ||||
-rw-r--r-- | libmpcodecs/ae_twolame.c | 217 | ||||
-rw-r--r-- | libmpcodecs/ae_twolame.h | 14 |
5 files changed, 245 insertions, 0 deletions
diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile index 061c15916d..c3ad12c6c9 100644 --- a/libmpcodecs/Makefile +++ b/libmpcodecs/Makefile @@ -44,6 +44,10 @@ ENCODER_SRCS += ae_toolame.c EXTRA_INC += $(TOOLAME_EXTRAFLAGS) endif +ifeq ($(TWOLAME),yes) +ENCODER_SRCS += ae_twolame.c +endif + ifeq ($(CONFIG_MP3LAME),yes) ENCODER_SRCS += ae_lame.c endif diff --git a/libmpcodecs/ae.c b/libmpcodecs/ae.c index 2b1da10d04..af4a2bb751 100644 --- a/libmpcodecs/ae.c +++ b/libmpcodecs/ae.c @@ -27,6 +27,10 @@ #include "ae_faac.h" #endif +#ifdef HAVE_TWOLAME +#include "ae_twolame.h" +#endif + audio_encoder_t *new_audio_encoder(muxer_stream_t *stream, audio_encoding_params_t *params) { int ris; @@ -63,6 +67,11 @@ audio_encoder_t *new_audio_encoder(muxer_stream_t *stream, audio_encoding_params ris = mpae_init_faac(encoder); break; #endif +#ifdef HAVE_TWOLAME + case ACODEC_TWOLAME: + ris = mpae_init_twolame(encoder); + break; +#endif } if(! ris) diff --git a/libmpcodecs/ae.h b/libmpcodecs/ae.h index d1da14073d..316af9eb15 100644 --- a/libmpcodecs/ae.h +++ b/libmpcodecs/ae.h @@ -9,6 +9,7 @@ #define ACODEC_LAVC 4 #define ACODEC_TOOLAME 5 #define ACODEC_FAAC 6 +#define ACODEC_TWOLAME 7 #define AE_NEEDS_COMPRESSED_INPUT 1 diff --git a/libmpcodecs/ae_twolame.c b/libmpcodecs/ae_twolame.c new file mode 100644 index 0000000000..b6f06c774a --- /dev/null +++ b/libmpcodecs/ae_twolame.c @@ -0,0 +1,217 @@ +#include <stdio.h> +#include <stdlib.h> +#include <inttypes.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include "m_option.h" +#include "../mp_msg.h" +#include "aviheader.h" +#include "../libaf/af_format.h" +#include "ms_hdr.h" +#include "muxer.h" +#include "ae_twolame.h" +#include "../libmpdemux/mp3_hdr.h" + + +static int + param_bitrate = 192, + param_psy = 3, + param_maxvbr = 0, + param_errprot = 0, + param_debug = 0; + +static float param_vbr = 0; +static char *param_mode = "stereo"; + +m_option_t twolameopts_conf[] = { + {"br", ¶m_bitrate, CONF_TYPE_INT, 0, 0, 0, NULL}, + {"mode", ¶m_mode, CONF_TYPE_STRING, 0, 0, 0, NULL}, + {"psy", ¶m_psy, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL}, + {"vbr", ¶m_vbr, CONF_TYPE_FLOAT, CONF_RANGE, -50, 50, NULL}, + {"maxvbr", ¶m_maxvbr, CONF_TYPE_INT, 0, 0, 0, NULL}, + {"errprot", ¶m_errprot, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL}, + {"debug", ¶m_debug, CONF_TYPE_INT, CONF_RANGE, 0, 100000000, NULL}, + {NULL, NULL, 0, 0, 0, 0, NULL} +}; + + +static int bind_twolame(audio_encoder_t *encoder, muxer_stream_t *mux_a) +{ + mpae_twolame_ctx *ctx = (mpae_twolame_ctx *) encoder->priv; + + mux_a->wf = malloc(sizeof(WAVEFORMATEX)+256); + mux_a->wf->wFormatTag = 0x50; + mux_a->wf->nChannels = encoder->params.channels; + mux_a->wf->nSamplesPerSec = encoder->params.sample_rate; + mux_a->wf->nAvgBytesPerSec = encoder->params.bitrate / 8; + + if(ctx->vbr || ((mux_a->wf->nAvgBytesPerSec * encoder->params.samples_per_frame) % mux_a->wf->nSamplesPerSec)) + { + mux_a->h.dwScale = encoder->params.samples_per_frame; + mux_a->h.dwRate = encoder->params.sample_rate; + mux_a->h.dwSampleSize = 0; // Blocksize not constant + } + else + { + mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * encoder->params.samples_per_frame)/ mux_a->wf->nSamplesPerSec; /* for cbr */ + mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec; + mux_a->h.dwSampleSize = mux_a->h.dwScale; + } + mux_a->wf->nBlockAlign = mux_a->h.dwScale; + mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000; + mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign; + + mux_a->wf->cbSize = 0; //12; + mux_a->wf->wBitsPerSample = 0; /* does not apply */ + ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1; + ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2; + ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign; + ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1; + ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0; + + // Fix allocation + mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize); + + encoder->input_format = AF_FORMAT_S16_NE; + encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize; + encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2; + + return 1; +} + +static int encode_twolame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size) +{ + mpae_twolame_ctx *ctx = (mpae_twolame_ctx *)encoder->priv; + int ret_size = 0, r2; + + len /= (2*encoder->params.channels); + ret_size = twolame_encode_buffer_interleaved(ctx->twolame_ctx, src, len, dest, max_size); + r2 = mp_decode_mp3_header(dest); + mp_msg(MSGT_MENCODER, MSGL_V, "\nSIZE: %d, max: %d, r2: %d\n", ret_size, max_size, r2); + if(r2 > 0) + ret_size = r2; + return ret_size; +} + +int close_twolame(audio_encoder_t *encoder) +{ + free(encoder->priv); + return 1; +} + +static int get_frame_size(audio_encoder_t *encoder) +{ + int sz; + if(encoder->stream->buffer_len < 4) + return 0; + sz = mp_decode_mp3_header(encoder->stream->buffer); + if(sz <= 0) + return 0; + return sz; +} + + +int mpae_init_twolame(audio_encoder_t *encoder) +{ + int mode; + mpae_twolame_ctx *ctx = NULL; + + if(encoder->params.channels == 1) + { + mp_msg(MSGT_MENCODER, MSGL_INFO, "ae_twolame, 1 audio channel, forcing mono mode\n"); + mode = TWOLAME_MONO; + } + else if(encoder->params.channels == 2) + { + if(! strcasecmp(param_mode, "dual")) + mode = TWOLAME_DUAL_CHANNEL; + else if(! strcasecmp(param_mode, "jstereo")) + mode = TWOLAME_JOINT_STEREO; + else if(! strcasecmp(param_mode, "stereo")) + mode = TWOLAME_STEREO; + else + { + mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, unknown mode %s, exiting\n", param_mode); + } + } + else + mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, Twolame can't encode > 2 channels, exiting\n"); + + ctx = (mpae_twolame_ctx *) calloc(1, sizeof(mpae_twolame_ctx)); + if(ctx == NULL) + { + mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, couldn't alloc a %d bytes context, exiting\n", sizeof(mpae_twolame_ctx)); + return 0; + } + + ctx->twolame_ctx = twolame_init(); + if(ctx->twolame_ctx == NULL) + { + mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, couldn't initial parameters from libtwolame, exiting\n"); + free(ctx); + return 0; + } + ctx->vbr = 0; + + if(twolame_set_num_channels(ctx->twolame_ctx, encoder->params.channels) != 0) + return 0; + if(twolame_set_mode(ctx->twolame_ctx, mode) != 0) + return 0; + + if(twolame_set_in_samplerate(ctx->twolame_ctx, encoder->params.sample_rate) != 0) + return 0; + + if(twolame_set_out_samplerate(ctx->twolame_ctx, encoder->params.sample_rate) != 0) + return 0; + + if(encoder->params.sample_rate < 32000) + twolame_set_version(ctx->twolame_ctx, TWOLAME_MPEG2); + else + twolame_set_version(ctx->twolame_ctx, TWOLAME_MPEG1); + + if(twolame_set_psymodel(ctx->twolame_ctx, param_psy) != 0) + return 0; + + if(twolame_set_bitrate(ctx->twolame_ctx, param_bitrate) != 0) + return 0; + + if(param_errprot) + if(twolame_set_error_protection(ctx->twolame_ctx, TRUE) != 0) + return 0; + + if(param_vbr != 0) + { + if(twolame_set_VBR(ctx->twolame_ctx, TRUE) != 0) + return 0; + if(twolame_set_VBR_q(ctx->twolame_ctx, param_vbr) != 0) + return 0; + if(twolame_set_padding(ctx->twolame_ctx, FALSE) != 0) + return 0; + if(param_maxvbr) + { + if(twolame_set_VBR_max_bitrate_kbps(ctx->twolame_ctx, param_maxvbr) != 0) + return 0; + } + ctx->vbr = 1; + } + + if(twolame_set_verbosity(ctx->twolame_ctx, param_debug) != 0) + return 0; + + if(twolame_init_params(ctx->twolame_ctx) != 0) + return 0; + + encoder->params.bitrate = param_bitrate * 1000; + encoder->params.samples_per_frame = 1152; + encoder->priv = ctx; + encoder->decode_buffer_size = 1152 * 2 * encoder->params.channels; + + encoder->bind = bind_twolame; + encoder->get_frame_size = get_frame_size; + encoder->encode = encode_twolame; + encoder->close = close_twolame; + + return 1; +} + diff --git a/libmpcodecs/ae_twolame.h b/libmpcodecs/ae_twolame.h new file mode 100644 index 0000000000..65d3590f9b --- /dev/null +++ b/libmpcodecs/ae_twolame.h @@ -0,0 +1,14 @@ +#ifndef MPAE_TWOLAME_H +#define MPAE_TWOLAME_H + +#include "ae.h" +#include <twolame.h> + +typedef struct { + twolame_options *twolame_ctx; + int vbr; +} mpae_twolame_ctx; + +int mpae_init_twolame(audio_encoder_t *encoder); + +#endif |