changeset 15234:e84a6ae9d51e

audio encoding reworked
author nicodvb
date Fri, 22 Apr 2005 06:59:59 +0000
parents e18a07d6badb
children 856baee3ef2b
files cfg-mencoder.h configure libmpcodecs/Makefile libmpcodecs/ae.c libmpcodecs/ae.h libmpcodecs/ae_lame.c libmpcodecs/ae_lame.h libmpcodecs/ae_lavc.c libmpcodecs/ae_lavc.h libmpcodecs/ae_pcm.c libmpcodecs/ae_pcm.h libmpcodecs/ae_toolame.c libmpcodecs/ae_toolame.h mencoder.c
diffstat 14 files changed, 947 insertions(+), 746 deletions(-) [+]
line wrap: on
line diff
--- a/cfg-mencoder.h	Thu Apr 21 21:23:53 2005 +0000
+++ b/cfg-mencoder.h	Fri Apr 22 06:59:59 2005 +0000
@@ -22,33 +22,7 @@
 #endif
 
 #ifdef HAVE_MP3LAME
-m_option_t lameopts_conf[]={
-	{"q", &lame_param_quality, CONF_TYPE_INT, CONF_RANGE, 0, 9, NULL},
-	{"aq", &lame_param_algqual, CONF_TYPE_INT, CONF_RANGE, 0, 9, NULL},
-	{"vbr", &lame_param_vbr, CONF_TYPE_INT, CONF_RANGE, 0, vbr_max_indicator, NULL},
-	{"cbr", &lame_param_vbr, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-	{"abr", &lame_param_vbr, CONF_TYPE_FLAG, 0, 0, vbr_abr, NULL},
-	{"mode", &lame_param_mode, CONF_TYPE_INT, CONF_RANGE, 0, MAX_INDICATOR, NULL},
-	{"padding", &lame_param_padding, CONF_TYPE_INT, CONF_RANGE, 0, PAD_MAX_INDICATOR, NULL},
-	{"br", &lame_param_br, CONF_TYPE_INT, CONF_RANGE, 0, 1024, NULL},
-	{"ratio", &lame_param_ratio, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
-	{"vol", &lame_param_scale, CONF_TYPE_FLOAT, CONF_RANGE, 0, 10, NULL},
-	{"lowpassfreq",&lame_param_lowpassfreq, CONF_TYPE_INT, CONF_RANGE, -1, 48000,0},
-	{"highpassfreq",&lame_param_highpassfreq, CONF_TYPE_INT, CONF_RANGE, -1, 48000,0},
-	{"nofree", &lame_param_free_format, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-	{"free", &lame_param_free_format, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-	{"br_min", &lame_param_br_min, CONF_TYPE_INT, CONF_RANGE, 0, 1024, NULL},
-	{"br_max", &lame_param_br_max, CONF_TYPE_INT, CONF_RANGE, 0, 1024, NULL},
-#if HAVE_MP3LAME >= 392
-	{"fast", &lame_param_fast, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-	{"preset", &lame_param_preset, CONF_TYPE_STRING, 0, 0, 0, NULL},
-#else
-	{"fast", "MPlayer was built without -lameopts fast support (requires libmp3lame >=3.92).\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
-	{"preset", "MPlayer was built without -lameopts preset support (requires libmp3lame >=3.92).\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
-#endif
-	{"help", MSGTR_MEncoderMP3LameHelp, CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
-	{NULL, NULL, 0, 0, 0, 0, NULL}
-};
+extern m_option_t lameopts_conf[];
 #endif
 
 #ifdef USE_LIBAVCODEC
--- a/configure	Thu Apr 21 21:23:53 2005 +0000
+++ b/configure	Fri Apr 22 06:59:59 2005 +0000
@@ -6800,6 +6800,7 @@
 DS_LIB = $_ld_dshow
 AV_DEP = $_dep_libavcodec $_dep_libavformat
 AV_LIB = $_ld_libavcodec $_ld_libavformat
+CONFIG_LIBAVCODEC = $_libavcodec
 CONFIG_LIBAVFORMAT = $_libavformat
 ZORAN = $_zr
 FAME = $_fame
--- a/libmpcodecs/Makefile	Thu Apr 21 21:23:53 2005 +0000
+++ b/libmpcodecs/Makefile	Fri Apr 22 06:59:59 2005 +0000
@@ -19,7 +19,7 @@
 VFILTER_SRCS += vf_pp.c
 endif
 
-ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_raw.c ve_libdv.c ve_xvid.c ve_xvid4.c ve_qtvideo.c ve_nuv.c ve_x264.c
+ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_raw.c ve_libdv.c ve_xvid.c ve_xvid4.c ve_qtvideo.c ve_nuv.c ve_x264.c ae.c ae_pcm.c
 
 NATIVE_SRCS=native/RTjpegN.c native/minilzo.c native/nuppelvideo.c native/xa_gsm.c native/decode144.c native/decode288.c
 
@@ -40,10 +40,18 @@
 endif
 
 ifeq ($(TOOLAME),yes)
-AUDIO_SRCS += ae_toolame.c
+ENCODER_SRCS += ae_toolame.c
 EXTRA_INC += $(TOOLAME_EXTRAFLAGS)
 endif
 
+ifeq ($(CONFIG_MP3LAME),yes)
+ENCODER_SRCS += ae_lame.c
+endif
+
+ifeq ($(CONFIG_LIBAVCODEC),yes)
+ENCODER_SRCS += ae_lavc.c
+endif
+
 SRCS=$(AUDIO_SRCS) $(VIDEO_SRCS) $(VFILTER_SRCS) $(NATIVE_SRCS) img_format.c
 OBJS=$(SRCS:.c=.o)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae.c	Fri Apr 22 06:59:59 2005 +0000
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <math.h>
+#include "aviheader.h"
+#include "ms_hdr.h"
+#include "muxer.h"
+#include "ae.h"
+#include "../config.h"
+
+#ifdef HAVE_TOOLAME
+#include "ae_toolame.h"
+#endif
+
+#ifdef HAVE_MP3LAME
+#include "ae_lame.h"
+#endif
+
+#ifdef USE_LIBAVCODEC
+#include "ae_lavc.h"
+#endif
+
+audio_encoder_t *new_audio_encoder(muxer_stream_t *stream, audio_encoding_params_t *params)
+{
+	int ris;
+	if(! params)
+		return NULL;
+	
+	audio_encoder_t *encoder = (audio_encoder_t *) calloc(1, sizeof(audio_encoder_t));
+	memcpy(&encoder->params, params, sizeof(audio_encoding_params_t));
+	encoder->stream = stream;
+	
+	switch(stream->codec)
+	{
+		case ACODEC_PCM:
+			ris = mpae_init_pcm(encoder);
+			break;
+#ifdef HAVE_TOOLAME
+		case ACODEC_TOOLAME:
+			ris = mpae_init_toolame(encoder);
+			break;
+#endif
+#ifdef USE_LIBAVCODEC
+		case ACODEC_LAVC:
+			ris = mpae_init_lavc(encoder);
+			break;
+#endif
+#ifdef HAVE_MP3LAME
+		case ACODEC_VBRMP3:
+			ris = mpae_init_lame(encoder);
+			break;
+#endif
+	}
+	
+	if(! ris)
+	{
+		free(encoder);
+		return NULL;
+	}
+	encoder->bind(encoder, stream);
+	encoder->decode_buffer = (int*)malloc(encoder->decode_buffer_size);
+	if(! encoder->decode_buffer)
+	{
+		free(encoder);
+		return NULL;
+	}
+	
+	encoder->codec = stream->codec;
+	return encoder;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae.h	Fri Apr 22 06:59:59 2005 +0000
@@ -0,0 +1,44 @@
+
+#ifndef __MPAE_H__
+#define __MPAE_H__
+
+#define ACODEC_COPY 0
+#define ACODEC_PCM 1
+#define ACODEC_VBRMP3 2
+#define ACODEC_NULL 3
+#define ACODEC_LAVC 4
+#define ACODEC_TOOLAME 5
+
+#define AE_NEEDS_COMPRESSED_INPUT 1
+
+typedef struct {
+	int channels;
+	int sample_rate;
+	int bitrate;
+	int samples_per_frame;
+	int audio_preload;
+} audio_encoding_params_t;
+
+typedef struct {
+	int codec;
+	int flags;
+	muxer_stream_t *stream;
+	audio_encoding_params_t params;
+	int audio_preload;	//in ms
+	int input_format;
+	int min_buffer_size, max_buffer_size;	//for init_audio_filters
+	int *decode_buffer;
+	int decode_buffer_size;
+	int decode_buffer_len;
+	void *priv;
+	int (*bind)(void*, muxer_stream_t*);
+	int (*get_frame_size)(void*);
+	int (*set_decoded_len)(void *encoder, int len);
+	int (*encode)(void *encoder, uint8_t *dest, void *src, int nsamples, int max_size);
+	int (*fixup)();
+	int (*close)();
+} audio_encoder_t;
+
+audio_encoder_t *new_audio_encoder(muxer_stream_t *stream, audio_encoding_params_t *params);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae_lame.c	Fri Apr 22 06:59:59 2005 +0000
@@ -0,0 +1,329 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include "m_option.h"
+#include "../mp_msg.h"
+#include "aviheader.h"
+#include "ms_hdr.h"
+#include "muxer.h"
+#include "../help_mp.h"
+#include "ae_pcm.h"
+#include "../libaf/af_format.h"
+#include "../libmpdemux/mp3_hdr.h"
+
+#undef CDECL
+#include <lame/lame.h>
+
+lame_global_flags *lame;
+static int lame_param_quality=0; // best
+static int lame_param_algqual=5; // same as old default
+static int lame_param_vbr=vbr_default;
+static int lame_param_mode=-1; // unset
+static int lame_param_padding=-1; // unset
+static int lame_param_br=-1; // unset
+static int lame_param_ratio=-1; // unset
+static float lame_param_scale=-1; // unset
+static int lame_param_lowpassfreq = 0; //auto
+static int lame_param_highpassfreq = 0; //auto
+static int lame_param_free_format = 0; //disabled
+static int lame_param_br_min = 0; //not specified
+static int lame_param_br_max = 0; //not specified
+
+#if HAVE_MP3LAME >= 392
+int lame_param_fast=0; // unset
+static char* lame_param_preset=NULL; // unset
+static int  lame_presets_set( lame_t gfp, int fast, int cbr, const char* preset_name );
+static void  lame_presets_longinfo_dm ( FILE* msgfp );
+#endif
+
+
+m_option_t lameopts_conf[]={
+	{"q", &lame_param_quality, CONF_TYPE_INT, CONF_RANGE, 0, 9, NULL},
+	{"aq", &lame_param_algqual, CONF_TYPE_INT, CONF_RANGE, 0, 9, NULL},
+	{"vbr", &lame_param_vbr, CONF_TYPE_INT, CONF_RANGE, 0, vbr_max_indicator, NULL},
+	{"cbr", &lame_param_vbr, CONF_TYPE_FLAG, 0, 0, 0, NULL},
+	{"abr", &lame_param_vbr, CONF_TYPE_FLAG, 0, 0, vbr_abr, NULL},
+	{"mode", &lame_param_mode, CONF_TYPE_INT, CONF_RANGE, 0, MAX_INDICATOR, NULL},
+	{"padding", &lame_param_padding, CONF_TYPE_INT, CONF_RANGE, 0, PAD_MAX_INDICATOR, NULL},
+	{"br", &lame_param_br, CONF_TYPE_INT, CONF_RANGE, 0, 1024, NULL},
+	{"ratio", &lame_param_ratio, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
+	{"vol", &lame_param_scale, CONF_TYPE_FLOAT, CONF_RANGE, 0, 10, NULL},
+	{"lowpassfreq",&lame_param_lowpassfreq, CONF_TYPE_INT, CONF_RANGE, -1, 48000,0},
+	{"highpassfreq",&lame_param_highpassfreq, CONF_TYPE_INT, CONF_RANGE, -1, 48000,0},
+	{"nofree", &lame_param_free_format, CONF_TYPE_FLAG, 0, 0, 0, NULL},
+	{"free", &lame_param_free_format, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"br_min", &lame_param_br_min, CONF_TYPE_INT, CONF_RANGE, 0, 1024, NULL},
+	{"br_max", &lame_param_br_max, CONF_TYPE_INT, CONF_RANGE, 0, 1024, NULL},
+#if HAVE_MP3LAME >= 392
+	{"fast", &lame_param_fast, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"preset", &lame_param_preset, CONF_TYPE_STRING, 0, 0, 0, NULL},
+#else
+	{"fast", "MPlayer was built without -lameopts fast support (requires libmp3lame >=3.92).\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
+	{"preset", "MPlayer was built without -lameopts preset support (requires libmp3lame >=3.92).\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
+#endif
+	{"help", MSGTR_MEncoderMP3LameHelp, CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
+	{NULL, NULL, 0, 0, 0, 0, NULL}
+};
+
+
+static int pass;
+extern int verbose;
+
+static int bind_lame(audio_encoder_t *encoder, muxer_stream_t *mux_a)
+{
+    mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_MP3AudioSelected);
+    mux_a->h.dwSampleSize=0; // VBR
+    mux_a->h.dwRate=encoder->params.sample_rate;
+    mux_a->h.dwScale=encoder->params.samples_per_frame; // samples/frame
+    if(sizeof(MPEGLAYER3WAVEFORMAT)!=30) mp_msg(MSGT_MENCODER,MSGL_WARN,MSGTR_MP3WaveFormatSizeNot30,sizeof(MPEGLAYER3WAVEFORMAT));
+    mux_a->wf=malloc(sizeof(MPEGLAYER3WAVEFORMAT)); // should be 30
+    mux_a->wf->wFormatTag=0x55; // MP3
+    mux_a->wf->nChannels= (lame_param_mode<0) ? encoder->params.channels : ((lame_param_mode==3) ? 1 : 2);
+    mux_a->wf->nSamplesPerSec=mux_a->h.dwRate;
+    if(! lame_param_vbr)
+        mux_a->wf->nAvgBytesPerSec=lame_param_br * 125;
+    else
+        mux_a->wf->nAvgBytesPerSec=192000/8; // FIXME!
+    mux_a->wf->nBlockAlign=encoder->params.samples_per_frame; // required for l3codeca.acm + WMP 6.4
+    mux_a->wf->wBitsPerSample=0; //16;
+    // from NaNdub:  (requires for l3codeca.acm)
+    mux_a->wf->cbSize=12;
+    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->wID=1;
+    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->fdwFlags=2;
+    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nBlockSize=encoder->params.samples_per_frame; // ???
+    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nFramesPerBlock=1;
+    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nCodecDelay=0;
+    
+    encoder->input_format = AF_FORMAT_S16_LE;
+    encoder->min_buffer_size = 4608;
+    encoder->max_buffer_size = mux_a->h.dwRate * mux_a->wf->nChannels * 2;
+    
+    return 1;
+}
+
+#define min(a, b) ((a) <= (b) ? (a) : (b))
+
+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;
+}
+
+static int encode_lame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size)
+{
+    int n = 0;
+    if(encoder->params.channels == 1)
+        n = lame_encode_buffer(lame, (short *)src, (short *)src, len/2, dest, max_size);
+    else
+        n = lame_encode_buffer_interleaved(lame,(short *)src, len/4, dest, max_size);
+
+    return (n < 0 ? 0 : n);
+}
+
+
+static int close_lame(audio_encoder_t *encoder)
+{
+    return 1;
+}
+
+static void fixup(audio_encoder_t *encoder)
+{
+    // fixup CBR mp3 audio header:
+    if(!lame_param_vbr) {
+        encoder->stream->h.dwSampleSize=1;
+        ((MPEGLAYER3WAVEFORMAT*)(encoder->stream->wf))->nBlockSize=
+            (encoder->stream->size+(encoder->stream->h.dwLength>>1))/encoder->stream->h.dwLength;
+        encoder->stream->h.dwLength=encoder->stream->size;
+        encoder->stream->h.dwRate=encoder->stream->wf->nAvgBytesPerSec;
+        encoder->stream->h.dwScale=1;
+        encoder->stream->wf->nBlockAlign=1;
+        mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_CBRAudioByterate,
+            encoder->stream->h.dwRate,((MPEGLAYER3WAVEFORMAT*)(encoder->stream->wf))->nBlockSize);
+    }
+}
+
+int mpae_init_lame(audio_encoder_t *encoder)
+{
+    encoder->params.bitrate = lame_param_br * 125;
+    encoder->params.samples_per_frame = encoder->params.sample_rate < 32000 ? 576 : 1152;
+    encoder->decode_buffer_size = 2304;
+
+    lame=lame_init();
+    lame_set_bWriteVbrTag(lame,0);
+    lame_set_in_samplerate(lame,encoder->params.sample_rate);
+    //lame_set_in_samplerate(lame,sh_audio->samplerate); // if resampling done by lame
+    lame_set_num_channels(lame,encoder->params.channels);
+    lame_set_out_samplerate(lame,encoder->params.sample_rate);
+    lame_set_quality(lame,lame_param_algqual); // 0 = best q
+    if(lame_param_free_format) lame_set_free_format(lame,1);
+    if(lame_param_vbr){  // VBR:
+        lame_set_VBR(lame,lame_param_vbr); // vbr mode
+        lame_set_VBR_q(lame,lame_param_quality); // 0 = best vbr q  5=~128k
+        if(lame_param_br>0) lame_set_VBR_mean_bitrate_kbps(lame,lame_param_br);
+        if(lame_param_br_min>0) lame_set_VBR_min_bitrate_kbps(lame,lame_param_br_min);
+        if(lame_param_br_max>0) lame_set_VBR_max_bitrate_kbps(lame,lame_param_br_max);
+    } else {    // CBR:
+        if(lame_param_br>0) lame_set_brate(lame,lame_param_br);
+    }
+    if(lame_param_mode>=0) lame_set_mode(lame,lame_param_mode); // j-st
+    if(lame_param_ratio>0) lame_set_compression_ratio(lame,lame_param_ratio);
+    if(lame_param_scale>0) {
+        mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_SettingAudioInputGain, lame_param_scale);
+        lame_set_scale(lame,lame_param_scale);
+    }
+    if(lame_param_lowpassfreq>=-1) lame_set_lowpassfreq(lame,lame_param_lowpassfreq);
+    if(lame_param_highpassfreq>=-1) lame_set_highpassfreq(lame,lame_param_highpassfreq);
+#if HAVE_MP3LAME >= 392
+    if(lame_param_preset != NULL) {
+        mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_LamePresetEquals,lame_param_preset);
+        if(lame_presets_set(lame,lame_param_fast, (lame_param_vbr==0), lame_param_preset) < 0)
+            return 0;
+    }
+#endif
+    if(lame_init_params(lame) == -1) {
+        mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LameCantInit); 
+        return 0;
+    }
+    if(verbose>0) {
+        lame_print_config(lame);
+        lame_print_internals(lame);
+    }
+    
+    encoder->bind = bind_lame;
+    encoder->get_frame_size = get_frame_size;
+    encoder->encode = encode_lame;
+    encoder->fixup = fixup;
+    encoder->close = close_lame;
+    return 1;
+}
+
+#if HAVE_MP3LAME >= 392
+/* lame_presets_set 
+   taken out of presets_set in lame-3.93.1/frontend/parse.c and modified */
+static int  lame_presets_set( lame_t gfp, int fast, int cbr, const char* preset_name )
+{
+    int mono = 0;
+
+    if (strcmp(preset_name, "help") == 0) {
+        mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_LameVersion, get_lame_version(), get_lame_url());
+        lame_presets_longinfo_dm(stderr);
+        return -1;
+    }
+
+    //aliases for compatibility with old presets
+
+    if (strcmp(preset_name, "phone") == 0) {
+        preset_name = "16";
+        mono = 1;
+    }
+    if ( (strcmp(preset_name, "phon+") == 0) ||
+         (strcmp(preset_name, "lw") == 0) ||
+         (strcmp(preset_name, "mw-eu") == 0) ||
+         (strcmp(preset_name, "sw") == 0)) {
+        preset_name = "24";
+        mono = 1;
+    }
+    if (strcmp(preset_name, "mw-us") == 0) {
+        preset_name = "40";
+        mono = 1;
+    }
+    if (strcmp(preset_name, "voice") == 0) {
+        preset_name = "56";
+        mono = 1;
+    }
+    if (strcmp(preset_name, "fm") == 0) {
+        preset_name = "112";
+    }
+    if ( (strcmp(preset_name, "radio") == 0) ||
+         (strcmp(preset_name, "tape") == 0)) {
+        preset_name = "112";
+    }
+    if (strcmp(preset_name, "hifi") == 0) {
+        preset_name = "160";
+    }
+    if (strcmp(preset_name, "cd") == 0) {
+        preset_name = "192";
+    }
+    if (strcmp(preset_name, "studio") == 0) {
+        preset_name = "256";
+    }
+
+#if HAVE_MP3LAME >= 393
+    if (strcmp(preset_name, "medium") == 0) {
+        if (fast > 0)
+           lame_set_preset(gfp, MEDIUM_FAST);
+        else
+           lame_set_preset(gfp, MEDIUM);
+
+        return 0;
+    }
+#endif
+    
+    if (strcmp(preset_name, "standard") == 0) {
+        if (fast > 0)
+           lame_set_preset(gfp, STANDARD_FAST);
+        else
+           lame_set_preset(gfp, STANDARD);
+
+        return 0;
+    }
+    
+    else if (strcmp(preset_name, "extreme") == 0){
+        if (fast > 0)
+           lame_set_preset(gfp, EXTREME_FAST);
+        else
+           lame_set_preset(gfp, EXTREME);
+
+        return 0;
+    }
+    					
+    else if (((strcmp(preset_name, "insane") == 0) || 
+              (strcmp(preset_name, "320"   ) == 0))   && (fast < 1)) {
+
+        lame_set_preset(gfp, INSANE);
+ 
+        return 0;
+    }
+
+    // Generic ABR Preset
+    if (((atoi(preset_name)) > 0) &&  (fast < 1)) {
+        if ((atoi(preset_name)) >= 8 && (atoi(preset_name)) <= 320){
+            lame_set_preset(gfp, atoi(preset_name));
+
+            if (cbr == 1 )
+                lame_set_VBR(gfp, vbr_off);
+
+            if (mono == 1 ) {
+                lame_set_mode(gfp, MONO);
+            }
+
+            return 0;
+
+        }
+        else {
+            mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_LameVersion, get_lame_version(), get_lame_url());
+            mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_InvalidBitrateForLamePreset);
+            return -1;
+        }
+    }
+
+    mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_LameVersion, get_lame_version(), get_lame_url());
+    mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_InvalidLamePresetOptions);
+    return -1;
+}
+#endif
+
+#if HAVE_MP3LAME >= 392
+/* lame_presets_longinfo_dm
+   taken out of presets_longinfo_dm in lame-3.93.1/frontend/parse.c and modified */
+static void  lame_presets_longinfo_dm ( FILE* msgfp )
+{
+        mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_LamePresetsLongInfo);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae_lame.h	Fri Apr 22 06:59:59 2005 +0000
@@ -0,0 +1,8 @@
+#ifndef __AE_PCM_H_
+#define __AE_PCM_H_
+
+#include "ae.h"
+
+int mpae_init_lame(audio_encoder_t *encoder);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae_lavc.c	Fri Apr 22 06:59:59 2005 +0000
@@ -0,0 +1,197 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include "m_option.h"
+#include "../mp_msg.h"
+#include "aviheader.h"
+#include "ms_hdr.h"
+#include "muxer.h"
+#include "ae_lavc.h"
+#include "help_mp.h"
+#include "../config.h"
+#include "../libaf/af_format.h"
+#ifdef USE_LIBAVCODEC_SO
+#include <ffmpeg/avcodec.h>
+#else
+#include "libavcodec/avcodec.h"
+#endif
+
+static AVCodec        *lavc_acodec;
+static AVCodecContext *lavc_actx;
+extern char *lavc_param_acodec;
+extern int  lavc_param_abitrate;
+extern int  lavc_param_atag;
+extern int  avcodec_inited;
+static int compressed_frame_size = 0;
+
+static int bind_lavc(audio_encoder_t *encoder, muxer_stream_t *mux_a)
+{
+	mux_a->wf = malloc(sizeof(WAVEFORMATEX)+lavc_actx->extradata_size+256);
+	mux_a->wf->wFormatTag = lavc_param_atag;
+	mux_a->wf->nChannels = lavc_actx->channels;
+	mux_a->wf->nSamplesPerSec = lavc_actx->sample_rate;
+	mux_a->wf->nAvgBytesPerSec = (lavc_actx->bit_rate / 8);
+	mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec;
+	if(lavc_actx->block_align)
+		mux_a->h.dwSampleSize = mux_a->h.dwScale = lavc_actx->block_align;
+	else 
+	{
+		mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * lavc_actx->frame_size)/ mux_a->wf->nSamplesPerSec; /* for cbr */
+	
+		if ((mux_a->wf->nAvgBytesPerSec *
+			lavc_actx->frame_size) % mux_a->wf->nSamplesPerSec) 
+		{
+			mux_a->h.dwScale = lavc_actx->frame_size;
+			mux_a->h.dwRate = lavc_actx->sample_rate;
+			mux_a->h.dwSampleSize = 0; // Blocksize not constant
+		} 
+		else 
+			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;
+
+	switch(lavc_param_atag) 
+	{
+		case 0x11: /* imaadpcm */
+			mux_a->wf->wBitsPerSample = 4;
+			mux_a->wf->cbSize = 2;
+			((uint16_t*)mux_a->wf)[sizeof(WAVEFORMATEX)] = 
+				((lavc_actx->block_align - 4 * lavc_actx->channels) / (4 * lavc_actx->channels)) * 8 + 1;
+			break;
+		case 0x55: /* mp3 */
+			mux_a->wf->cbSize = 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;
+			break;
+		default:
+			mux_a->wf->wBitsPerSample = 0; /* Unknown */
+			if (lavc_actx->extradata && (lavc_actx->extradata_size > 0))
+			{
+				memcpy(mux_a->wf+sizeof(WAVEFORMATEX), lavc_actx->extradata,
+					lavc_actx->extradata_size);
+				mux_a->wf->cbSize = lavc_actx->extradata_size;
+			}
+			else
+				mux_a->wf->cbSize = 0;
+			break;
+	}
+
+	// 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_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size)
+{
+	int n;
+	n = avcodec_encode_audio(lavc_actx, dest, size, src);
+	if(n > compressed_frame_size)
+		compressed_frame_size = n;	//it's valid because lavc encodes in cbr mode
+	return n;
+}
+
+
+static int close_lavc(audio_encoder_t *encoder)
+{
+	compressed_frame_size = 0;
+	return 1;
+}
+
+static int get_frame_size(audio_encoder_t *encoder)
+{
+	return compressed_frame_size;
+}
+
+int mpae_init_lavc(audio_encoder_t *encoder)
+{
+	encoder->params.samples_per_frame = encoder->params.sample_rate;
+	encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8;
+	
+	if(!lavc_param_acodec)
+	{
+		mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName);
+		return 0;
+	}
+
+	if(!avcodec_inited){
+		avcodec_init();
+		avcodec_register_all();
+		avcodec_inited=1;
+	}
+
+	lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec);
+	if (!lavc_acodec)
+	{
+		mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LavcAudioCodecNotFound, lavc_param_acodec);
+		return 0;
+	}
+	if(lavc_param_atag == 0)
+	{
+		lavc_param_atag = codec_get_wav_tag(lavc_acodec->id);
+		if(!lavc_param_atag)
+		{
+			mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't find wav tag for specified codec, exit\n");
+			return 0;
+		}
+	}
+
+	lavc_actx = avcodec_alloc_context();
+	if(lavc_actx == NULL)
+	{
+		mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext);
+		return 0;
+	}
+	
+	// put sample parameters
+	lavc_actx->channels = encoder->params.channels;
+	lavc_actx->sample_rate = encoder->params.sample_rate;
+	lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate * 1000;
+	
+
+	/*
+	* Special case for adpcm_ima_wav.
+	* The bitrate is only dependant on samplerate.
+	* We have to known frame_size and block_align in advance,
+	* so I just copied the code from libavcodec/adpcm.c
+	*
+	* However, ms adpcm_ima_wav uses a block_align of 2048,
+	* lavc defaults to 1024
+	*/
+	if(lavc_param_atag == 0x11) {
+		int blkalign = 2048;
+		int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1;
+		lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize;
+	}
+
+	if(avcodec_open(lavc_actx, lavc_acodec) < 0)
+	{
+		mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate);
+		return 0;
+	}
+
+	if(lavc_param_atag == 0x11) {
+		lavc_actx->block_align = 2048;
+		lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1;
+	}
+
+	encoder->decode_buffer_size = lavc_actx->frame_size * 2 * encoder->params.channels;
+	encoder->bind = bind_lavc;
+	encoder->get_frame_size = get_frame_size;
+	encoder->encode = encode_lavc;
+	encoder->close = close_lavc;
+
+	return 1;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae_lavc.h	Fri Apr 22 06:59:59 2005 +0000
@@ -0,0 +1,8 @@
+#ifndef __AE_LAVC_H_
+#define __AE_LAVC_H_
+
+#include "ae.h"
+
+int mpae_init_lavc(audio_encoder_t *encoder);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae_pcm.c	Fri Apr 22 06:59:59 2005 +0000
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.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_pcm.h"
+
+
+static int bind_pcm(audio_encoder_t *encoder, muxer_stream_t *mux_a)
+{
+	mux_a->h.dwScale=1;
+	mux_a->h.dwRate=encoder->params.sample_rate;
+	mux_a->wf=malloc(sizeof(WAVEFORMATEX));
+	mux_a->wf->wFormatTag=0x1; // PCM
+	mux_a->wf->nChannels=encoder->params.channels;
+	mux_a->h.dwSampleSize=2*mux_a->wf->nChannels;
+	mux_a->wf->nBlockAlign=mux_a->h.dwSampleSize;
+	mux_a->wf->nSamplesPerSec=mux_a->h.dwRate;
+	mux_a->wf->nAvgBytesPerSec=mux_a->h.dwSampleSize*mux_a->wf->nSamplesPerSec;
+	mux_a->wf->wBitsPerSample=16;
+	mux_a->wf->cbSize=0; // FIXME for l3codeca.acm
+	
+	encoder->input_format = (mux_a->wf->wBitsPerSample==8) ? AF_FORMAT_U8 : AF_FORMAT_S16_LE;
+	encoder->min_buffer_size = 16384;
+	encoder->max_buffer_size = mux_a->wf->nAvgBytesPerSec;
+	
+	return 1;
+}
+
+static int encode_pcm(audio_encoder_t *encoder, uint8_t *dest, void *src, int nsamples, int max_size)
+{
+	max_size = min(nsamples, max_size);
+	memcpy(dest, src, max_size);
+	return max_size;
+}
+
+static void set_decoded_len(audio_encoder_t *encoder, int len)
+{
+	return;
+}
+
+static int close_pcm(audio_encoder_t *encoder)
+{
+	return 1;
+}
+
+static int get_frame_size(audio_encoder_t *encoder)
+{
+	return 0;
+}
+
+int mpae_init_pcm(audio_encoder_t *encoder)
+{
+	encoder->params.samples_per_frame = encoder->params.sample_rate;
+	encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8;
+	
+	encoder->decode_buffer_size = encoder->params.bitrate / 8;
+	encoder->bind = bind_pcm;
+	encoder->get_frame_size = get_frame_size;
+	encoder->set_decoded_len = set_decoded_len;
+	encoder->encode = encode_pcm;
+	encoder->close = close_pcm;
+	
+	return 1;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae_pcm.h	Fri Apr 22 06:59:59 2005 +0000
@@ -0,0 +1,8 @@
+#ifndef __AE_PCM_H_
+#define __AE_PCM_H_
+
+#include "ae.h"
+
+int mpae_init_pcm(audio_encoder_t *encoder);
+
+#endif
--- a/libmpcodecs/ae_toolame.c	Thu Apr 21 21:23:53 2005 +0000
+++ b/libmpcodecs/ae_toolame.c	Fri Apr 22 06:59:59 2005 +0000
@@ -1,13 +1,19 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
 #include "m_option.h"
 #include "../mp_msg.h"
-#include <stdlib.h>
-#include <inttypes.h>
+#include "aviheader.h"
+#include "../libaf/af_format.h"
+#include "ms_hdr.h"
+#include "muxer.h"
 #include "ae_toolame.h"
+#include "../libmpdemux/mp3_hdr.h"
 
 
 static int 
     param_bitrate = 192,
-    param_srate = 48000,
     param_psy = 3,
     param_maxvbr = 192,
     param_errprot = 0,
@@ -28,17 +34,95 @@
 };
 
 
-mpae_toolame_ctx *mpae_init_toolame(int channels, int srate)
+static int bind_toolame(audio_encoder_t *encoder, muxer_stream_t *mux_a)
+{
+	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 = 125 * encoder->params.bitrate;
+	mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec;
+	mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * encoder->params.samples_per_frame)/ mux_a->wf->nSamplesPerSec; /* for cbr */
+	
+	if((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.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 = 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_toolame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size)
+{
+	mpae_toolame_ctx *ctx = (mpae_toolame_ctx *)encoder->priv;
+	int ret_size = 0, i, nsamples;
+	int16_t *buffer;
+	
+	nsamples = len / (2*encoder->params.channels);
+	buffer = (uint16_t *) src;
+	for(i = 0; i < nsamples; i++)
+	{
+	    ctx->left_pcm[i] = buffer[ctx->channels * i];
+	    ctx->right_pcm[i] = buffer[(ctx->channels * i) + (ctx->channels - 1)];
+	}
+	
+	toolame_encode_buffer(ctx->toolame_ctx, ctx->left_pcm, ctx->right_pcm, nsamples, dest, max_size, &ret_size);
+	return ret_size;
+}
+
+int close_toolame(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_toolame(audio_encoder_t *encoder)
 {
 	int mode;
 	mpae_toolame_ctx *ctx = NULL;
 	
-	if(channels == 1)
+	if(encoder->params.channels == 1)
 	{
 		mp_msg(MSGT_MENCODER, MSGL_INFO, "ae_toolame, 1 audio channel, forcing mono mode\n");
 		mode = MPG_MD_MONO;
 	}
-	else if(channels == 2)
+	else if(encoder->params.channels == 2)
 	{
 		if(! strcasecmp(param_mode, "dual"))
 			mode = MPG_MD_DUAL_CHANNEL;
@@ -58,7 +142,7 @@
 	if(ctx == NULL)
 	{
 		mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_toolame, couldn't alloc a %d bytes context, exiting\n", sizeof(mpae_toolame_ctx));
-		return NULL;
+		return 0;
 	}
 	
 	ctx->toolame_ctx = toolame_init();
@@ -66,64 +150,56 @@
 	{
 		mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_toolame, couldn't initial parameters from libtoolame, exiting\n");
 		free(ctx);
-		return NULL;
+		return 0;
 	}
-	ctx->channels = channels;
-	ctx->srate = srate;
+	ctx->channels = encoder->params.channels;
+	ctx->srate = encoder->params.sample_rate;
 
 	if(toolame_setMode(ctx->toolame_ctx, mode) != 0)
-		return NULL;
+		return 0;
 	
 	if(toolame_setPsymodel(ctx->toolame_ctx, param_psy) != 0)
-		return NULL;
+		return 0;
 	
-	if(toolame_setSampleFreq(ctx->toolame_ctx, srate) != 0)
-		return NULL;
+	if(toolame_setSampleFreq(ctx->toolame_ctx, encoder->params.sample_rate) != 0)
+		return 0;
 	
 	if(toolame_setBitrate(ctx->toolame_ctx, param_bitrate) != 0)
-		return NULL;
+		return 0;
 	
 	if(param_errprot)
 		if(toolame_setErrorProtection(ctx->toolame_ctx, TRUE) != 0)
-			return NULL;
+			return 0;
 	
 	if(param_vbr > 0)
 	{
 		if(toolame_setVBR(ctx->toolame_ctx, TRUE) != 0)
-			return NULL;
+			return 0;
 		if(toolame_setVBRLevel(ctx->toolame_ctx, param_maxvbr) != 0)
-			return NULL;
+			return 0;
 		if(toolame_setPadding(ctx->toolame_ctx, FALSE) != 0)
-			return NULL;
+			return 0;
 		if(toolame_setVBRUpperBitrate(ctx->toolame_ctx, param_maxvbr) != 0)
-			return NULL;
+			return 0;
 	}
 	
 	if(toolame_setVerbosity(ctx->toolame_ctx, param_debug) != 0)
-		return NULL;
+		return 0;
 	
 	if(toolame_init_params(ctx->toolame_ctx) != 0)
-		return NULL;
+		return 0;
 	
 	ctx->bitrate = param_bitrate;
+	encoder->params.bitrate = ctx->bitrate;
+	encoder->params.samples_per_frame = 1152;
+	encoder->priv = ctx;
+	encoder->decode_buffer_size = 1152 * 2 * encoder->params.channels;
 	
-	return ctx;
+	encoder->bind = bind_toolame;
+	encoder->get_frame_size = get_frame_size;
+	encoder->encode = encode_toolame;
+	encoder->close = close_toolame;
+	
+	return 1;
 }
 
-
-int mpae_encode_toolame(mpae_toolame_ctx *ctx, uint8_t *dest, int nsamples, void *src, int max_size)
-{
-	int ret_size = 0, i;
-	int16_t *buffer;
-	
-	buffer = (uint16_t *) src;
-	for(i = 0; i < nsamples; i++)
-	{
-	    ctx->left_pcm[i] = buffer[ctx->channels * i];
-	    ctx->right_pcm[i] = buffer[(ctx->channels * i) + (ctx->channels - 1)];
-	}
-	
-	toolame_encode_buffer(ctx->toolame_ctx, ctx->left_pcm, ctx->right_pcm, nsamples, dest, max_size, &ret_size);
-	
-	return ret_size;
-}
--- a/libmpcodecs/ae_toolame.h	Thu Apr 21 21:23:53 2005 +0000
+++ b/libmpcodecs/ae_toolame.h	Fri Apr 22 06:59:59 2005 +0000
@@ -1,6 +1,7 @@
 #ifndef MPAE_TOOLAME_H
 #define MPAE_TOOLAME_H
 
+#include "ae.h"
 #include <toolame.h>
 
 typedef struct {
@@ -9,7 +10,6 @@
 	int16_t left_pcm[1152], right_pcm[1152];
 } mpae_toolame_ctx;
 
-mpae_toolame_ctx *mpae_init_toolame(int channels, int srate);
-int mpae_encode_toolame(mpae_toolame_ctx *ctx, uint8_t *dest, int nsamples, void *src, int max_size);
+int mpae_init_toolame(audio_encoder_t *encoder);
 
 #endif
--- a/mencoder.c	Thu Apr 21 21:23:53 2005 +0000
+++ b/mencoder.c	Fri Apr 22 06:59:59 2005 +0000
@@ -64,11 +64,6 @@
 // for MPEGLAYER3WAVEFORMAT:
 #include "libmpdemux/ms_hdr.h"
 
-#ifdef HAVE_MP3LAME
-#undef CDECL
-#include <lame/lame.h>
-#endif
-
 #include <inttypes.h>
 
 #include "libvo/fastmemcpy.h"
@@ -76,31 +71,14 @@
 #include "osdep/timer.h"
 
 #ifdef USE_LIBAVCODEC
-// for lavc audio encoding
-
 #ifdef USE_LIBAVCODEC_SO
 #include <ffmpeg/avcodec.h>
 #else
 #include "libavcodec/avcodec.h"
 #endif
-
-static AVCodec        *lavc_acodec;
-static AVCodecContext *lavc_actx = NULL;
-extern char    *lavc_param_acodec;
-extern int      lavc_param_abitrate;
-extern int      lavc_param_atag;
-// tmp buffer for lavc audio encoding (to free!!!!!)
-static void    *lavc_abuf = NULL;
-extern int      avcodec_inited;
-
-static uint32_t lavc_find_atag(char *codec);
 #endif
 
-#ifdef HAVE_TOOLAME
-#include "libmpcodecs/ae_toolame.h"
-static mpae_toolame_ctx *mpae_toolame;
-#endif
-
+#include "libmpcodecs/ae.h"
 int vo_doublebuffering=0;
 int vo_directrendering=0;
 int vo_config_count=0;
@@ -229,29 +207,6 @@
 //#include "libmpeg2/mpeg2.h"
 //#include "libmpeg2/mpeg2_internal.h"
 
-#ifdef HAVE_MP3LAME
-int lame_param_quality=0; // best
-int lame_param_algqual=5; // same as old default
-int lame_param_vbr=vbr_default;
-int lame_param_mode=-1; // unset
-int lame_param_padding=-1; // unset
-int lame_param_br=-1; // unset
-int lame_param_ratio=-1; // unset
-float lame_param_scale=-1; // unset
-int lame_param_lowpassfreq = 0; //auto
-int lame_param_highpassfreq = 0; //auto
-int lame_param_free_format = 0; //disabled
-int lame_param_br_min = 0; //not specified
-int lame_param_br_max = 0; //not specified
-
-#if HAVE_MP3LAME >= 392
-int lame_param_fast=0; // unset
-static char* lame_param_preset=NULL; // unset
-static int  lame_presets_set( lame_t gfp, int fast, int cbr, const char* preset_name );
-static void  lame_presets_longinfo_dm ( FILE* msgfp );
-#endif
-#endif
-
 //static int vo_w=0, vo_h=0;
 
 //-------------------------- config stuff:
@@ -397,10 +352,6 @@
 muxer_stream_t* mux_v=NULL;
 off_t muxer_f_size=0;
 
-#ifdef HAVE_MP3LAME
-lame_global_flags *lame;
-#endif
-
 double v_pts_corr=0;
 double v_timer_corr=0;
 
@@ -415,6 +366,9 @@
 
 unsigned int timer_start;
 
+audio_encoding_params_t aparams;
+audio_encoder_t *aencoder = NULL;
+
   mp_msg_init();
   mp_msg_set_level(MSGL_STATUS);
   mp_msg(MSGT_CPLAYER,MSGL_INFO, "MEncoder " VERSION " (C) 2000-2005 MPlayer Team\n");
@@ -852,6 +806,21 @@
 
 mux_a->codec=out_audio_codec;
 
+aparams.channels = audio_output_channels ? audio_output_channels : sh_audio->channels;
+aparams.sample_rate = force_srate ? force_srate : new_srate;
+aparams.audio_preload = 1000 * audio_preload;
+if(mux_a->codec != ACODEC_COPY) {
+    aencoder = new_audio_encoder(mux_a, &aparams);
+    if(!aencoder)
+        mencoder_exit(1, NULL);
+    if(!init_audio_filters(sh_audio, 
+        new_srate, sh_audio->channels, sh_audio->sample_format,  
+        aparams.sample_rate, aparams.channels, aencoder->input_format, 
+        aencoder->min_buffer_size, aencoder->max_buffer_size)) {
+      mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_NoMatchingFilter);
+      mencoder_exit(1,NULL);
+    }
+}
 switch(mux_a->codec){
 case ACODEC_COPY:
     if (playback_speed != 1.0) mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_NoSpeedWithFrameCopy);
@@ -885,271 +854,6 @@
 	mux_a->wf->wFormatTag, mux_a->wf->nChannels, mux_a->wf->nSamplesPerSec,
 	mux_a->wf->wBitsPerSample, mux_a->wf->nAvgBytesPerSec, mux_a->h.dwSampleSize);
     break;
-case ACODEC_PCM:
-    mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_CBRPCMAudioSelected);
-    mux_a->h.dwScale=1;
-    mux_a->h.dwRate=force_srate?force_srate:new_srate;
-    mux_a->wf=malloc(sizeof(WAVEFORMATEX));
-    mux_a->wf->wFormatTag=0x1; // PCM
-    mux_a->wf->nChannels=audio_output_channels?audio_output_channels:sh_audio->channels;
-    mux_a->h.dwSampleSize=2*mux_a->wf->nChannels;
-    mux_a->wf->nBlockAlign=mux_a->h.dwSampleSize;
-    mux_a->wf->nSamplesPerSec=mux_a->h.dwRate;
-    mux_a->wf->nAvgBytesPerSec=mux_a->h.dwSampleSize*mux_a->wf->nSamplesPerSec;
-    mux_a->wf->wBitsPerSample=16;
-    mux_a->wf->cbSize=0; // FIXME for l3codeca.acm
-    // setup filter:
-    if(!init_audio_filters(sh_audio, 
-        new_srate,
-	sh_audio->channels, sh_audio->sample_format,
-	mux_a->wf->nSamplesPerSec, mux_a->wf->nChannels,
-	(mux_a->wf->wBitsPerSample==8)?	AF_FORMAT_U8:AF_FORMAT_S16_LE,
-	16384, mux_a->wf->nAvgBytesPerSec)){
-      mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_NoMatchingFilter);
-    }
-    break;
-#ifdef HAVE_MP3LAME
-case ACODEC_VBRMP3:
-    mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_MP3AudioSelected);
-    mux_a->h.dwSampleSize=0; // VBR
-    mux_a->h.dwRate=force_srate?force_srate:new_srate;
-    mux_a->h.dwScale=(mux_a->h.dwRate<32000)?576:1152; // samples/frame
-    if(sizeof(MPEGLAYER3WAVEFORMAT)!=30) mp_msg(MSGT_MENCODER,MSGL_WARN,MSGTR_MP3WaveFormatSizeNot30,sizeof(MPEGLAYER3WAVEFORMAT));
-    mux_a->wf=malloc(sizeof(MPEGLAYER3WAVEFORMAT)); // should be 30
-    mux_a->wf->wFormatTag=0x55; // MP3
-    mux_a->wf->nChannels= (lame_param_mode<0) ? sh_audio->channels :
-	((lame_param_mode==3) ? 1 : 2);
-    mux_a->wf->nSamplesPerSec=mux_a->h.dwRate;
-    if(! lame_param_vbr)
-        mux_a->wf->nAvgBytesPerSec=lame_param_br * 125;
-    else
-        mux_a->wf->nAvgBytesPerSec=192000/8; // FIXME!
-    mux_a->wf->nBlockAlign=(mux_a->h.dwRate<32000)?576:1152; // required for l3codeca.acm + WMP 6.4
-    mux_a->wf->wBitsPerSample=0; //16;
-    // from NaNdub:  (requires for l3codeca.acm)
-    mux_a->wf->cbSize=12;
-    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->wID=1;
-    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->fdwFlags=2;
-    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nBlockSize=(mux_a->h.dwRate<32000)?576:1152; // ???
-    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nFramesPerBlock=1;
-    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nCodecDelay=0;
-    // setup filter:
-    if(!init_audio_filters(sh_audio, 
-	new_srate,
-	sh_audio->channels, sh_audio->sample_format,
-	mux_a->wf->nSamplesPerSec, mux_a->wf->nChannels,
-	AF_FORMAT_S16_NE,
-	4608, mux_a->h.dwRate*mux_a->wf->nChannels*2)){
-      mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_NoMatchingFilter);
-    }
-    break;
-#endif
-#ifdef USE_LIBAVCODEC
-case ACODEC_LAVC:
-    if(!lavc_param_acodec)
-    {
-	mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName);
-	exit(1);
-    }
-
-    if(!avcodec_inited){
-	avcodec_init();
-	avcodec_register_all();
-	avcodec_inited=1;
-    }
-
-    lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec);
-    if (!lavc_acodec)
-    {
-	mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LavcAudioCodecNotFound, lavc_param_acodec);
-	exit(1);
-    }
-
-    lavc_actx = avcodec_alloc_context();
-    if(lavc_actx == NULL)
-    {
-	mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext);
-	exit(1);
-    }
-
-    if(lavc_param_atag == 0)
-	lavc_param_atag = lavc_find_atag(lavc_param_acodec);
-
-    // put sample parameters
-    lavc_actx->channels = audio_output_channels ? audio_output_channels : sh_audio->channels;
-    lavc_actx->sample_rate = force_srate ? force_srate : new_srate;
-    lavc_actx->bit_rate = lavc_param_abitrate * 1000;
-
-    /*
-     * Special case for imaadpcm.
-     * The bitrate is only dependant on samplerate.
-     * We have to known frame_size and block_align in advance,
-     * so I just copied the code from libavcodec/adpcm.c
-     *
-     * However, ms imaadpcm uses a block_align of 2048,
-     * lavc defaults to 1024
-     */
-    if(lavc_param_atag == 0x11) {
-	int blkalign = 2048;
-	int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1;
-	lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize;
-    }
-
-    if(avcodec_open(lavc_actx, lavc_acodec) < 0)
-    {
-	mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate);
-	exit(1);
-    }
-
-    if(lavc_param_atag == 0x11) {
-	lavc_actx->block_align = 2048;
-	lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1;
-    }
-
-    lavc_abuf = malloc(lavc_actx->frame_size * 2 * lavc_actx->channels);
-    if(lavc_abuf == NULL)
-    {
-	mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CannotAllocateBytes, lavc_actx->frame_size * 2 * lavc_actx->channels);
-	exit(1);
-    }
-
-    mux_a->wf = malloc(sizeof(WAVEFORMATEX)+lavc_actx->extradata_size+256);
-    mux_a->wf->wFormatTag = lavc_param_atag;
-    mux_a->wf->nChannels = lavc_actx->channels;
-    mux_a->wf->nSamplesPerSec = lavc_actx->sample_rate;
-    mux_a->wf->nAvgBytesPerSec = (lavc_actx->bit_rate / 8);
-    mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec;
-    if (lavc_actx->block_align) {
-	mux_a->h.dwSampleSize = mux_a->h.dwScale = lavc_actx->block_align;
-    } else {
-	mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * lavc_actx->frame_size)/ mux_a->wf->nSamplesPerSec; /* for cbr */
-
-	if ((mux_a->wf->nAvgBytesPerSec *
-	    lavc_actx->frame_size) % mux_a->wf->nSamplesPerSec) {
-	    mux_a->h.dwScale = lavc_actx->frame_size;
-	    mux_a->h.dwRate = lavc_actx->sample_rate;
-	    mux_a->h.dwSampleSize = 0; // Blocksize not constant
-	} else {
-	    mux_a->h.dwSampleSize = mux_a->h.dwScale;
-	}
-    }
-    mux_a->wf->nBlockAlign = mux_a->h.dwScale;
-    mux_a->h.dwSuggestedBufferSize = audio_preload*mux_a->wf->nAvgBytesPerSec;
-    mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign;
-
-    switch (lavc_param_atag) {
-    case 0x11: /* imaadpcm */
-	mux_a->wf->wBitsPerSample = 4;
-	mux_a->wf->cbSize = 2;
-	((uint16_t*)mux_a->wf)[sizeof(WAVEFORMATEX)] = 
-	    ((lavc_actx->block_align - 4 * lavc_actx->channels) / (4 * lavc_actx->channels)) * 8 + 1;
-	break;
-    case 0x55: /* mp3 */
-	mux_a->wf->cbSize = 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;
-	break;
-    default:
-	mux_a->wf->wBitsPerSample = 0; /* Unknown */
-	if (lavc_actx->extradata && (lavc_actx->extradata_size > 0))
-	{
-	    memcpy(mux_a->wf+sizeof(WAVEFORMATEX), lavc_actx->extradata,
-		    lavc_actx->extradata_size);
-	    mux_a->wf->cbSize = lavc_actx->extradata_size;
-	}
-	else
-	    mux_a->wf->cbSize = 0;
-	break;
-    }
-
-    // Fix allocation    
-    mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize);
-
-    // setup filter:
-    if (!init_audio_filters(
-	sh_audio,
-	new_srate, sh_audio->channels,
-	sh_audio->sample_format,
-	mux_a->wf->nSamplesPerSec, mux_a->wf->nChannels,
-	AF_FORMAT_S16_NE,
-	mux_a->h.dwSuggestedBufferSize,
-	mux_a->h.dwSuggestedBufferSize*2)) {
-	mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_NoMatchingFilter);
-	exit(1);
-    }
-
-    mp_msg(MSGT_MENCODER, MSGL_V, "FRAME_SIZE: %d, BUFFER_SIZE: %d, TAG: 0x%x\n", lavc_actx->frame_size, lavc_actx->frame_size * 2 * lavc_actx->channels, mux_a->wf->wFormatTag);
-
-    break;
-#endif
-
-#ifdef HAVE_TOOLAME
-case ACODEC_TOOLAME:
-{
-    int cn = audio_output_channels ? audio_output_channels : sh_audio->channels;
-    int sr = force_srate ? force_srate : new_srate;
-    int br;
-
-    mpae_toolame = mpae_init_toolame(cn, sr);
-    if(mpae_toolame == NULL)
-    {
-	mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't open toolame codec, exiting\n");
-	exit(1);
-    }
-    
-    br = mpae_toolame->bitrate;
-
-    mux_a->wf = malloc(sizeof(WAVEFORMATEX)+256);
-    mux_a->wf->wFormatTag = 0x50;
-    mux_a->wf->nChannels = cn;
-    mux_a->wf->nSamplesPerSec = sr;
-    mux_a->wf->nAvgBytesPerSec = 1000 * (br / 8);
-    mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec;
-    mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * 1152)/ mux_a->wf->nSamplesPerSec; /* for cbr */
-
-    if ((mux_a->wf->nAvgBytesPerSec *
-	1152) % mux_a->wf->nSamplesPerSec) {
-	mux_a->h.dwScale = 1152;
-	mux_a->h.dwRate = sr;
-	mux_a->h.dwSampleSize = 0; // Blocksize not constant
-    } else {
-	mux_a->h.dwSampleSize = mux_a->h.dwScale;
-    }
-    mux_a->wf->nBlockAlign = mux_a->h.dwScale;
-    mux_a->h.dwSuggestedBufferSize = audio_preload*mux_a->wf->nAvgBytesPerSec;
-    mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign;
-
-    mux_a->wf->cbSize = 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);
-
-    // setup filter:
-    if (!init_audio_filters(
-	sh_audio,
-	new_srate, sh_audio->channels,
-	sh_audio->sample_format,
-	mux_a->wf->nSamplesPerSec, mux_a->wf->nChannels,
-	AF_FORMAT_S16_NE,
-	mux_a->h.dwSuggestedBufferSize,
-	mux_a->h.dwSuggestedBufferSize*2)) {
-	mp_msg(MSGT_CPLAYER, MSGL_ERR, "Couldn't find matching filter / ao format!\n");
-	exit(1);
-    }
-
-    break;
-}
-#endif
 }
 
 if (verbose>1) print_wave_header(mux_a->wf);
@@ -1168,54 +872,6 @@
 
 decoded_frameno=0;
 
-if(sh_audio)
-switch(mux_a->codec){
-#ifdef HAVE_MP3LAME
-case ACODEC_VBRMP3:
-
-lame=lame_init();
-lame_set_bWriteVbrTag(lame,0);
-lame_set_in_samplerate(lame,mux_a->wf->nSamplesPerSec);
-//lame_set_in_samplerate(lame,sh_audio->samplerate); // if resampling done by lame
-lame_set_num_channels(lame,mux_a->wf->nChannels);
-lame_set_out_samplerate(lame,mux_a->wf->nSamplesPerSec);
-lame_set_quality(lame,lame_param_algqual); // 0 = best q
-if(lame_param_free_format) lame_set_free_format(lame,1);
-if(lame_param_vbr){  // VBR:
-    lame_set_VBR(lame,lame_param_vbr); // vbr mode
-    lame_set_VBR_q(lame,lame_param_quality); // 0 = best vbr q  5=~128k
-    if(lame_param_br>0) lame_set_VBR_mean_bitrate_kbps(lame,lame_param_br);
-    if(lame_param_br_min>0) lame_set_VBR_min_bitrate_kbps(lame,lame_param_br_min);
-    if(lame_param_br_max>0) lame_set_VBR_max_bitrate_kbps(lame,lame_param_br_max);
-} else {    // CBR:
-    if(lame_param_br>0) lame_set_brate(lame,lame_param_br);
-}
-if(lame_param_mode>=0) lame_set_mode(lame,lame_param_mode); // j-st
-if(lame_param_ratio>0) lame_set_compression_ratio(lame,lame_param_ratio);
-if(lame_param_scale>0) {
-    mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_SettingAudioInputGain, lame_param_scale);
-    lame_set_scale(lame,lame_param_scale);
-}
-if(lame_param_lowpassfreq>=-1) lame_set_lowpassfreq(lame,lame_param_lowpassfreq);
-if(lame_param_highpassfreq>=-1) lame_set_highpassfreq(lame,lame_param_highpassfreq);
-#if HAVE_MP3LAME >= 392
-if(lame_param_preset != NULL){
-  mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_LamePresetEquals,lame_param_preset);
-  lame_presets_set(lame,lame_param_fast, (lame_param_vbr==0), lame_param_preset);
-}
-#endif
-if(lame_init_params(lame) == -1){
-    mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LameCantInit); 
-    mencoder_exit(1,NULL);
-}
-if(verbose>0){
-    lame_print_config(lame);
-    lame_print_internals(lame);
-}
-break;
-#endif
-}
-
 signal(SIGINT,exit_sighandler);  // Interrupt from keyboard
 signal(SIGQUIT,exit_sighandler); // Quit from keyboard
 signal(SIGTERM,exit_sighandler); // kill
@@ -1225,6 +881,12 @@
 else if (sh_audio) {
 	int out_format = 0, out_minsize = 0, out_maxsize = 0;
 	int do_init_filters = 1;
+	if((aencoder != NULL) && (mux_a->codec != ACODEC_COPY))
+	{
+		out_format = aencoder->input_format;
+		out_minsize = aencoder->min_buffer_size;
+		out_maxsize = aencoder->max_buffer_size;
+	}
 	switch(mux_a->codec){
 		case ACODEC_COPY:
 			do_init_filters = 0;
@@ -1258,36 +920,6 @@
 				
 			}
 			break;
-		case ACODEC_PCM:
-			mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_CBRPCMAudioSelected);
-			out_format = (mux_a->wf->wBitsPerSample==8) ? AF_FORMAT_U8 : AF_FORMAT_S16_LE;
-			out_minsize = 16384;
-			out_maxsize = mux_a->wf->nAvgBytesPerSec;
-			break;
-#ifdef HAVE_MP3LAME
-		case ACODEC_VBRMP3:
-			mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_MP3AudioSelected);
-			out_format = AF_FORMAT_S16_NE;
-			out_minsize = 4608;
-			out_maxsize = mux_a->h.dwRate*mux_a->wf->nChannels*2;
-			break;
-#endif
-#ifdef USE_LIBAVCODEC
-		case ACODEC_LAVC:
-			out_format = AF_FORMAT_S16_NE;
-			out_minsize = mux_a->h.dwSuggestedBufferSize;
-			out_maxsize = mux_a->h.dwSuggestedBufferSize*2;
-			mp_msg(MSGT_MENCODER, MSGL_V, "FRAME_SIZE: %d, BUFFER_SIZE: %d, TAG: 0x%x\n",
-			       lavc_actx->frame_size, lavc_actx->frame_size * 2 * lavc_actx->channels, mux_a->wf->wFormatTag);
-			break;
-#endif
-#ifdef HAVE_TOOLAME
-		case ACODEC_TOOLAME:
-			out_format = AF_FORMAT_S16_NE;
-			out_minsize = mux_a->h.dwSuggestedBufferSize;
-			out_maxsize = mux_a->h.dwSuggestedBufferSize*2;
-			break;
-#endif
 	}
 	if (do_init_filters) if(!init_audio_filters(sh_audio,
 	    new_srate,
@@ -1300,7 +932,7 @@
 	    out_maxsize))
 	{
 		mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_NoMatchingFilter);
-		exit(1);
+		mencoder_exit(1, NULL);
 	}
 }
 
@@ -1420,71 +1052,67 @@
 if(sh_audio){
     // get audio:
     while(mux_a->timer-audio_preload<mux_v->timer){
+        float tottime;
 	int len=0;
 
 	ptimer_start = GetTimerMS();
+	// CBR - copy 0.5 sec of audio
+	// or until the end of video:
+	tottime = stop_time(demuxer, mux_v);
+	if (tottime != -1) {
+		tottime -= mux_a->timer;
+		if (tottime > 1./audio_density) tottime = 1./audio_density;
+	}
+	else tottime = 1./audio_density;
 
-#ifdef USE_LIBAVCODEC
-	if(mux_a->codec == ACODEC_LAVC){
-	    int  size, rd_len;
-	
-	    size = lavc_actx->frame_size * 2 * mux_a->wf->nChannels;
 
-	    rd_len = dec_audio(sh_audio, lavc_abuf, size);
-	    if(rd_len != size)
-		break;
+	if(aencoder)
+	{
+		if(mux_a->h.dwSampleSize) /* CBR */
+		{
+			if(aencoder->set_decoded_len)
+			{
+				len = mux_a->h.dwSampleSize*(int)(mux_a->h.dwRate*tottime);
+				aencoder->set_decoded_len(aencoder, len);
+			}
+			else
+				len = aencoder->decode_buffer_size;
 
-	    // Encode one frame
-	    mux_a->buffer_len += avcodec_encode_audio(lavc_actx, mux_a->buffer + mux_a->buffer_len, size, lavc_abuf);
-	    if (mux_a->h.dwSampleSize) { /* CBR */
-		/*
-		 * work around peculiar lame behaviour
-		 */
-		if (mux_a->buffer_len < mux_a->wf->nBlockAlign) {
-		    len = 0;
-		} else {
-		    len = mux_a->wf->nBlockAlign*(mux_a->buffer_len/mux_a->wf->nBlockAlign);
+			len = dec_audio(sh_audio, aencoder->decode_buffer, len);
+			mux_a->buffer_len += aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, 
+				(void*)aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len);
+			if(mux_a->buffer_len < mux_a->wf->nBlockAlign)
+				len = 0;
+			else 
+				len = mux_a->wf->nBlockAlign*(mux_a->buffer_len/mux_a->wf->nBlockAlign);
 		}
-	    } else { /* VBR */
-		len = mux_a->buffer_len;
+		else	/* VBR */
+		{
+			int sz = 0;
+			while(1)
+			{
+				len = 0;
+				if(! sz)
+					sz = aencoder->get_frame_size(aencoder);
+				if(sz > 0 && mux_a->buffer_len >= sz)
+				{
+					len = sz;
+					break;
+				}
+				len = dec_audio(sh_audio,aencoder->decode_buffer, aencoder->decode_buffer_size);
+				if(len <= 0)
+				{
+					len = 0;
+					break;
+				}
+				len = aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, (void*)aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len);
+				mux_a->buffer_len += len;
+			}
 	    }
 	    if (mux_v->timer == 0) mux_a->h.dwInitialFrames++;
 	}
-#endif
-#ifdef HAVE_TOOLAME
-	if((mux_a->codec == ACODEC_TOOLAME) && (mpae_toolame != NULL)){
-	    int  size, rd_len;
-	    uint8_t buf[1152*2*2];
-	    size = 1152 * 2 * mux_a->wf->nChannels;
-
-	    rd_len = dec_audio(sh_audio, buf, size);
-	    if(rd_len != size)
-		break;
-
-	    // Encode one frame
-	    mux_a->buffer_len += mpae_encode_toolame(mpae_toolame, mux_a->buffer + mux_a->buffer_len, 1152, (void*)buf, mux_a->buffer_size-mux_a->buffer_len);
-	    if (mux_a->h.dwSampleSize) { /* CBR */
-		if (mux_a->buffer_len < mux_a->wf->nBlockAlign) {
-		    len = 0;
-		} else {
-		    len = mux_a->wf->nBlockAlign*(mux_a->buffer_len/mux_a->wf->nBlockAlign);
-		}
-	    } else { /* VBR */
-		len = mux_a->buffer_len;
-	    }
-	    if (mux_v->timer == 0) mux_a->h.dwInitialFrames++;
-	}
-#endif
+	else {
 	if(mux_a->h.dwSampleSize){
-	    // CBR - copy 0.5 sec of audio
-	    // or until the end of video:
-	    float tottime = stop_time(demuxer, mux_v);
-	    if (tottime != -1) {
-		    tottime -= mux_a->timer;
-		    if (tottime > 1./audio_density) tottime = 1./audio_density;
-	    }
-	    else tottime = 1./audio_density;
-	    
 	    switch(mux_a->codec){
 	    case ACODEC_COPY: // copy
 		len=mux_a->wf->nAvgBytesPerSec*tottime;
@@ -1492,65 +1120,14 @@
 		len*=mux_a->h.dwSampleSize;
 		len=demux_read_data(sh_audio->ds,mux_a->buffer,len);
 		break;
-	    case ACODEC_PCM:
-		len=mux_a->h.dwSampleSize*(int)(mux_a->h.dwRate*tottime);
-		len=dec_audio(sh_audio,mux_a->buffer,len);
-		break;
 	    }
 	} else {
 	    // VBR - encode/copy an audio frame
 	    switch(mux_a->codec){
 	    case ACODEC_COPY: // copy
 		len=ds_get_packet(sh_audio->ds,(unsigned char**) &mux_a->buffer);
-//		printf("VBR audio framecopy not yet implemented!\n");
 		break;
-#ifdef HAVE_MP3LAME
-	    case ACODEC_VBRMP3:
-		while(mux_a->buffer_len<4){
-		  unsigned char tmp[2304];
-		  int len=dec_audio(sh_audio,tmp,2304);
-		  if(len<=0) break; // eof
-		  /* mono encoding, a bit tricky */
-		  if (mux_a->wf->nChannels == 1)
-		  {
-		    len = lame_encode_buffer(lame, (short *)tmp, (short *)tmp, len/2,
-			mux_a->buffer+mux_a->buffer_len, mux_a->buffer_size-mux_a->buffer_len);
-		  }
-		  else
-		  {
-		    len=lame_encode_buffer_interleaved(lame,
-		      (short *)tmp,len/4,
-		      mux_a->buffer+mux_a->buffer_len,mux_a->buffer_size-mux_a->buffer_len);
-		  }
-		  if(len<0) break; // error
-		  mux_a->buffer_len+=len;
 		}
-		if(mux_a->buffer_len<4) break;
-		len=mp_decode_mp3_header(mux_a->buffer);
-		//printf("%d\n",len);
-		if(len<=0) break; // bad frame!
-//		printf("[%d]\n",mp_mp3_get_lsf(mux_a->buffer));
-		while(mux_a->buffer_len<len){
-		  unsigned char tmp[2304];
-		  int len=dec_audio(sh_audio,tmp,2304);
-		  if(len<=0) break; // eof
-		  /* mono encoding, a bit tricky */
-		  if (mux_a->wf->nChannels == 1)
-		  {
-		    len = lame_encode_buffer(lame, (short *)tmp, (short *)tmp, len/2,
-			mux_a->buffer+mux_a->buffer_len, mux_a->buffer_size-mux_a->buffer_len);
-		  }
-		  else
-		  {
-		    len=lame_encode_buffer_interleaved(lame,
-		      (short *)tmp,len/4,
-		      mux_a->buffer+mux_a->buffer_len,mux_a->buffer_size-mux_a->buffer_len);
-		  }
-		  if(len<0) break; // error
-		  mux_a->buffer_len+=len;
-		}
-		break;
-#endif
 	    }
 	}
 	if(len<=0) break; // EOF?
@@ -1858,20 +1435,9 @@
     	                                              VFCTRL_FLUSH_FRAMES, 0);
 }
 
-#ifdef HAVE_MP3LAME
-// fixup CBR mp3 audio header:
-if(sh_audio && mux_a->codec==ACODEC_VBRMP3 && !lame_param_vbr){
-    mux_a->h.dwSampleSize=1;
-    ((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nBlockSize=
-	(mux_a->size+(mux_a->h.dwLength>>1))/mux_a->h.dwLength;
-    mux_a->h.dwLength=mux_a->size;
-    mux_a->h.dwRate=mux_a->wf->nAvgBytesPerSec;
-    mux_a->h.dwScale=1;
-    mux_a->wf->nBlockAlign=1;
-    mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_CBRAudioByterate,
-	    mux_a->h.dwRate,((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nBlockSize);
-}
-#endif
+if(aencoder)
+    if(aencoder->fixup)
+        aencoder->fixup(aencoder);
 
 mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_WritingAVIIndex);
 if (muxer->cont_write_index) muxer_write_index(muxer);
@@ -1905,11 +1471,6 @@
 if(demuxer) free_demuxer(demuxer);
 if(stream) free_stream(stream); // kill cache thread
 
-#ifdef USE_LIBAVCODEC
-if(lavc_abuf != NULL)
-    free(lavc_abuf);
-#endif
-
 return interrupted;
 }
 
@@ -1978,163 +1539,6 @@
 }
 #endif
 
-#if HAVE_MP3LAME >= 392
-/* lame_presets_set 
-   taken out of presets_set in lame-3.93.1/frontend/parse.c and modified */
-static int  lame_presets_set( lame_t gfp, int fast, int cbr, const char* preset_name )
-{
-    int mono = 0;
-
-    if (strcmp(preset_name, "help") == 0) {
-        mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_LameVersion, get_lame_version(), get_lame_url());
-        lame_presets_longinfo_dm( stdout );
-        return -1;
-    }
-
-
-
-    //aliases for compatibility with old presets
-
-    if (strcmp(preset_name, "phone") == 0) {
-        preset_name = "16";
-        mono = 1;
-    }
-    if ( (strcmp(preset_name, "phon+") == 0) ||
-         (strcmp(preset_name, "lw") == 0) ||
-         (strcmp(preset_name, "mw-eu") == 0) ||
-         (strcmp(preset_name, "sw") == 0)) {
-        preset_name = "24";
-        mono = 1;
-    }
-    if (strcmp(preset_name, "mw-us") == 0) {
-        preset_name = "40";
-        mono = 1;
-    }
-    if (strcmp(preset_name, "voice") == 0) {
-        preset_name = "56";
-        mono = 1;
-    }
-    if (strcmp(preset_name, "fm") == 0) {
-        preset_name = "112";
-    }
-    if ( (strcmp(preset_name, "radio") == 0) ||
-         (strcmp(preset_name, "tape") == 0)) {
-        preset_name = "112";
-    }
-    if (strcmp(preset_name, "hifi") == 0) {
-        preset_name = "160";
-    }
-    if (strcmp(preset_name, "cd") == 0) {
-        preset_name = "192";
-    }
-    if (strcmp(preset_name, "studio") == 0) {
-        preset_name = "256";
-    }
-
-#if HAVE_MP3LAME >= 393
-    if (strcmp(preset_name, "medium") == 0) {
-
-        if (fast > 0)
-           lame_set_preset(gfp, MEDIUM_FAST);
-        else
-           lame_set_preset(gfp, MEDIUM);
-
-        return 0;
-    }
-#endif
-    
-    if (strcmp(preset_name, "standard") == 0) {
-
-        if (fast > 0)
-           lame_set_preset(gfp, STANDARD_FAST);
-        else
-           lame_set_preset(gfp, STANDARD);
-
-        return 0;
-    }
-    
-    else if (strcmp(preset_name, "extreme") == 0){
-
-        if (fast > 0)
-           lame_set_preset(gfp, EXTREME_FAST);
-        else
-           lame_set_preset(gfp, EXTREME);
-
-        return 0;
-    }
-    					
-    else if (((strcmp(preset_name, "insane") == 0) || 
-              (strcmp(preset_name, "320"   ) == 0))   && (fast < 1)) {
-
-        lame_set_preset(gfp, INSANE);
- 
-        return 0;
-    }
-
-    // Generic ABR Preset
-    if (((atoi(preset_name)) > 0) &&  (fast < 1)) {
-        if ((atoi(preset_name)) >= 8 && (atoi(preset_name)) <= 320){
-            lame_set_preset(gfp, atoi(preset_name));
-
-            if (cbr == 1 )
-                lame_set_VBR(gfp, vbr_off);
-
-            if (mono == 1 ) {
-                lame_set_mode(gfp, MONO);
-            }
-
-            return 0;
-
-        }
-        else {
-            mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_LameVersion, get_lame_version(), get_lame_url());
-            mp_msg(MSGT_MENCODER, MSGL_ERR, MSGTR_InvalidBitrateForLamePreset);
-            return -1;
-        }
-    }
-
-
-
-    mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_LameVersion, get_lame_version(), get_lame_url());
-    mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_InvalidLamePresetOptions);
-    mencoder_exit(1, MSGTR_ErrorParsingCommandLine);
-}
-#endif
-
-#if HAVE_MP3LAME >= 392
-/* lame_presets_longinfo_dm
-   taken out of presets_longinfo_dm in lame-3.93.1/frontend/parse.c and modified */
-static void  lame_presets_longinfo_dm ( FILE* msgfp )
-{
-        mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_LamePresetsLongInfo);
-	mencoder_exit(0, NULL);
-}
-#endif
-
-#ifdef USE_LIBAVCODEC
-static uint32_t lavc_find_atag(char *codec)
-{
-    if(codec == NULL)
-       return 0;
-
-    if(! strcasecmp(codec, "mp2"))
-       return 0x50;
-
-    if(! strcasecmp(codec, "mp3"))
-       return 0x55;
-
-    if(! strcasecmp(codec, "ac3"))
-       return 0x2000;
-
-    if(! strcasecmp(codec, "adpcm_ima_wav"))
-       return 0x11;
-
-    if(! strncasecmp(codec, "bonk", 4))
-       return 0x2048;
-
-    return 0;
-}
-#endif
 
 static float stop_time(demuxer_t* demuxer, muxer_stream_t* mux_v) {
 	float timeleft = -1;