diff --git a/Makefile b/Makefile index 1c22670f04..397f8a7d9d 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ endif V_LIBS = $(X_LIB) $(MP1E_LIB) $(GGI_LIB) $(MLIB_LIB) $(SDL_LIB) $(SVGA_LIB) $(AA_LIB) $(DIRECTFB_LIB) AO_LIBS = -Llibao2 -lao2 -A_LIBS = $(ALSA_LIB) $(NAS_LIB) $(MAD_LIB) $(VORBIS_LIB) $(SGIAUDIO_LIB) +A_LIBS = $(ALSA_LIB) $(NAS_LIB) $(MAD_LIB) $(VORBIS_LIB) $(FAAD_LIB) $(SGIAUDIO_LIB) CODEC_LIBS = -Llibmpcodecs -lmpcodecs -Lg72x -lg72x -Lmp3lib -lMP3 -Llibac3 -lac3 -Lliba52 -la52 -Lxa -lxa -Llibmpeg2 -lmpeg2 $(AV_LIB) -Llibfame -lfame COMMON_LIBS = $(CODEC_LIBS) -Llibmpdemux -lmpdemux $(NEW_INPUT_LIB) $(LIB_LOADER) $(A_LIBS) $(CSS_LIB) $(ARCH_LIB) -Lpostproc -lpostproc $(DECORE_LIB) -Llinux -losdep $(TERMCAP_LIB) $(STREAMING_LIB) $(Z_LIB) $(GTK_LIBS) $(PNG_LIB) $(JPEG_LIB) -lm diff --git a/codec-cfg.c b/codec-cfg.c index c339d69020..1e759cff3d 100644 --- a/codec-cfg.c +++ b/codec-cfg.c @@ -227,6 +227,7 @@ static short get_driver(char *s,int audioflag) "dk4adpcm", "dk3adpcm", "roqaudio", + "faad", NULL }; static char *videodrv[] = { diff --git a/codec-cfg.h b/codec-cfg.h index 3b6c22dff9..a10967e1b9 100644 --- a/codec-cfg.h +++ b/codec-cfg.h @@ -40,6 +40,7 @@ #define AFM_DK4ADPCM 17 #define AFM_DK3ADPCM 18 #define AFM_ROQAUDIO 19 +#define AFM_AAC 20 #define VFM_MPEG 1 #define VFM_VFW 2 diff --git a/configure b/configure index 00c0457cbe..230f336a30 100755 --- a/configure +++ b/configure @@ -131,6 +131,7 @@ Optional features: --disable-divx4linux disable DivX4linux codec [autodetect] --disable-opendivx disable OpenDivx codec [enable] --enable-vorbis build with OggVorbis support [autodetect] + --enable-faad build with FAAD (AAC) support [autodetect] --disable-iconv do not use iconv(3) function [autodetect] --disable-rtc disable RTC (/dev/rtc) on Linux [autodetect] --disable-mp1e disable libmp1e support @@ -756,6 +757,7 @@ _rtc=auto _ossaudio=auto _mad=auto _vorbis=auto +_faad=auto _css=auto _dvdread=auto _xanim=auto @@ -859,6 +861,8 @@ for ac_option do --disable-mad) _mad=no ;; --enable-vorbis) _vorbis=yes ;; --disable-vorbis) _vorbis=no ;; + --enable-faad) _faad=yes ;; + --disable-faad) _faad=no ;; --enable-css) _css=yes ;; --disable-css) _css=no ;; --enable-dvdread) _dvdread=yes ;; @@ -2477,6 +2481,24 @@ fi echores "$_vorbis" +echocheck "FAAD (AAC) support" +if test "$_faad" = auto ; then + _faad=no + cat > $TMPC << EOF +#include +int main(void) { return 0; } +EOF + cc_check -lfaad -lm && _faad=yes +fi +if test "$_faad" = yes ; then + _def_faad='#define HAVE_FAAD 1' + _ld_faad='-lfaad' +else + _def_faad='#undef HAVE_FAAD' +fi +echores "$_faad" + + echocheck "Win32 DLL support" qnx && _win32=no if test "$_win32" = auto ; then @@ -3226,6 +3248,7 @@ ALSA_LIB = $_ld_alsa NAS_LIB = $_ld_nas MAD_LIB = $_ld_mad VORBIS_LIB = $_ld_vorbis +FAAD_LIB = $_ld_faad SGIAUDIO_LIB = $_ld_sgiaudio # input @@ -3517,6 +3540,9 @@ $_def_mad /* enable OggVorbis support */ $_def_vorbis +/* enable FAAD (AAC) support */ +$_def_faad + /* enable streaming */ $_def_streaming diff --git a/dec_audio.c b/dec_audio.c index c13134fa13..c92579c364 100644 --- a/dec_audio.c +++ b/dec_audio.c @@ -83,6 +83,18 @@ typedef struct ov_struct_st { } ov_struct_t; #endif +#ifdef HAVE_FAAD +#include +static faacDecHandle faac_hdec; +static faacDecFrameInfo faac_finfo; +static int faac_bytesconsumed = 0; +static unsigned char *faac_buffer; +/* configure maximum supported channels, * + * this is theoretically max. 64 chans */ +#define FAAD_MAX_CHANNELS 6 +#define FAAD_BUFFLEN (FAAD_MIN_STREAMSIZE*FAAD_MAX_CHANNELS) +#endif + #ifdef USE_LIBAVCODEC #ifdef USE_LIBAVCODEC_SO #include @@ -388,6 +400,17 @@ case AFM_VORBIS: sh_audio->audio_out_minsize=1024*4; // 1024 samples/frame #endif break; +case AFM_AAC: + // AAC (MPEG2 Audio, MPEG4 Audio) +#ifndef HAVE_FAAD + mp_msg(MSGT_DECAUDIO,MSGL_ERR,"Error: Cannot decode AAC data, because MPlayer was compiled without FAAD support\n"/*MSGTR_NoFAAD*/); + driver=0; +#else + mp_msg(MSGT_DECAUDIO,MSGL_V,"Using FAAD to decode AAC content!\n"/*MSGTR_UseFAAD*/); + // Samples per frame * channels per frame, this might not work with >2 chan AAC, need test samples! ::atmos + sh_audio->audio_out_minsize=2048*2; +#endif + break; case AFM_PCM: case AFM_DVDPCM: case AFM_ALAW: @@ -810,6 +833,66 @@ case AFM_VORBIS: { mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Init OK!\n"); } break; #endif + +#ifdef HAVE_FAAD +case AFM_AAC: { + unsigned long faac_samplerate, faac_channels; + faacDecConfigurationPtr faac_conf; + faac_hdec = faacDecOpen(); + +#if 0 + /* Set the default object type and samplerate */ + /* This is useful for RAW AAC files */ + faac_conf = faacDecGetCurrentConfiguration(faac_hdec); + if(sh_audio->samplerate) + faac_conf->defSampleRate = sh_audio->samplerate; + /* XXX: is outputFormat samplesize of compressed data or samplesize of + * decoded data, maybe upsampled? Also, FAAD support FLOAT output, + * how do we handle that (FAAD_FMT_FLOAT)? ::atmos + */ + if(sh_audio->samplesize) + switch(sh_audio->samplesize){ + case 1: // 8Bit + mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: 8Bit samplesize not supported by FAAD, assuming 16Bit!\n"); + default: + case 2: // 16Bit + faac_conf->outputFormat = FAAD_FMT_16BIT; + break; + case 3: // 24Bit + faac_conf->outputFormat = FAAD_FMT_24BIT; + break; + case 4: // 32Bit + faac_conf->outputFormat = FAAD_FMT_32BIT; + break; + } + faac_conf->defObjectType = LTP; // => MAIN, LC, SSR, LTP available. + + faacDecSetConfiguration(faac_hdec, faac_conf); +#endif + + if(faac_buffer == NULL) + faac_buffer = (unsigned char*)malloc(FAAD_BUFFLEN); + memset(faac_buffer, 0, FAAD_BUFFLEN); + demux_read_data(sh_audio->ds, faac_buffer, FAAD_BUFFLEN); + + /* init the codec */ + if((faac_bytesconsumed = faacDecInit(faac_hdec, faac_buffer, &faac_samplerate, &faac_channels)) < 0) { + mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to initialize the decoder!\n"); // XXX: deal with cleanup! + faacDecClose(faac_hdec); + free(faac_buffer); + faac_buffer = NULL; + driver = 0; + } else { + mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", faac_bytesconsumed); // XXX: remove or move to debug! + mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %dHz channels: %d\n", faac_samplerate, faac_channels); + sh_audio->channels = faac_channels; + sh_audio->samplerate = faac_samplerate; + sh_audio->i_bps = 128*1000/8; // XXX: HACK!!! There's currently no way to get bitrate from libfaad2! ::atmos + } + +} break; +#endif + #ifdef USE_LIBMAD case AFM_MAD: { @@ -974,6 +1057,50 @@ int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){ } } break; #endif + +#ifdef HAVE_FAAD + case AFM_AAC: { + int /*i,*/ k, j = 0; + void *faac_sample_buffer; + + len = 0; + while(len < minlen) { + /* update buffer */ + if (faac_bytesconsumed > 0) { + for (k = 0; k < (FAAD_BUFFLEN - faac_bytesconsumed); k++) + faac_buffer[k] = faac_buffer[k + faac_bytesconsumed]; + demux_read_data(sh_audio->ds, faac_buffer + (FAAD_BUFFLEN) - faac_bytesconsumed, faac_bytesconsumed); + faac_bytesconsumed = 0; + } + /*for (i = 0; i < 16; i++) + printf ("%02X ", faac_buffer[i]); + printf ("\n");*/ + do { + faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, faac_buffer+j); + /* update buffer index after faacDecDecode */ + faac_bytesconsumed += faac_finfo.bytesconsumed; + if(faac_finfo.error > 0) { + mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Trying to resync!\n"); + j++; + } else + break; + } while(j < FAAD_BUFFLEN); + + + if(faac_finfo.error > 0) { + mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to decode frame: %s \n", + faacDecGetErrorMessage(faac_finfo.error)); + } else if (faac_finfo.samples == 0) + mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Decoded zero samples!\n"); + else { + mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Successfully decoded frame (%dBytes)!\n", faac_finfo.samples*faac_finfo.channels); + memcpy(buf+len,faac_sample_buffer, faac_finfo.samples*faac_finfo.channels); + len += faac_finfo.samples*faac_finfo.channels; + } + } + + } break; +#endif case AFM_PCM: // AVI PCM len=demux_read_data(sh_audio->ds,buf,minlen); break; @@ -1224,6 +1351,14 @@ void resync_audio_stream(sh_audio_t *sh_audio){ sh_audio->ac3_frame=ac3_decode_frame(); // resync // if(verbose) printf(" OK!\n"); break; +#endif +#ifdef HAVE_FAAD + case AFM_AAC: + //if(faac_buffer != NULL) + faac_bytesconsumed = 0; + memset(faac_buffer, 0, FAAD_BUFFLEN); + //demux_read_data(sh_audio->ds, faac_buffer, FAAD_BUFFLEN); + break; #endif case AFM_A52: case AFM_ACM: diff --git a/etc/codecs.conf b/etc/codecs.conf index 19c533298a..8c62c8705b 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -260,6 +260,7 @@ videocodec ffodivx fourcc MP4S,mp4s ; ISO MPEG-4 Video V1 fourcc xvid,XVID,XviD fourcc DX50 + fourcc mp4v format 0x4 driver ffmpeg dll mpeg4 ;opendivx @@ -426,6 +427,13 @@ audiocodec roqaudio fourcc RoQA driver roqaudio +audiocodec faad + info "AAC MPEG2/MPEG4 Audio" + status buggy + comment "Under developemnt by Atmos" + fourcc mp4a,MP4A + driver faad + ; =============== WINDOWS DLL's ============== videocodec vp3