[xiph-commits] r7421 - in icecast/trunk/ices0: . doc src
brendan at motherfish-iii.xiph.org
brendan
Thu Aug 5 19:04:11 PDT 2004
Author: brendan
Date: Thu Aug 5 19:04:11 2004
New Revision: 7421
Added:
icecast/trunk/ices0/src/in_mp4.c
icecast/trunk/ices0/src/in_mp4.h
Modified:
icecast/trunk/ices0/NEWS
icecast/trunk/ices0/README
icecast/trunk/ices0/TODO
icecast/trunk/ices0/configure.ac
icecast/trunk/ices0/doc/ices.1.in
icecast/trunk/ices0/src/Makefile.am
icecast/trunk/ices0/src/icestypes.h
icecast/trunk/ices0/src/stream.c
Log:
MP4 (AAC) transcoding support. Doesn't read metadata. Only reads stereo files.
Can't read from pipes.
Modified: icecast/trunk/ices0/NEWS
===================================================================
--- icecast/trunk/ices0/NEWS 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/NEWS 2004-07-30 18:59:21 UTC (rev 7421)
@@ -1,3 +1,4 @@
+ * MP4 audio support added via libfaad.
* Crossfader added.
* Tested with LAME 3.96.1
0.3 2003-07-13
Modified: icecast/trunk/ices0/README
===================================================================
--- icecast/trunk/ices0/README 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/README 2004-07-30 18:59:21 UTC (rev 7421)
@@ -9,6 +9,8 @@
2. Signal Handling
3. Playlist Handling
4. Reencoding
+ 5. Vorbis and MP4 transcoding
+ 6. Crossfading
D. Configuring
1. Command line options
2. Configuration file (ices.conf)
@@ -92,6 +94,13 @@
init, shutdown, get_next, and get_current_lineno. I suggest
you take a look in the distributed module files and just
expand on that.
+ 5. Vorbis and MP4 transcoding
+ If compiled with the appropriate libraries, ices can transcode
+ Ogg Vorbis and MP4 (AAC) audio files to MP3 on the fly. Keep your
+ sources in whatever format you like best.
+ 6. Crossfading
+ If compiled with reencoding support, ices can also crossfade
+ between tracks, giving you that pro radio station sound.
D. Configuring
ices can do everything shout could do, and more. It can be
configured through hard coded defaults, a configfile, and command
@@ -103,6 +112,7 @@
Options:
o -B (Background (daemon mode))
o -b <stream bitrate>
+ o -C <crossfade seconds>
o -c <configfile>
o -D <base directory>
o -d <stream description>
@@ -129,37 +139,38 @@
<?xml version="1.0"?>
<ices:Configuration xmlns:ices="http://www.icecast.org/
projects/ices">
- <ices:Playlist>
- <ices:File>apan.txt</ices:File>
- <ices:Randomize>1</ices:Randomize>
- <ices:Type>builtin</ices:Type>
- <ices:Module>ices</ices:Module>
- </ices:Playlist>
- <ices:Server>
- <ices:Hostname>localhost</ices:Hostname>
- <ices:Port>8000</ices:Port>
- <ices:Password>letmein</ices:Password>
- <ices:Protocol>xaudiocast</ices:Protocol>
- </ices:Server>
- <ices:Execution>
- <ices:Background>0</ices:Background>
- <ices:Verbose>1</ices:Verbose>
- <ices:BaseDirectory>/tmp</ices:BaseDirectory>
- <ices:Reencode>0</ices:Reencode>
- <ices:Samplerate>-1</ices:Samplerate>
- <ices:Channels>-1</ices:Channels>
- </ices:Execution>
- <ices:Stream>
- <ices:Name>Cool ices default name from XML</ice
+ <Playlist>
+ <File>apan.txt</File>
+ <Randomize>1</Randomize>
+ <Type>builtin</Type>
+ <Module>ices</Module>
+ <Crossfade>0</Crossfade>
+ </Playlist>
+ <Server>
+ <Hostname>localhost</Hostname>
+ <Port>8000</Port>
+ <Password>letmein</Password>
+ <Protocol>http</Protocol>
+ </Server>
+ <Execution>
+ <Background>0</Background>
+ <Verbose>1</Verbose>
+ <BaseDirectory>/tmp</BaseDirectory>
+ <Reencode>0</Reencode>
+ <Samplerate>-1</Samplerate>
+ <Channels>-1</Channels>
+ </Execution>
+ <Stream>
+ <Name>Cool ices default name from XML</ice
s:Name>
- <ices:Genre>Cool ices genre from XML</ices:Genr
+ <Genre>Cool ices genre from XML</Genr
e>
- <ices:Description>Cool ices description from XM
-L</ices:Description>
- <ices:URL>Cool ices URL from XML</ices:URL>
- <ices:Bitrate>128</ices:Bitrate>
- <ices:Public>1</ices:Public>
- </ices:Stream>
+ <Description>Cool ices description from XM
+L</Description>
+ <URL>Cool ices URL from XML</URL>
+ <Bitrate>128</Bitrate>
+ <Public>1</Public>
+ </Stream>
</ices:Configuration>
3. Configurations options
This describes all the different options in ices.
@@ -300,6 +311,11 @@
ices.pm, although do NOT specify the file extension for
the module. Use 'whatever' instead of 'whatever.pm' or
'whatever.py'
+ o Playlist Crossfade
+ Command line option: -C <crossfade secs>
+ Config file tag: Playlist/Crossfade
+ If this is greater than zero, and you have reencoding support,
+ ices will crossfade the specified number of seconds between tracks.
E. Licensing
ices is licensed under the Gnu General Public License, and for
more info about that I suggest you read the file named COPYING.
@@ -308,4 +324,4 @@
nice streaming mp3 client, go to developer.icecast.org.
_______
- This document is written by Alexander Haväng [eel at icecast.org].
+ This document was originally written by Alexander Haväng [eel at icecast.org].
Modified: icecast/trunk/ices0/TODO
===================================================================
--- icecast/trunk/ices0/TODO 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/TODO 2004-07-30 18:59:21 UTC (rev 7421)
@@ -1,4 +1,5 @@
+* MP4: metadata, piped input, mono
* Improved error handling
* Make the scripting engines, and vorbis and MP3 reencoding, run-time linkable
-$Id: TODO,v 1.5 2003/03/19 18:58:24 brendan Exp $
+$Id$
Property changes on: icecast/trunk/ices0/TODO
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: icecast/trunk/ices0/configure.ac
===================================================================
--- icecast/trunk/ices0/configure.ac 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/configure.ac 2004-07-30 18:59:21 UTC (rev 7421)
@@ -251,7 +251,7 @@
fi
AC_ARG_WITH(vorbis,
- [[ --with-vorbis[=DIR] support for vorbis using libvorbisfile [in DIR]]])
+ [[ --with-vorbis[=DIR] support for vorbis transcoding using libvorbisfile [in DIR]]])
if test "$have_LAME" != "yes"
then
@@ -296,6 +296,52 @@
fi
fi
+AC_ARG_WITH(faad,
+ [[ --with-faad[=DIR] support for MP4 (AAC) transcoding using libfaad [in DIR]]])
+
+if test "$have_LAME" != "yes"
+then
+ if test -n "$with_faad" -a "$with_faad" != "no"
+ then
+ AC_MSG_ERROR([MP4 transcoding cannot be enabled without LAME])
+ elif test "$with_faad" != "no"
+ then
+ AC_MSG_RESULT([MP4 transcoding is disabled because LAME is not enabled])
+ with_faad="no"
+ fi
+fi
+
+have_faad="no"
+if test "$with_faad" != "no"
+then
+ if test -n "$with_faad" -a "$with_faad" != "yes"
+ then
+ CPPFLAGS="$CPPFLAGS -I$with_faad/include"
+ LDFLAGS="$LDFLAGS -L$with_faad/lib"
+ fi
+
+ AC_CHECK_HEADER(faad.h, have_faad="maybe")
+ if test "$have_faad" != "no"
+ then
+ AC_CHECK_LIB(mp4v2, MP4Read, [
+ LIBS="$LIBS -lmp4v2 -lfaad"
+ AC_DEFINE(HAVE_LIBFAAD, 1, [Define if you have libfaad])
+ ICES_OBJECTS="$ICES_OBJECTS in_mp4.o"
+ have_faad="yes"
+ ],[have_faad="no"])
+ fi
+fi
+
+if test "$with_faad" != "no" -a "$have_faad" != "yes"
+then
+ if test -n "$with_faad"
+ then
+ AC_MSG_ERROR([Could not find libfaad])
+ else
+ AC_MSG_RESULT([Could not find libfaad, MP4 transcoding disabled])
+ fi
+fi
+
dnl -- and finish up --
LIBS="$LIBS $LIBM $LIBDL"
@@ -312,3 +358,4 @@
AC_MSG_RESULT([ Perl : $have_perl])
AC_MSG_RESULT([ LAME : $have_LAME])
AC_MSG_RESULT([ Vorbis : $have_vorbis])
+AC_MSG_RESULT([ MP4 : $have_faad])
Modified: icecast/trunk/ices0/doc/ices.1.in
===================================================================
--- icecast/trunk/ices0/doc/ices.1.in 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/doc/ices.1.in 2004-07-30 18:59:21 UTC (rev 7421)
@@ -68,7 +68,8 @@
On-the-fly reencoding of your source audio to a different bitrate,
number of channels and/or sample rate. ices can also decode Ogg Vorbis
files and reencode them on the fly as MP3, for the benefit of older
-listening software.
+listening software. This just in: it can transcode MP4 (AAC) files now
+too.
.IP \(bu
Crossfading between tracks. This is a new feature, and requires
reencoding support.
Modified: icecast/trunk/ices0/src/Makefile.am
===================================================================
--- icecast/trunk/ices0/src/Makefile.am 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/src/Makefile.am 2004-07-30 18:59:21 UTC (rev 7421)
@@ -5,13 +5,13 @@
bin_PROGRAMS = ices
noinst_HEADERS = icestypes.h definitions.h setup.h log.h stream.h util.h \
- cue.h metadata.h in_vorbis.h mp3.h id3.h signals.h reencode.h \
+ cue.h metadata.h in_vorbis.h mp3.h in_mp4.h id3.h signals.h reencode.h \
ices_config.h
ices_SOURCES = ices.c log.c setup.c stream.c util.c mp3.c cue.c metadata.c \
id3.c signals.c crossfade.c
-EXTRA_ices_SOURCES = ices_config.c reencode.c in_vorbis.c
+EXTRA_ices_SOURCES = ices_config.c reencode.c in_vorbis.c in_mp4.c
ices_LDADD = $(ICES_OBJECTS) playlist/libplaylist.a
ices_DEPENDENCIES = $(ices_LDADD)
Modified: icecast/trunk/ices0/src/icestypes.h
===================================================================
--- icecast/trunk/ices0/src/icestypes.h 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/src/icestypes.h 2004-07-30 18:59:21 UTC (rev 7421)
@@ -78,7 +78,8 @@
/* -- input stream types -- */
typedef enum {
ICES_INPUT_VORBIS,
- ICES_INPUT_MP3
+ ICES_INPUT_MP3,
+ ICES_INPUT_MP4
} input_type_t;
typedef struct _input_stream_t {
Added: icecast/trunk/ices0/src/in_mp4.c
===================================================================
--- icecast/trunk/ices0/src/in_mp4.c 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/src/in_mp4.c 2004-07-30 18:59:21 UTC (rev 7421)
@@ -0,0 +1,198 @@
+/* in_mp4.c
+ * Plugin to read MP4 files as PCM
+ *
+ * Copyright (c) 2004 Brendan Cully <brendan at xiph.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#include "config.h"
+#include "in_mp4.h"
+#include "metadata.h"
+
+#include <string.h>
+
+/* fink error? */
+#define HAVE_IN_PORT_T 1
+#define HAVE_SOCKLEN_T 1
+#include <mp4.h>
+#include <faad.h>
+
+#define SAMPLESIZE 2
+#ifdef WORDS_BIGENDIAN
+# define ICES_OV_BE 1
+#else
+# define ICES_OV_BE 0
+#endif
+
+/* -- data structures -- */
+typedef struct {
+ MP4FileHandle mp4file;
+ MP4TrackId track;
+ faacDecHandle decoder;
+ MP4SampleId cur_sample;
+} mp4_in_t;
+
+/* -- static prototypes -- */
+static int ices_mp4_readpcm (input_stream_t* self, size_t len,
+ int16_t* left, int16_t* right);
+static int ices_mp4_close (input_stream_t* self);
+
+/* try to open an MP4 file for decoding. Returns:
+ * 0: success
+ * 1: not an MP4 file
+ * -1: error opening
+ */
+int
+ices_mp4_open (input_stream_t* self, char* buf, size_t len)
+{
+ mp4_in_t* mp4_data;
+ MP4FileHandle mp4file;
+ MP4TrackId track;
+ faacDecHandle decoder;
+ unsigned int tracks;
+ unsigned int i;
+ unsigned char *escfg;
+ unsigned int escfglen;
+ unsigned long samplerate;
+ unsigned char channels;
+
+ /* At the moment we can only open seekable streams */
+ if (! self->filesize)
+ return 1;
+
+ if ((mp4file = MP4Read(self->path, 0)) == MP4_INVALID_FILE_HANDLE)
+ return 1;
+
+ /* find audio stream */
+ track = MP4_INVALID_TRACK_ID;
+ tracks = MP4GetNumberOfTracks(mp4file, MP4_AUDIO_TRACK_TYPE, 0);
+ for (i = 0; i < tracks; i++) {
+ if ((track = MP4FindTrackId(mp4file, i, MP4_AUDIO_TRACK_TYPE, 0)) != MP4_INVALID_TRACK_ID)
+ break;
+ }
+ if (track == MP4_INVALID_TRACK_ID) {
+ ices_log_error("ices_mp4_open: No audio track found");
+ goto errMP4;
+ }
+
+ MP4GetTrackESConfiguration(mp4file, track, &escfg, &escfglen);
+ if (!escfg) {
+ ices_log_error("ices_mp4_open: No audio format information found");
+ goto errMP4;
+ }
+
+ if (!(decoder = faacDecOpen())) {
+ ices_log_error("ices_mp4_open: Could not get a FAAD handle");
+ goto errMP4;
+ }
+
+ if (faacDecInit2(decoder, escfg, escfglen, &samplerate, &channels) < 0) {
+ ices_log_error("ices_mp4_open: Could not initialise FAAD");
+ free(escfg);
+ goto errFAAC;
+ }
+ free(escfg);
+
+ ices_log_debug("Found MP4 audio at track %u, sample rate %u, %u channels", track, samplerate, channels);
+
+ if (channels != 2) {
+ ices_log_error("ices_mp4_open: Bad number of channels");
+ goto errFAAC;
+ }
+
+ if (!(mp4_data = (mp4_in_t*)malloc (sizeof (mp4_in_t)))) {
+ ices_log_error ("Malloc failed in ices_mp4_open");
+ goto errFAAC;
+ }
+
+ close(self->fd);
+
+ self->samplerate = samplerate;
+ self->channels = channels;
+
+ mp4_data->mp4file = mp4file;
+ mp4_data->track = track;
+ mp4_data->decoder = decoder;
+ mp4_data->cur_sample = 1;
+
+ self->type = ICES_INPUT_MP4;
+ self->data = mp4_data;
+
+ self->read = NULL;
+ self->readpcm = ices_mp4_readpcm;
+ self->close = ices_mp4_close;
+
+ return 0;
+
+errFAAC:
+ faacDecClose(decoder);
+errMP4:
+ MP4Close(mp4file);
+
+ return -1;
+}
+
+static int
+ices_mp4_readpcm (input_stream_t* self, size_t olen, int16_t* left,
+ int16_t* right)
+{
+ mp4_in_t* mp4_data = (mp4_in_t*)self->data;
+ unsigned char* buf;
+ unsigned int blen;
+ faacDecFrameInfo fi;
+ void* decbuf;
+ int i;
+
+ fi.samples = 0;
+ while (fi.samples == 0) {
+ buf = NULL;
+ if (!MP4ReadSample(mp4_data->mp4file, mp4_data->track, mp4_data->cur_sample++,
+ &buf, &blen, NULL, NULL, NULL, NULL) || !blen)
+ {
+ ices_log_error("Error reading MP4");
+ return 0;
+ }
+
+ decbuf = faacDecDecode(mp4_data->decoder, &fi, buf, blen);
+ free (buf);
+ if (fi.error) {
+ ices_log_error("Error decoding MP4: %s", faacDecGetErrorMessage(fi.error));
+ return 0;
+ }
+
+ }
+ i = 0;
+ while (i < fi.samples * 2) {
+ *left++ = ((int16_t*)decbuf)[i++];
+ *right++ = ((int16_t*)decbuf)[i++];
+ }
+
+ return fi.samples / 2;
+}
+
+static int
+ices_mp4_close (input_stream_t* self)
+{
+ mp4_in_t* mp4_data = (mp4_in_t*) self->data;
+
+ faacDecClose(mp4_data->decoder);
+ MP4Close(mp4_data->mp4file);
+ free (mp4_data);
+
+ return 0;
+}
Property changes on: icecast/trunk/ices0/src/in_mp4.c
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: icecast/trunk/ices0/src/in_mp4.h
===================================================================
--- icecast/trunk/ices0/src/in_mp4.h 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/src/in_mp4.h 2004-07-30 18:59:21 UTC (rev 7421)
@@ -0,0 +1,30 @@
+/* in_mp4.h
+ * ices input plugin to read MP4 files as PCM
+ *
+ * Copyright (c) 2004 Brendan Cully <brendan at xiph.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef IN_MP4_H
+#define IN_MP4_H
+
+#include "definitions.h"
+
+int ices_mp4_open (input_stream_t* self, char* buf, size_t len);
+
+#endif
Property changes on: icecast/trunk/ices0/src/in_mp4.h
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: icecast/trunk/ices0/src/stream.c
===================================================================
--- icecast/trunk/ices0/src/stream.c 2004-07-30 17:33:50 UTC (rev 7420)
+++ icecast/trunk/ices0/src/stream.c 2004-07-30 18:59:21 UTC (rev 7421)
@@ -352,6 +352,15 @@
return -1;
}
+ #ifdef HAVE_LIBFAAD
+ if (!(rc = ices_mp4_open (source, buf, len)))
+ return 0;
+ if (rc < 0) {
+ close(fd);
+ return -1;
+ }
+ #endif
+
if (!(rc = ices_mp3_open (source, buf, len)))
return 0;
if (rc < 0) {
More information about the commits
mailing list