Mercurial > mplayer.hg
changeset 2415:58ea110b4036
libmad (ARM) patch by jeroen.dobbelaere@acunia.com
author | arpi |
---|---|
date | Tue, 23 Oct 2001 12:03:41 +0000 |
parents | 557a31eed636 |
children | 25e7342b5171 |
files | Makefile codec-cfg.c codec-cfg.h dec_audio.c etc/codecs.conf |
diffstat | 5 files changed, 163 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Tue Oct 23 12:02:45 2001 +0000 +++ b/Makefile Tue Oct 23 12:03:41 2001 +0000 @@ -18,8 +18,8 @@ # 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
--- a/codec-cfg.c Tue Oct 23 12:02:45 2001 +0000 +++ b/codec-cfg.c Tue Oct 23 12:03:41 2001 +0000 @@ -209,6 +209,7 @@ "hwac3", "libvorbis", "ffmpeg", + "libmad", NULL }; static char *videodrv[] = {
--- a/codec-cfg.h Tue Oct 23 12:02:45 2001 +0000 +++ b/codec-cfg.h Tue Oct 23 12:03:41 2001 +0000 @@ -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
--- a/dec_audio.c Tue Oct 23 12:02:45 2001 +0000 +++ b/dec_audio.c Tue Oct 23 12:03:41 2001 +0000 @@ -63,6 +63,55 @@ extern int avcodec_inited; #endif + + +#ifdef USE_LIBMAD +#include <mad.h> +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 @@ 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 @@ 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 @@ 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; i<mad_synth.pcm.length; ++i) { + *samples++ = mad_scale(mad_synth.pcm.samples[0][i]); + *samples++ = mad_scale(mad_synth.pcm.samples[0][i]); + // *buf++ = mad_scale(mad_synth.pcm.sampAles[1][i]); + } + len = end_size*4; + } + } + else + { + printf(__FILE__ ":%d:mad: frame decoding failed\n", __LINE__); + } + + break; + } +#endif } return len; } @@ -770,8 +897,16 @@ case AFM_HWAC3: sh_audio->a_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 @@ 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 } }
--- a/etc/codecs.conf Tue Oct 23 12:02:45 2001 +0000 +++ b/etc/codecs.conf Tue Oct 23 12:03:41 2001 +0000 @@ -590,6 +590,17 @@ 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