summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authoratmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-03-26 15:53:18 +0000
committeratmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-03-26 15:53:18 +0000
commit96b58cfa58648a4aa6ae0881332652cb99f7cee8 (patch)
tree47a273a5f6533ae6afba9a31788a3e3c7470f614 /libmpcodecs
parent9ef25a9736dacc702a4db9e7ea7035bf526c1515 (diff)
downloadmpv-96b58cfa58648a4aa6ae0881332652cb99f7cee8.tar.bz2
mpv-96b58cfa58648a4aa6ae0881332652cb99f7cee8.tar.xz
Port dec_audio.c faad aac decoder to libmpcodecs, cleaned up code, improved buffering scheme.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@5357 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/Makefile2
-rw-r--r--libmpcodecs/ad.c4
-rw-r--r--libmpcodecs/ad_faad.c204
3 files changed, 209 insertions, 1 deletions
diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile
index ae8e5a1917..5ac92114f9 100644
--- a/libmpcodecs/Makefile
+++ b/libmpcodecs/Makefile
@@ -3,7 +3,7 @@ include ../config.mak
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 --git a/libmpcodecs/ad.c b/libmpcodecs/ad.c
index 47880ef942..2171405550 100644
--- a/libmpcodecs/ad.c
+++ b/libmpcodecs/ad.c
@@ -31,6 +31,7 @@ extern ad_functions_t mpcodecs_ad_roqaudio;
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 @@ ad_functions_t* mpcodecs_ad_drivers[] =
#endif
&mpcodecs_ad_acm,
#endif
+#ifdef HAVE_FAAD
+ &mpcodecs_ad_faad,
+#endif
NULL
};
diff --git a/libmpcodecs/ad_faad.c b/libmpcodecs/ad_faad.c
new file mode 100644
index 0000000000..227543f3c4
--- /dev/null
+++ b/libmpcodecs/ad_faad.c
@@ -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 <atmosfear at users.sourceforge.net>
+ * File licensed under the GPL, see http://www.fsf.org/ for more info.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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 <faad.h>
+
+/* 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 */
+