# HG changeset patch # User atmos4 # Date 1017157998 0 # Node ID 739cad21c32c89635b245f81c30da8c2d4deef59 # Parent d9bea3d1372515d51db1801d233eded161523533 Port dec_audio.c faad aac decoder to libmpcodecs, cleaned up code, improved buffering scheme. diff -r d9bea3d13725 -r 739cad21c32c libmpcodecs/Makefile --- a/libmpcodecs/Makefile Tue Mar 26 12:43:01 2002 +0000 +++ b/libmpcodecs/Makefile Tue Mar 26 15:53:18 2002 +0000 @@ -3,7 +3,7 @@ LIBNAME = libmpcodecs.a -AUDIO_SRCS=dec_audio.c ad.c ad_a52.c ad_acm.c ad_alaw.c ad_dk3adpcm.c ad_dk4adpcm.c ad_dshow.c ad_dvdpcm.c ad_ffmpeg.c ad_hwac3.c ad_imaadpcm.c ad_mp3.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c +AUDIO_SRCS=dec_audio.c ad.c ad_a52.c ad_acm.c ad_alaw.c ad_dk3adpcm.c ad_dk4adpcm.c ad_dshow.c ad_dvdpcm.c ad_ffmpeg.c ad_hwac3.c ad_imaadpcm.c ad_mp3.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c ad_faad.c VIDEO_SRCS=dec_video.c vd.c vd_null.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.c vd_odivx.c vd_divx4.c vd_raw.c vd_xanim.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_nuv.c vd_libmpeg2.c vd_msrle.c vd_huffyuv.c vd_zlib.c ifeq ($(PNG),yes) diff -r d9bea3d13725 -r 739cad21c32c libmpcodecs/ad.c --- a/libmpcodecs/ad.c Tue Mar 26 12:43:01 2002 +0000 +++ b/libmpcodecs/ad.c Tue Mar 26 15:53:18 2002 +0000 @@ -31,6 +31,7 @@ extern ad_functions_t mpcodecs_ad_dshow; extern ad_functions_t mpcodecs_ad_acm; extern ad_functions_t mpcodecs_ad_msgsm; +extern ad_functions_t mpcodecs_ad_faad; ad_functions_t* mpcodecs_ad_drivers[] = { @@ -56,5 +57,8 @@ #endif &mpcodecs_ad_acm, #endif +#ifdef HAVE_FAAD + &mpcodecs_ad_faad, +#endif NULL }; diff -r d9bea3d13725 -r 739cad21c32c libmpcodecs/ad_faad.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpcodecs/ad_faad.c Tue Mar 26 15:53:18 2002 +0000 @@ -0,0 +1,204 @@ +/* ad_faad.c - MPlayer AAC decoder using libfaad2 + * This file is part of MPlayer, see http://mplayerhq.hu/ for info. + * (c)2002 by Felix Buenemann + * File licensed under the GPL, see http://www.fsf.org/ for more info. + */ + +#include +#include +#include + +#include "config.h" +#include "ad_internal.h" + +#ifdef HAVE_FAAD + +static ad_info_t info = +{ + "AAC (MPEG2/4 Advanced Audio Coding)", + "libfaad2", + AFM_AAC, + "Felix Buenemann", + "faad2", + "Under development!" +}; + +LIBAD_EXTERN(faad) + +#include + +/* configure maximum supported channels, * + * this is theoretically max. 64 chans */ +#define FAAD_MAX_CHANNELS 6 +#define FAAD_BUFFLEN (FAAD_MIN_STREAMSIZE*FAAD_MAX_CHANNELS) + +//#define AAC_DUMP_COMPRESSED + +static faacDecHandle faac_hdec; +static faacDecFrameInfo faac_finfo; + +static int preinit(sh_audio_t *sh) +{ + sh->audio_in_minsize=FAAD_BUFFLEN; + sh->audio_out_minsize=2048*FAAD_MAX_CHANNELS; + + // XXX: why is this duplicated in sh struct? ::atmos + sh->a_in_buffer_size=sh->audio_in_minsize; + sh->a_in_buffer=malloc(sh->a_in_buffer_size); + sh->a_in_buffer_len=0; + return 1; +} + +static int init(sh_audio_t *sh) +{ + unsigned long faac_samplerate, faac_channels; + int faac_init; + faac_hdec = faacDecOpen(); + + sh->a_in_buffer_len = demux_read_data(sh->ds, sh->a_in_buffer, sh->a_in_buffer_size); + + // If we don't get the ES descriptor, try manual config + if(!sh->codecdata_len) { +#if 1 + faacDecConfigurationPtr faac_conf; + /* Set the default object type and samplerate */ + /* This is useful for RAW AAC files */ + faac_conf = faacDecGetCurrentConfiguration(faac_hdec); + if(sh->samplerate) + faac_conf->defSampleRate = sh->samplerate; + /* XXX: FAAD support FLOAT output, how do we handle + * that (FAAD_FMT_FLOAT)? ::atmos + */ + if(sh->samplesize) + switch(sh->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 + + /* init the codec */ + faac_init = faacDecInit(faac_hdec, sh->a_in_buffer, + &faac_samplerate, &faac_channels); + sh->a_in_buffer_len -= (faac_init > 0)?faac_init:0; // how many bytes init consumed + + } else { // We have ES DS in codecdata + /*int i; + for(i = 0; i < sh_audio->codecdata_len; i++) + printf("codecdata_dump %d: 0x%02X\n", i, sh_audio->codecdata[i]);*/ + + faac_init = faacDecInit2(faac_hdec, sh->codecdata, + sh->codecdata_len, &faac_samplerate, &faac_channels); + } + if(faac_init < 0) { + mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to initialize the decoder!\n"); // XXX: deal with cleanup! + faacDecClose(faac_hdec); + // XXX: free a_in_buffer here or in uninit? + return 0; + } else { + mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug! + mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %dHz channels: %d\n", faac_samplerate, faac_channels); + sh->channels = faac_channels; + sh->samplerate = faac_samplerate; + //sh->o_bps = sh->samplesize*faac_channels*faac_samplerate; + if(!sh->i_bps) { + mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: compressed input bitrate missing, assuming 128kbit/s!\n"); + sh->i_bps = 128*1000/8; // XXX: HACK!!! ::atmos + } else + mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: got %dkbit/s bitrate from MP4 header!\n",sh->i_bps*8/1000); + } + return 1; +} + +static void uninit(sh_audio_t *sh) +{ + mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Closing decoder!\n"); + faacDecClose(faac_hdec); + if(sh->a_in_buffer_size) { + free(sh->a_in_buffer); + sh->a_in_buffer = NULL; + } +} + +static int control(sh_audio_t *sh,int cmd,void* arg, ...) +{ + switch(cmd) + { +#if 0 + case ADCTRL_RESYNC_STREAM: + return CONTROL_TRUE; + case ADCTRL_SKIP_FRAME: + return CONTROL_TRUE; +#endif + } + return CONTROL_UNKNOWN; +} + +static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen) +{ + int j = 0, len = 0; + void *faac_sample_buffer; + //memset(sh->a_buffer,0,sh->a_buffer_size); // XXX: check if needed. + + while(len < minlen) { + /* update buffer */ + if(sh->a_in_buffer_len < sh->a_in_buffer_size){ + sh->a_in_buffer_len += + demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len], + sh->a_in_buffer_size - sh->a_in_buffer_len); + } + +#ifdef DUMP_AAC_COMPRESSED + {int i; + for (i = 0; i < 16; i++) + printf ("%02X ", sh->a_in_buffer[i]); + printf ("\n");} +#endif + do { + faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, sh->a_in_buffer+j); + /* update buffer index after faacDecDecode */ + if(faac_finfo.bytesconsumed >= sh->a_in_buffer_len){ + sh->a_in_buffer_len=0; + } else { + sh->a_in_buffer_len-=faac_finfo.bytesconsumed; + memcpy(sh->a_in_buffer,&sh->a_in_buffer[faac_finfo.bytesconsumed],sh->a_in_buffer_len); + } + + 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 { + /* XXX: samples already multiplied by channels! */ + mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Successfully decoded frame (%d Bytes)!\n", + sh->samplesize*faac_finfo.samples); + memcpy(buf+len,faac_sample_buffer, sh->samplesize*faac_finfo.samples); + len += sh->samplesize*faac_finfo.samples; + //printf("FAAD: buffer: %d bytes consumed: %d \n", k, faac_finfo.bytesconsumed); + } + } + return len; +} + +#endif /* !HAVE_FAAD */ +