[MPlayer-cvslog] CVS: main/libmpcodecs ae.c, NONE, 1.1 ae.h, NONE, 1.1 ae_lame.c, NONE, 1.1 ae_lame.h, NONE, 1.1 ae_lavc.c, NONE, 1.1 ae_lavc.h, NONE, 1.1 ae_pcm.c, NONE, 1.1 ae_pcm.h, NONE, 1.1 ae_toolame.c, 1.3, 1.4 ae_toolame.h, 1.1, 1.2

Nico Sabbi CVS syncmail at mplayerhq.hu
Fri Apr 22 08:59:11 CEST 2005


CVS change done by Nico Sabbi CVS

Update of /cvsroot/mplayer/main/libmpcodecs
In directory mail:/var2/tmp/cvs-serv14794

Modified Files:
	ae_toolame.c ae_toolame.h 
Added Files:
	ae.c ae.h ae_lame.c ae_lame.h ae_lavc.c ae_lavc.h ae_pcm.c 
	ae_pcm.h 
Log Message:
audio encoding reworked

--- NEW FILE ---
#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;
}



--- NEW FILE ---

#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

--- NEW FILE ---
#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

--- NEW FILE ---
#ifndef __AE_PCM_H_
#define __AE_PCM_H_

#include "ae.h"

int mpae_init_lame(audio_encoder_t *encoder);

#endif

--- NEW FILE ---
#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;
}


--- NEW FILE ---
#ifndef __AE_LAVC_H_
#define __AE_LAVC_H_

#include "ae.h"

int mpae_init_lavc(audio_encoder_t *encoder);

#endif

--- NEW FILE ---
#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;
}


--- NEW FILE ---
#ifndef __AE_PCM_H_
#define __AE_PCM_H_

#include "ae.h"

int mpae_init_pcm(audio_encoder_t *encoder);

#endif

Index: ae_toolame.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ae_toolame.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ae_toolame.c	21 Jan 2005 07:22:04 -0000	1.3
+++ ae_toolame.c	22 Apr 2005 06:59:08 -0000	1.4
@@ -1,13 +1,19 @@
-#include "m_option.h"
-#include "../mp_msg.h"
+#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_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;
+	
+	encoder->bind = bind_toolame;
+	encoder->get_frame_size = get_frame_size;
+	encoder->encode = encode_toolame;
+	encoder->close = close_toolame;
 	
-	return ctx;
+	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;
-}

Index: ae_toolame.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ae_toolame.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ae_toolame.h	21 Sep 2004 19:43:37 -0000	1.1
+++ ae_toolame.h	22 Apr 2005 06:59:08 -0000	1.2
@@ -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




More information about the MPlayer-cvslog mailing list