From dac324322af86902eac3283e9dabf19aa0f68305 Mon Sep 17 00:00:00 2001 From: arpi Date: Tue, 23 Oct 2001 12:03:41 +0000 Subject: [PATCH] libmad (ARM) patch by jeroen.dobbelaere@acunia.com git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2416 b3059339-0415-0410-9bf9-f77b7e298cf2 --- Makefile | 4 +- codec-cfg.c | 1 + codec-cfg.h | 1 + dec_audio.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++- etc/codecs.conf | 11 ++++ 5 files changed, 163 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 7c02bb380c..fa7dc02d03 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,8 @@ BINDIR = ${prefix}/bin # BINDIR = /usr/local/bin SRCS = xacodec.c cpudetect.c postproc/swscale.c postproc/postprocess.c mp_msg.c ac3-iec958.c find_sub.c dec_audio.c dec_video.c codec-cfg.c subreader.c linux/getch2.c linux/timer-lx.c linux/shmem.c xa/xa_gsm.c xa/rle8.c lirc_mp.c cfgparser.c mixer.c spudec.c OBJS = $(SRCS:.c=.o) -CFLAGS = $(OPTFLAGS) -Ilibmpdemux -Iloader -Ilibvo $(CSS_INC) $(EXTRA_INC) # -Wall -A_LIBS = -Lmp3lib -lMP3 -Llibac3 -lac3 $(ALSA_LIB) $(ESD_LIB) +CFLAGS = $(OPTFLAGS) -Ilibmpdemux -Iloader -Ilibvo $(CSS_INC) $(EXTRA_INC) $(MADLIB_INC) # -Wall +A_LIBS = -Lmp3lib -lMP3 -Llibac3 -lac3 $(ALSA_LIB) $(ESD_LIB) $(MADLIB_LIB) VO_LIBS = -Llibvo -lvo $(MLIB_LIB) $(X_LIBS) PARTS = libmpdemux mp3lib libac3 libmpeg2 opendivx libavcodec encore libvo libao2 drivers drivers/syncfb diff --git a/codec-cfg.c b/codec-cfg.c index 3f756a416d..64a3c94f5c 100644 --- a/codec-cfg.c +++ b/codec-cfg.c @@ -209,6 +209,7 @@ static short get_driver(char *s,int audioflag) "hwac3", "libvorbis", "ffmpeg", + "libmad", NULL }; static char *videodrv[] = { diff --git a/codec-cfg.h b/codec-cfg.h index e96196acc3..9b1f7858bc 100644 --- a/codec-cfg.h +++ b/codec-cfg.h @@ -29,6 +29,7 @@ #define AFM_HWAC3 9 #define AFM_VORBIS 10 #define AFM_FFMPEG 11 +#define AFM_MAD 12 #define VFM_MPEG 1 #define VFM_VFW 2 diff --git a/dec_audio.c b/dec_audio.c index c6605886bc..439e93c6e7 100644 --- a/dec_audio.c +++ b/dec_audio.c @@ -63,6 +63,55 @@ typedef struct ov_struct_st { extern int avcodec_inited; #endif + + +#ifdef USE_LIBMAD +#include +static struct mad_stream mad_stream; +static struct mad_frame mad_frame; +static struct mad_synth mad_synth; + + +// ensure buffer is filled with some data +static void mad_prepare_buffer(sh_audio_t* sh_audio, struct mad_stream* ms, int length) +{ + if(sh_audio->a_in_buffer_len < length) { + int len = demux_read_data(sh_audio->ds, sh_audio->a_in_buffer+sh_audio->a_in_buffer_len, length-sh_audio->a_in_buffer_len); + sh_audio->a_in_buffer_len += len; + } +} + +static void mad_postprocess_buffer(sh_audio_t* sh_audio, struct mad_stream* ms) +{ + int delta = (unsigned char*)ms->next_frame - (unsigned char *)sh_audio->a_in_buffer; + if(delta != 0) { + sh_audio->a_in_buffer_len -= delta; + memcpy(sh_audio->a_in_buffer, ms->next_frame, sh_audio->a_in_buffer_len); + } +} + + +static inline +signed short mad_scale(mad_fixed_t sample) +{ + /* round */ + sample += (1L << (MAD_F_FRACBITS - 16)); + + /* clip */ + if (sample >= MAD_F_ONE) + sample = MAD_F_ONE - 1; + else if (sample < -MAD_F_ONE) + sample = -MAD_F_ONE; + + /* quantize */ + return sample >> (MAD_F_FRACBITS + 1 - 16); +} +#endif + + + + + int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen); @@ -191,6 +240,17 @@ case AFM_FFMPEG: sh_audio->audio_out_minsize=AVCODEC_MAX_AUDIO_FRAME_SIZE; break; #endif + +#ifdef USE_LIBMAD + case AFM_MAD: + printf(__FILE__ ":%d:mad: setting minimum outputsize\n", __LINE__); + sh_audio->audio_out_minsize=4608; + if(sh_audio->audio_in_minsize<8192) sh_audio->audio_in_minsize=8192; + sh_audio->a_in_buffer_size=sh_audio->audio_in_minsize; + sh_audio->a_in_buffer=malloc(sh_audio->a_in_buffer_size); + sh_audio->a_in_buffer_len=0; + break; +#endif } if(!driver) return 0; @@ -488,6 +548,37 @@ case AFM_VORBIS: { break; } #endif + +#ifdef USE_LIBMAD + case AFM_MAD: + { + printf(__FILE__ ":%d:mad: initialising\n", __LINE__); + mad_frame_init(&mad_frame); + mad_stream_init(&mad_stream); + + printf(__FILE__ ":%d:mad: preparing buffer\n", __LINE__); + mad_prepare_buffer(sh_audio, &mad_stream, sh_audio->a_in_buffer_size); + mad_stream_buffer(&mad_stream, (unsigned char*)(sh_audio->a_in_buffer), sh_audio->a_in_buffer_len); + mad_stream_sync(&mad_stream); + mad_synth_init(&mad_synth); + + if(mad_frame_decode(&mad_frame, &mad_stream) == 0) + { + printf(__FILE__ ":%d:mad: post processing buffer\n", __LINE__); + mad_postprocess_buffer(sh_audio, &mad_stream); + } + else + { + printf(__FILE__ ":%d:mad: frame decoding failed\n", __LINE__); + } + + sh_audio->channels=2; // hack + sh_audio->samplerate=mad_frame.header.sfreq; + sh_audio->i_bps=mad_frame.header.bitrate; + printf(__FILE__ ":%d:mad: continuing\n", __LINE__); + break; + } +#endif } if(!sh_audio->channels || !sh_audio->samplerate){ @@ -741,6 +832,42 @@ int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){ break; } #endif + +#ifdef USE_LIBMAD + case AFM_MAD: + { + mad_prepare_buffer(sh_audio, &mad_stream, sh_audio->a_in_buffer_size); + mad_stream_buffer(&mad_stream, sh_audio->a_in_buffer, sh_audio->a_in_buffer_len); + if(mad_frame_decode(&mad_frame, &mad_stream) == 0) + { + mad_synth_frame(&mad_synth, &mad_frame); + mad_postprocess_buffer(sh_audio, &mad_stream); + + /* and fill buffer */ + + { + int i; + int end_size = mad_synth.pcm.length; + signed short* samples = (signed short*)buf; + if(end_size > maxlen/4) + end_size=maxlen/4; + + for(i=0; ia_in_buffer_len=0; // reset ACM/DShow audio buffer break; + +#ifdef USE_LIBMAD + case AFM_MAD: + mad_prepare_buffer(sh_audio, &mad_stream, sh_audio->a_in_buffer_size); + mad_stream_buffer(&mad_stream, sh_audio->a_in_buffer, sh_audio->a_in_buffer_len); + mad_stream_sync(&mad_stream); + mad_postprocess_buffer(sh_audio, &mad_stream); + break; } - +#endif } void skip_audio_frame(sh_audio_t *sh_audio){ @@ -796,6 +931,18 @@ void skip_audio_frame(sh_audio_t *sh_audio){ demux_read_data(sh_audio->ds,NULL,skip); break; } +#ifdef USE_LIBMAD + case AFM_MAD: + { + mad_prepare_buffer(sh_audio, &mad_stream, sh_audio->a_in_buffer_size); + mad_stream_buffer(&mad_stream, sh_audio->a_in_buffer, sh_audio->a_in_buffer_len); + mad_stream_skip(&mad_stream, 2); + mad_stream_sync(&mad_stream); + mad_postprocess_buffer(sh_audio, &mad_stream); + break; + } +#endif + default: ds_fill_buffer(sh_audio->ds); // skip PCM frame } } diff --git a/etc/codecs.conf b/etc/codecs.conf index 34540e56c8..15213eae57 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -590,6 +590,17 @@ audiocodec mp3 dll "mp3lib (mpglib)" flags seekable +;MAD library +audiocodec mad + info "MAD MPEG layer-2, layer-3" + status working + comment "Optimized for ARM" + format 0x50 + format 0x55 + driver libmad + dll "libmad" + flags seekable + audiocodec ffmp3 info "FFmpeg layer-123 audio decoder - integer only" status working