changeset 15259:854990f357ee

added faac audio encoder
author nicodvb
date Mon, 25 Apr 2005 07:07:57 +0000
parents c2979462805a
children f6bc5991c5b8
files Makefile cfg-mencoder.h configure libmpcodecs/Makefile libmpcodecs/ae.c libmpcodecs/ae_faac.c libmpcodecs/ae_faac.h mencoder.c
diffstat 8 files changed, 267 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Mon Apr 25 06:46:30 2005 +0000
+++ b/Makefile	Mon Apr 25 07:07:57 2005 +0000
@@ -41,6 +41,10 @@
 CODEC_LIBS += $(TOOLAME_LIB)
 endif
 
+ifeq ($(FAAC),yes)
+CODEC_LIBS += $(FAAC_LIB)
+endif
+
 PARTS = libmpdemux libmpcodecs libavcodec libavformat libao2 drivers osdep postproc input libvo libaf
 ifeq ($(MP3LIB),yes)
 PARTS += mp3lib
--- a/cfg-mencoder.h	Mon Apr 25 06:46:30 2005 +0000
+++ b/cfg-mencoder.h	Mon Apr 25 07:07:57 2005 +0000
@@ -33,6 +33,10 @@
 extern m_option_t toolameopts_conf[];
 #endif
 
+#ifdef HAVE_FAAC
+extern m_option_t faacopts_conf[];
+#endif
+
 #ifdef USE_WIN32DLL
 extern m_option_t vfwopts_conf[];
 #endif
@@ -115,6 +119,11 @@
 #else
 	{"toolame", "MPlayer was compiled without libtoolame. See README or DOCS.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
 #endif
+#ifdef HAVE_FAAC
+	{"faac", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_FAAC, NULL},
+#else
+	{"faac", "MPlayer was compiled without libfaac. See README or DOCS.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
+#endif
 	{"help", "\nAvailable codecs:\n"
 	"   copy     - frame copy, without re-encoding (useful for AC3)\n"
 	"   pcm      - uncompressed PCM audio\n"
@@ -127,6 +136,9 @@
 #ifdef HAVE_TOOLAME
 	"   toolame  - Toolame MP2 audio encoder\n"
 #endif
+#ifdef HAVE_FAAC
+	"   faac  - FAAC AAC audio encoder\n"
+#endif
 	"\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
 	{NULL, NULL, 0, 0, 0, 0, NULL}
 };
@@ -244,6 +256,11 @@
 #else
 	{"toolameopts", "MPlayer was compiled without libtoolame. See README or DOCS.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
 #endif
+#ifdef HAVE_FAAC
+	{"faacopts", faacopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
+#else
+	{"faacopts", "MPlayer was compiled without libfaac. See README or DOCS.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
+#endif
 #ifdef USE_WIN32DLL
 	{"vfwopts", vfwopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
 #endif
--- a/configure	Mon Apr 25 06:46:30 2005 +0000
+++ b/configure	Mon Apr 25 07:07:57 2005 +0000
@@ -217,6 +217,7 @@
   --disable-internal-matroska disable internal Matroska support [enabled]
   --enable-external-faad build with external FAAD2 (AAC) support [autodetect]
   --disable-internal-faad disable internal FAAD2 (AAC) support [autodetect]
+  --disable-faac         disable support for FAAC (AAC encoder) [autodetect]
   --disable-ladspa       disable LADSPA plugin support [autodetect]
   --disable-libdv        disable libdv 0.9.5 en/decoding support [autodetect]
   --disable-mad          disable libmad (MPEG audio) support [autodetect]
@@ -1333,6 +1334,7 @@
 _tremor=no
 _faad_internal=auto
 _faad_external=auto
+_faac=auto
 _ladspa=auto
 _xmms=no
 # dvdnav disabled, it does not work
@@ -1531,6 +1533,7 @@
   --disable-internal-faad)	_faad_internal=no	;;
   --enable-external-faad)	_faad_external=yes	_faad_internal=no	;;
   --disable-external-faad)	_faad_external=no	;;
+  --disable-faac)	_faac=no	;;
   --enable-ladspa)	_ladspa=yes	;;
   --disable-ladspa)	_ladspa=no		;;
   --enable-xmms)	_xmms=yes	;;
@@ -5317,6 +5320,34 @@
 fi
 echores "$_matroska_internal"
 
+echocheck "FAAC (AAC encoder) support"
+if test "$_faac" = auto ; then
+  cat > $TMPC <<EOF
+#include <inttypes.h> 
+#include <faac.h>
+int main(void) { unsigned long x, y; faacEncOpen(48000, 2, &x, &y); return 0; }
+EOF
+  if ( cc_check -c -O4 -lfaac $_ld_lm ); then
+    _faac=yes
+    _ld_faac="-lfaac"
+  else
+    if ( cc_check -c -O4 -lfaac -lmp4v2 -lstdc++ $_ld_lm ); then
+      _faac=yes
+      _ld_faac="-lfaac -lmp4v2 -lstdc++"
+    else
+      _faac=no
+      _ld_faac=""
+    fi
+  fi
+fi
+if test "$_faac" = yes ; then
+  _def_faac="#define HAVE_FAAC 1"
+  _codecmodules="$_codecmodules faac"
+else
+  _def_faac="#undef HAVE_FAAC"
+  _nocodecmodules="$_nocodecmodules faac"
+fi
+echores "$_faac"
 
 echocheck "internal FAAD2 (AAC) support"
 _inc_faad="-I`pwd`/libfaad2"
@@ -6846,6 +6877,8 @@
 TOOLAME=$_toolame
 TOOLAME_EXTRAFLAGS=$_toolame_extraflags
 TOOLAME_LIB=$_toolame_lib
+FAAC=$_faac
+FAAC_LIB=$_ld_faac
 AMR_NB=$_amr_nb
 AMR_NB_FIXED=$_amr_nb_fixed
 AMR_WB=$_amr_wb
@@ -7382,6 +7415,9 @@
 $_def_faad
 $_def_faad_internal
 
+/* enable FAAC (AAC encoder) support */
+$_def_faac
+
 /* enable LADSPA plugin support */
 $_def_ladspa
 
--- a/libmpcodecs/Makefile	Mon Apr 25 06:46:30 2005 +0000
+++ b/libmpcodecs/Makefile	Mon Apr 25 07:07:57 2005 +0000
@@ -52,6 +52,10 @@
 ENCODER_SRCS += ae_lavc.c
 endif
 
+ifeq ($(FAAC),yes)
+ENCODER_SRCS += ae_faac.c
+endif
+
 SRCS=$(AUDIO_SRCS) $(VIDEO_SRCS) $(VFILTER_SRCS) $(NATIVE_SRCS) img_format.c
 OBJS=$(SRCS:.c=.o)
 
--- a/libmpcodecs/ae.c	Mon Apr 25 06:46:30 2005 +0000
+++ b/libmpcodecs/ae.c	Mon Apr 25 07:07:57 2005 +0000
@@ -23,6 +23,10 @@
 #include "ae_lavc.h"
 #endif
 
+#ifdef HAVE_FAAC
+#include "ae_faac.h"
+#endif
+
 audio_encoder_t *new_audio_encoder(muxer_stream_t *stream, audio_encoding_params_t *params)
 {
 	int ris;
@@ -54,6 +58,11 @@
 			ris = mpae_init_lame(encoder);
 			break;
 #endif
+#ifdef HAVE_FAAC
+		case ACODEC_FAAC:
+			ris = mpae_init_faac(encoder);
+			break;
+#endif
 	}
 	
 	if(! ris)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae_faac.c	Mon Apr 25 07:07:57 2005 +0000
@@ -0,0 +1,188 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include "m_option.h"
+#include "../mp_msg.h"
+#include "aviheader.h"
+#include "../libaf/af_format.h"
+#include "ms_hdr.h"
+#include "muxer.h"
+#include <faac.h>
+#include "ae.h"
+
+
+static faacEncHandle faac;
+static faacEncConfigurationPtr config = NULL;
+static int 
+	param_bitrate = 128,
+	param_quality = 0,
+	param_object_type = MAIN,
+	param_mpeg = 2,
+	param_tns = 0,
+	param_raw = 0,
+	param_cutoff = 0,
+	param_format = 16,
+	param_debug = 0;
+
+static int enc_frame_size = 0, divisor;
+static unsigned long samples_input, max_bytes_output;
+static unsigned char *decoder_specific_buffer = NULL;
+static unsigned long decoder_specific_len = 0;
+
+m_option_t faacopts_conf[] = {
+	{"br", &param_bitrate, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"quality", &param_quality, CONF_TYPE_INT, CONF_RANGE, 0, 1000, NULL},
+	{"object", &param_object_type, CONF_TYPE_INT, CONF_RANGE, MAIN, LTP, NULL},
+	{"mpeg", &param_mpeg, CONF_TYPE_INT, CONF_RANGE, 2, 4, NULL},
+	{"tns", &param_tns, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"cutoff", &param_cutoff, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"format", &param_format, CONF_TYPE_INT, 0, 0, 0, NULL},
+	{"raw", &param_raw, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"debug", &param_debug, CONF_TYPE_INT, CONF_RANGE, 0, 100000000, NULL},
+	{NULL, NULL, 0, 0, 0, 0, NULL}
+};
+
+
+static int bind_faac(audio_encoder_t *encoder, muxer_stream_t *mux_a)
+{
+	mux_a->wf = calloc(1, sizeof(WAVEFORMATEX) + decoder_specific_len + 256);
+	mux_a->wf->wFormatTag = 0x706D;
+	mux_a->wf->nChannels = encoder->params.channels;
+	mux_a->h.dwSampleSize=0; // VBR
+	mux_a->h.dwRate=encoder->params.sample_rate;
+	mux_a->h.dwScale=encoder->params.samples_per_frame;
+	mux_a->wf->nSamplesPerSec=mux_a->h.dwRate;
+	mux_a->wf->nAvgBytesPerSec = 125 * encoder->params.bitrate;
+	
+	mux_a->wf->nBlockAlign = mux_a->h.dwScale;
+	mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000;
+	mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign;
+	
+	mux_a->wf->cbSize = decoder_specific_len;
+	mux_a->wf->wBitsPerSample = 0; /* does not apply */
+	((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1;
+	((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2;
+	((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign;
+	((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1;
+	((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0;
+	
+	// Fix allocation    
+	mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize);
+	
+	if(config->inputFormat == FAAC_INPUT_FLOAT)
+		encoder->input_format = AF_FORMAT_FLOAT_NE;
+	else if(config->inputFormat == FAAC_INPUT_32BIT)
+		encoder->input_format = AF_FORMAT_S32_NE;
+	else
+		encoder->input_format = AF_FORMAT_S16_NE;
+		
+	encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize;
+	encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2;
+
+	if(decoder_specific_buffer && decoder_specific_len)
+		memcpy(mux_a->wf + 1, decoder_specific_buffer, decoder_specific_len);
+	
+	return 1;
+}
+
+static int get_frame_size(audio_encoder_t *encoder)
+{
+	int sz = enc_frame_size;
+	enc_frame_size = 0;
+	return sz;
+}
+
+static int encode_faac(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size)
+{
+	// len is divided by the number of bytes per sample
+	enc_frame_size = faacEncEncode(faac,  (int32_t*) src,  len / divisor, dest, max_size);
+	
+	return enc_frame_size;
+}
+
+int close_faac(audio_encoder_t *encoder)
+{
+	return 1;
+}
+
+int mpae_init_faac(audio_encoder_t *encoder)
+{	
+	if(encoder->params.channels < 1 || encoder->params.channels > 6 || (param_mpeg != 2 && param_mpeg != 4))
+	{
+		mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, unsupported number of channels: %d, or mpeg version: %d, exit\n", encoder->params.channels, param_mpeg);
+		return 0;
+	}
+	
+	faac = faacEncOpen(encoder->params.sample_rate, encoder->params.channels, &samples_input, &max_bytes_output);
+	if(!faac)
+	{
+		mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't init, exit\n");
+		return 0;
+	}
+	mp_msg(MSGT_MENCODER, MSGL_V, "AE_FAAC, sample_input: %u, max_bytes_output: %u\n", samples_input, max_bytes_output);
+	config = faacEncGetCurrentConfiguration(faac);
+	if(!config)
+	{
+		mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't get init configuration, exit\n");
+		return 0;
+	}
+
+	param_bitrate *= 1000;
+	if(param_quality)
+		config->quantqual = param_quality;
+	else
+		config->bitRate = param_bitrate / encoder->params.channels;
+	
+	if(param_format==33)
+	{
+		config->inputFormat = FAAC_INPUT_FLOAT;
+		divisor = 4;
+	}
+	else if(param_format==32)
+	{
+		config->inputFormat = FAAC_INPUT_32BIT;
+		divisor = 4;
+	}
+	else
+	{
+		config->inputFormat = FAAC_INPUT_16BIT;
+		divisor = 2;
+	}
+	config->outputFormat = param_raw ? 0 : 1; // 1 is ADTS
+	config->aacObjectType = param_object_type;
+	config->mpegVersion = (param_mpeg == 4 ? MPEG4 : MPEG2);
+	config->useTns = param_tns;
+	config->allowMidside = 1;
+	config->shortctl = SHORTCTL_NORMAL;
+	param_cutoff = param_cutoff ? param_cutoff : encoder->params.sample_rate / 2;
+	if(param_cutoff > encoder->params.sample_rate / 2)
+		param_cutoff = encoder->params.sample_rate / 2;
+	config->bandWidth = param_cutoff;
+	if(encoder->params.channels == 6)
+		config->useLfe = 1;
+	
+	if(!faacEncSetConfiguration(faac, config)) 
+	{
+		mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, counldn't set specified parameters, exiting\n");
+		return 0;
+	}
+	
+	if(param_raw)
+		faacEncGetDecoderSpecificInfo(faac, &decoder_specific_buffer, &decoder_specific_len); 
+	else
+		decoder_specific_len = 0;
+		
+	encoder->params.bitrate = param_bitrate;
+	encoder->params.samples_per_frame = 1024;
+	encoder->decode_buffer_size =  divisor * samples_input;	//samples * 16 bits_per_sample
+	
+	encoder->bind = bind_faac;
+	encoder->get_frame_size = get_frame_size;
+	encoder->encode = encode_faac;
+	encoder->close = close_faac;
+	
+	return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/ae_faac.h	Mon Apr 25 07:07:57 2005 +0000
@@ -0,0 +1,8 @@
+#ifndef MPAE_FAAC_H
+#define MPAE_FAAC_H
+
+#include "ae.h"
+
+int mpae_init_faac(audio_encoder_t *encoder);
+
+#endif
--- a/mencoder.c	Mon Apr 25 06:46:30 2005 +0000
+++ b/mencoder.c	Mon Apr 25 07:07:57 2005 +0000
@@ -17,6 +17,7 @@
 #define ACODEC_NULL 3
 #define ACODEC_LAVC 4
 #define ACODEC_TOOLAME 5
+#define ACODEC_FAAC 6
 
 #include <stdio.h>
 #include <stdlib.h>