1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-06-23 06:25:24 +00:00

bump version, drop debian directory as it's unmaintained here. some more thread

removal work for stats, video preview merge (not built by default) and a couple
of bug fixes from reported feedback.

svn path=/icecast/branches/kh/icecast/; revision=15372
This commit is contained in:
Karl Heyes 2008-10-04 01:09:17 +00:00
parent 386a554a72
commit b6dc964a29
45 changed files with 902 additions and 1426 deletions

View File

@ -3,7 +3,7 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src conf debian doc web admin win32
SUBDIRS = src conf doc web admin win32
EXTRA_DIST = HACKING config.h.vc6 m4/acx_pthread.m4 m4/ogg.m4 \
m4/theora.m4 m4/vorbis.m4 m4/speex.m4\

15
NEWS
View File

@ -15,6 +15,21 @@ Feature differences from SVN trunk
any extra tags are show in the conf/icecast.xml.dist file
2.3.2-kh2
. more stats work. Clients are now processed as needed instead of a dedicated
thread per stats client.
. don't allow raw metadata updates if not from the same IP address as the source
client unless it is from the admin user. For some reason some source client
issue updates even though they are rejected.
. missing lock on streamlist master/slave update, could cause memory corruption.
. update to average bitrate handling.
. allow strftime expansion on dump filename, applies at the time the stream has
started
. removed debian directory, it's not maintained really so leave it to the debian
people to deal with it themselves.
. experimental theora keyframe as png patch added. not built by default
. minor memory leak plugged in fserve
2.3.2-kh1
. remove stats thread. Stats clients still have their own thread and queue.
. fix low bandwidth theora stream problem.

View File

@ -7,7 +7,7 @@
<head>
<title>Icecast log files</title>
</head>
<body style="color: white; font-size: 90%">
<body bgcolor="#656565" style="color: white; font-size: 90%">
<table>
<tr><td><pre>
<xsl:for-each select="/icestats"> <xsl:for-each select="log"> <xsl:value-of select="." /> </xsl:for-each></xsl:for-each>

View File

@ -13,7 +13,7 @@
/* Define to 1 if you have the <curl/curl.h> header file. */
#define HAVE_CURL_CURL_H 1
/* Define t o1 if you have the 'curl_global_init' function */
/* Define to 1 if you have the 'curl_global_init' function */
#define HAVE_CURL_GLOBAL_INIT 1
/* Define to 1 if you have the `inet_aton' function. */
@ -95,7 +95,7 @@
#define PACKAGE_NAME "Icecast"
/* Version number of package */
#define VERSION "2.3.2-kh1"
#define VERSION "2.3.2-kh2"
/* Define to the version of this package. */
#define PACKAGE_VERSION VERSION
@ -162,3 +162,4 @@ typedef unsigned int socklen_t;
/* time format for strftime */
#define ICECAST_TIME_FMT "%a, %d %b %Y %H:%M:%S"
#define PATH_MAX MAX_PATH

View File

@ -1,4 +1,4 @@
AC_INIT([Icecast], [2.3.2-kh1], [karl@xiph.org])
AC_INIT([Icecast], [2.3.2-kh2], [karl@xiph.org])
AC_PREREQ(2.59)
AC_CONFIG_SRCDIR(src/main.c)
@ -155,7 +155,7 @@ AC_SUBST(ICECAST_OPTIONAL)
AC_SUBST(HAVE_KATE)
AC_SUBST(KATE_LIBS)
AC_OUTPUT([Makefile conf/Makefile debian/Makefile src/Makefile src/avl/Makefile
AC_OUTPUT([Makefile conf/Makefile src/Makefile src/avl/Makefile
src/httpp/Makefile src/thread/Makefile src/log/Makefile
src/net/Makefile src/timing/Makefile doc/Makefile web/Makefile web/images/Makefile
admin/Makefile win32/Makefile win32/res/Makefile])

8
debian/Makefile.am vendored
View File

@ -1,8 +0,0 @@
## Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = 1.6 foreign
EXTRA_DIST = README.Debian changelog compat control copyright \
icecast2.1 icecast2.default icecast2.init icecast2.manpages \
icecast2.postinst icecast2.postrm icecast2.preinst rules watch

48
debian/README.Debian vendored
View File

@ -1,48 +0,0 @@
icecast2 for Debian
-------------------
In relation to the comment below by Jonas Smedegaard and chroot issues,
I've modified the debian package so that it will install xsl pages as
well as icecast.xml under /usr/share/icecast2, and symlink from there
to /etc/icecast2.
I've no idea why it would be necessary to symlink admin/ and web/ into
/etc/icecast2, but the config file icecast.xml should be there at least
as it's a standard location for config files.
However the *real* file now lives in /usr/share/icecast2/etc/icecast2/icecast.xml
because it must be available to the server when it runs in a jail (chroot)
otherwise config reload won't work as /etc/icecast2 would normally be outside
the jail.
The only issue pending of solution is the resolver within the jail,
which will be required mostly for the YP servers name resolution.
I'm researching this right now.
-- Rama <rama@r23.cc> Sun, 2 Jul 2006 10:24:43 +0200
In the Debian packaging the configuration files have been symlinked from
the upstream location below /usr/share to /etc. This is needed to
satisfy FHS (/usr/share are for static content only).
If running icecast2 in a chroot environment, beware that the symlinks to
/etc will break. A possible (untestet!) solution might be to manually
put the configuration files back below /usr/share - and revert the hack
again before updating the package!
-- Jonas Smedegaard <dr@jones.dk> Thu, 20 May 2004 21:04:27 +0200
It is recommended to run icecast under a dedicated user account, which only
has access to write the log files. The Debian package creates such an
account, named 'icecast2', and uses it by default, but you are free to
reconfigure it and remove the account.
Edit /etc/default/icecast2 to change the init-script configuration.
It is possible (but discouraged for security reasons) to bind to a
priviledged port (like standard web port 80). Edit /etc/init.d/icecast2
to not change userid and instead set the correct userid and group in
/etc/icecast2/icecast2.xml. Beware that this way you rely on the
icecast2 binary to properly drop priviledges (instead of the much more
thoroughly audited start-stop-daemon). Thanks to Jürgen A. Erhard
<jae@jerhard.org> for the tip.
-- Keegan Quinn <ice@thebasement.org>

410
debian/changelog vendored
View File

@ -1,410 +0,0 @@
icecast2 (2.3-kh6-2) stable; urgency=low
* Non-maintainer unofficial branch upload.
* Fixed debian/rules and debian/icecast2.postinst so that the xsl
pages get installed in /usr/share/icecast2 and symlink them to
/etc/icecast2 (is that symlink useful?) so that chroot setup
is more straight forward.
* /etc/icecast2/icecast.xml becomes a symlink to
/usr/share/icecast2/etc/icecast2/icecast.xml for the same reason.
-- Rama <rama@r23.cc> Fri, 30 Jun 2006 23:13:56 +0200
icecast2 (2.3-kh6-1) stable; urgency=low
* Non-maintainer unofficial branch upload.
* Depends on libtheora > 1.0alpha6
* NOTE: this is not considered stable but rather experimental
-- Rama <rama@r23.cc> Thu, 25 May 2006 19:12:39 +0200
icecast2 (2.2.0-1) unstable; urgency=low
* New upstream release. Closes: bug#286739 (thanks - again - to Andre
Tomt <andre@tomt.net>).
* Debian subdir is again stripped from tarball, but autotools patching
(to aboid complaints about the missing dir) is now in diff. Updated
note in debian/copyright.
* Build-depend on libtheora-dev (current version is too old but as
soon as libtheora is updated it will then get built in).
* Updated source location in debian/copyright and debian/watch.
* Correct typo in long description.
-- Jonas Smedegaard <dr@jones.dk> Wed, 29 Dec 2004 15:04:17 +0100
icecast2 (2.1.0-1) unstable; urgency=medium
* New upstream release. Closes: bug#279869 (thanks to Andre Tomt
<andre@tomt.net>).
* Strip annoying debian subdir from upstream source.
* Update debian/copyright:
+ License is included now (no need to refer to CVS).
+ Remove stray repeated license above licensing section.
+ Add note about tarball not being pristine (and explain why).
+ Use capital "I" in initial introduction to upstream name.
* Use generic (but unofficial) buildinfo cdbs snippet.
* Drop cleaning up conf/icecast.xml.dist (handled properly upstream
now).
* Set urgency=medium to hopefully reach sarge.
* Correct README.Debian to mention user "icecast2" (not "icecast").
* Move and symlink stylesheet to /etc (similar to xslt files).
-- Jonas Smedegaard <dr@jones.dk> Sun, 7 Nov 2004 15:52:50 +0100
icecast2 (2.0.2.debian-3) unstable; urgency=high
* Fix wrong space in build-depends.
* Set urgency=high to hopefully get this compiled (even for sparc)
in time for sarge release.
-- Jonas Smedegaard <dr@jones.dk> Tue, 26 Oct 2004 14:23:04 +0200
icecast2 (2.0.2.debian-2) unstable; urgency=high
* Include "endscript" in logrotate rule. Closes: bug#274823 (thanks to
Jose Antonio <jose@shaolin.homeip.net>).
* Set urgency=high to still push earlier security fix.
-- Jonas Smedegaard <dr@jones.dk> Mon, 4 Oct 2004 11:00:31 +0200
icecast2 (2.0.2.debian-1) unstable; urgency=high
* New upstream release.
+ Fixes upstream announced security bug.
+ Set urgency=high due to the above.
+ Closes: bug#274320 (thanks to Jeroen Wolffelaar
<jeroen@wolffelaar.nl>).
+ Again - strip non-free win32/ResizableDialog.* from source.
+ While we are at it, move upstream debian subdirectory off to
dist/debian. Hack configure and configure.in to not mess around.
* Update location of upstream source in copyright and watch file.
* Use more flexible regexp in watch file.
* Rename Debian NEWS file in source to get recognized automativally.
* Devine man page within rules file.
* Drop unneeded preinst (from a time before official Debian where it
did not run properly as a daemon?).
* Build-depend on libcurl3-dev, and on the virtual package libcurl-dev
only as fallback (not mandatory, but aptitude chokes and so will the
build daemons as well, I suppose).
* Reload (which does a sighup) daemon after logrotate. Closes:
bug#265301 (thanks to David Pashley <david@davidpashley.com>).
-- Jonas Smedegaard <dr@jones.dk> Sat, 2 Oct 2004 11:27:14 +0200
icecast2 (2.0.1.debian-3) unstable; urgency=low
* Tolerate failure to remove icecast group on purge (it is used by
other packages as well, and was badly handled in older unstable
packages). This closes: Bug#246263 (thanks to Pete de Zwart
<dezwart@froob.net>).
* Fix logrotate script. Closes: Bug#249404, #255430 (thanks
to Julien Cristau <jcristau@ens-lyon.fr> and Mykola A. Nickishov
<mn@mn.com.ua>).
* Mention upstream website in long description.
* Build-depend on autotools-dev to let cdbs do clever autotools magic.
* Stylistic improvements to debian/rules:
+ Add copyright notice and editor hints at top.
+ Use only (cdbs-)generic make targets.
* Build-depend generically on libxslt-dev and libcurl-dev (instead of
libxslt1-dev and libcurl2-dev).
-- Jonas Smedegaard <dr@jones.dk> Wed, 7 Jul 2004 09:32:56 +0200
icecast2 (2.0.1.debian-2) unstable; urgency=low
* Really add ChangeLog from 2.0.0.
-- Jonas Smedegaard <dr@jones.dk> Thu, 20 May 2004 23:03:22 +0200
icecast2 (2.0.1.debian-1) unstable; urgency=medium
* New upstream release (thanks to Ian Kumlien <pomac@vapor.com>):
+ According to announcement on website, it "fixes a overflow buffer
which can cause server crashes under certain circumstances" so set
urgency=medium (the code change is one line only).
+ Again, remove the non-free win32/ResizableDialog.* as it is
still(!) distributed with official source.
+ Add ChangeLog from 2.0.0 missing from current release.
* Register with (and recommend) logrotate. Closes: Bug#299404 (thanks
to Julien Cristau <jcristau@ens-lyon.fr>).
* Add note to README.Debian about chroots not working with symlinks
due to FHS requirements of configuration files located below /etc.
Closes: Bug#250056 (thanks to Ian Kumlien <pomac@vapor.com>).
* Standards-Version: 3.6.1 (no changes needed).
* Explicitly note version in watch file, and add it to TODO.Debian.
* Add comment to watch file hinting on how to use it.
-- Jonas Smedegaard <dr@jones.dk> Thu, 20 May 2004 21:40:03 +0200
icecast2 (2.0.0.debian-1) unstable; urgency=low
* Re-release with non-free files (unused with Debian) stripped from
source:
+ Remove non-free win32/ResizableDialog.* from source, and remove
its copyright and licensing info from debian/copyright.
+ Add to debian/copyright GPL info taken from newer CVS, and email
from upstream to BTS permitting it to be used also with this
earlier release.
+ This closes: Bug#229720, thanks to upstream and Steve Langasek
<vorlon@debian.org>.
* Add TODO.Debian with reminder to clean this mess later.
-- Jonas Smedegaard <dr@jones.dk> Sun, 28 Mar 2004 16:02:27 +0200
icecast2 (2.0.0-2) unstable; urgency=low
* Add group if non-existing.
-- Jonas Smedegaard <dr@jones.dk> Mon, 26 Jan 2004 16:07:23 +0100
icecast2 (2.0.0-1) unstable; urgency=low
* New upstream release. Closes: Bug#223645, thanks to Nicholas Humfrey
<njh@ecs.soton.ac.uk>.
* Use upstream long description, and rearrange short description a
bit.
* Rewrite debian/copyright:
+ Note the upstream package name.
+ Drop Debian-related info also in debian/changelog.
+ Update location of upstream source.
+ Replace general copyright and license info (where was it found?
See bug#229720) with that of individual files where provided.
* Update debian/watch with new location.
* Use username icecast2 (instead of icecast also used in the package
icecast-server). Add NEWS.Debian with info on the change. Closes:
bug#215671, #226807, thanks to Michael Deegan
<debbts@cnspc18.murdoch.edu.au> and Robin Lee Powell
<rlpowell@digitalkingdom.org>.
* Make sure /etc/icecast2 is owned by icecast2 and not world readable.
Closes: bug#210860, thanks to Frank Barknecht <fbar@footils.org>.
* Install NEWS again (now that NEWS and ChangeLog are different).
* Build-depend on libcurl2-dev (again, and hope it works now...).
Closes: Bug#222274 thanks to Nicholas Humfrey <njh@ecs.soton.ac.uk>.
* Let icecast2 go into background by itself (using -b). Closes:
Bug#204061 (and add the actual content of the bugreport - how to
bind to a priviledged port by starting as root - to README.Debian),
thanks to Jürgen A. Erhard <jae@jerhard.org>.
* Let "configure --program-transform-name" rename icecast to icecast2.
* Let debhelper create /var/log/icecast2/.
* Keep debian/rules comments from showing during build.
-- Jonas Smedegaard <dr@jones.dk> Mon, 26 Jan 2004 06:30:26 +0100
icecast2 (1.9+2.0beta3-1) unstable; urgency=low
* New upstream release.
* Taking over maintainership. When Keegan some day comes through the
NM process he can take over maintainance.
* ChangeLog is provided upstream now, so use that (in favor of NEWS).
-- Jonas Smedegaard <dr@jones.dk> Tue, 16 Dec 2003 22:02:25 +0100
icecast2 (1.9+2.0alphasnap2+20030802-1.2) unstable; urgency=low
* Another sponsor-NMU (forgot to force including source).
-- Jonas Smedegaard <dr@jones.dk> Sun, 17 Aug 2003 10:25:16 +0200
icecast2 (1.9+2.0alphasnap2+20030802-1.1) unstable; urgency=low
* NMU by sponsor.
-- Jonas Smedegaard <dr@jones.dk> Sun, 17 Aug 2003 01:25:22 +0200
icecast2 (1.9+2.0alphasnap2+20030802-1) unstable; urgency=low
* Added a 'watch' file to automate tracking of updates.
* Now uses dh-buildinfo to store information about the package build
environment. Added a Build-Dependancy to dh-buildinfo.
* Removed cdbs/autotools-vars.mk, from cdbs CVS, because a new release
was made.
* Enabled curl during configure stage, since --disable-curl was recently
broken upstream, and potentially broken YP support can be disabled at
runtime.
* Trimmed ancient upgrade nodes and other cruft, left over from
pre-Debian versions, from README.Debian.
* Removed some autotools build cruft, since bugs were fixed upstream.
* Normalized {preinst,postinst,postrm} filenames to
icecast2.{preinst,postinst,postrm}. Thanks to Emmanuel le Chevoir
for this suggestion.
* Fixed preinst; was stopping /usr/bin/icecast instead of
/usr/bin/icecast2. Thanks to Emmanuel le Chevoir for this suggestion.
* Removed prerm, since it was not serving any purpose. Thanks to
Emmanuel le Chevoir for this suggestion.
* Cleaned up postinst: removed old comments, fixed a path typo in the
configuration file location change message.
* Cleaned up postrm: removed old comments, fixed a typo in the group
removal test.
* Thanks to Jonas Smedegaard for sponsoring this package, and
providing many good suggestions.
-- Keegan Quinn <ice@thebasement.org> Sat, 2 Aug 2003 20:28:13 -0700
icecast2 (1.9+2.0alphasnap2+20030720-1.1) unstable; urgency=low
* NMU by sponsor (still closes: Bug#178160).
-- Jonas Smedegaard <dr@jones.dk> Wed, 23 Jul 2003 06:03:42 +0200
icecast2 (1.9+2.0alphasnap2+20030720-1) unstable; urgency=low
* New daily snapshot build.
* Added Build-Dependancy to cdbs, and increased debhelper version
requirement as recommended by cdbs README.
* Corrected Standards-Version to 3.6.0. This package now generates
no lintian errors.
* Updated Recommends for ices to ices2; it was renamed.
* Added more information to the long description.
* Thanks to Jonas Smedegaard for sponsoring this package.
* This revision still closes: #178160 - the last was not uploaded.
-- Keegan Quinn <ice@thebasement.org> Mon, 21 Jul 2003 08:55:27 -0700
icecast2 (1.9+2.0alphasnap2+20030714-0.2) unstable; urgency=low
* Sponsored upload. Closes: Bug#178160.
* Switch to cdbs (agreed with maintainer).
* Use cdbs autotools-vars.mk from CVS to avoid cross-compiling on same
host.
* Add build-dependency on libxml2-dev.
* Explicitly configure without curl support to avoid building broken
YP stuff.
* Hack src/Makefile.am to use AM_CFLAGS instead of CFLAGS (which is
overridden by cdbs), and add clean rule to avoid invoking automake.
* Disable daemon by default and hint about changing passwords before
enabling.
* Avoid moving config files from pre-Debian times - instead just print
a warning if config exists in old location (better mess as little as
possible with files not ever claimed to be ours).
* Update README.Debian to reflect the above, include note about YP
support not compiled in, and remove note regarding adoption.
* Strip paths from packaging scripts (they may move around in the
future, and if PATH is wrong then something else broken anyway).
* Avoid removing unused /usr/share/icecast2 on purge.
* Remove icecast group on purge only if empty.
* Standards-version 3.6 (no changes needed).
* Fix wrong escaping of sed vars in conf/Makefile.
* Symlink public files from /usr/share/icecast2 to /etc/icecast2
(instead of pointing public root dirs below /etc).
* Use upstream config (paths are properly included now).
-- Jonas Smedegaard <dr@jones.dk> Sun, 20 Jul 2003 20:19:30 +0200
icecast2 (1.9+2.0alphasnap2+20030714-0.1) unstable; urgency=low
* New daily snapshot build.
* Updated versioning scheme to reflect (as well as possible) that the
source is a daily snapshot now, not CVS.
-- Keegan Quinn <ice@thebasement.org> Mon, 14 Jul 2003 19:39:58 -0700
icecast2 (1.9+2.0alphacvs030704-0.1) unstable; urgency=low
* Constructed a build script to completely automate the construction
of the 'pristine' tarball from CVS. This doesn't really effect the
contents of the package, just makes it easier for me to rebuild.
* New CVS source.
* Removed Build-Dependancy on libcurl2-dev; packages built without this
library present will not have YP functionality, which is okay for
now since it's badly broken.
* Updated the default configuration file, including some new options
recently added upstream.
* Added a number of tweaks to clean up and rearrange new configuration
and documentation added to upstream install target.
* Moved the configuration file from /etc/icecast.xml to
/etc/icecast2/icecast.xml. See README.Debian.
* Nice ugly version number to reflect that upstream calls this the 2.0
alpha branch, without potentially introducing the need for an epoch.
-- Keegan Quinn <ice@thebasement.org> Thu, 3 Jul 2003 23:46:56 -0700
icecast2 (0.00.cvs030529-0.1) unstable; urgency=low
* New CVS source.
* Removed unnecessary debconf stuff.
* Added README.Debian.
* Path updates:
- /usr/share/icecast to /usr/share/icecast2,
- /var/log/icecast to /var/log/icecast2,
- /usr/bin/icecast to /usr/bin/icecast2,
- /usr/share/man/man8/icecast.8.gz to /usr/share/man/man8/icecast2.8.gz.
-- Keegan Quinn <ice@thebasement.org> Wed, 29 May 2003 22:53:21 -0700
icecast2 (0.00.cvs030403-0.2) unstable; urgency=low
* Tried to make the default configuration more understandable.
-- Keegan Quinn <ice@thebasement.org> Fri, 4 Apr 2003 10:55:27 -0800
icecast2 (0.00.cvs030403-0.1) unstable; urgency=low
* New CVS source.
* Minor changes to postrm.
-- Keegan Quinn <ice@thebasement.org> Thu, 3 Apr 2003 16:05:09 -0800
icecast2 (0.00.cvs030401-0.7) unstable; urgency=low
* Minor changes to postinst.
* Added --background flag to initscript, since this version of icecast
does not yet run detached.
-- Keegan Quinn <ice@thebasement.org> Thu, 3 Apr 2003 14:24:19 -0800
icecast2 (0.00.cvs030401-0.6) unstable; urgency=low
* Added Debianized configuration file.
* Created and set ownership of /var/log/icecast and /usr/share/icecast.
-- Keegan Quinn <ice@thebasement.org> Thu, 3 Apr 2003 14:15:11 -0800
icecast2 (0.00.cvs030401-0.5) unstable; urgency=low
* Attempt at making debconf work properly.
-- Keegan Quinn <ice@thebasement.org> Thu, 3 Apr 2003 12:07:16 -0800
icecast2 (0.00.cvs030401-0.4) unstable; urgency=low
* Minor edits to init.d script.
* Added bits to create and remove system accounts appropriately.
* Typo fix in the manual page.
-- Keegan Quinn <ice@thebasement.org> Thu, 3 Apr 2003 11:06:48 -0800
icecast2 (0.00.cvs030401-0.3) unstable; urgency=low
* Finished init.d script and manual page.
* Updated postinst to handle rc*.d links.
* Package is now lintian/linda clean.
-- Keegan Quinn <ice@thebasement.org> Wed, 2 Apr 2003 16:29:18 -0800
icecast2 (0.00.cvs030401-0.2) unstable; urgency=low
* Updated copyright (replacing dh_make template).
* Fixed duplicate conffiles.
-- Keegan Quinn <ice@thebasement.org> Wed, 2 Apr 2003 16:18:02 -0800
icecast2 (0.00.cvs030401-0.1) unstable; urgency=low
* New CVS source.
* Lots of packaging cleanup.
* Initial stab at manual page and init.d script.
-- Keegan Quinn <ice@thebasement.org> Wed, 2 Apr 2003 10:25:56 -0800
icecast2 (0.00.cvs030320-0.1) unstable; urgency=low
* New CVS source.
* Automated CVS original source creation.
-- Keegan Quinn <ice@thebasement.org> Thu, 20 Mar 2003 12:58:49 -0800
icecast2 (0.00.cvs030315-0.1) unstable; urgency=low
* Initial Release.
-- Keegan Quinn <ice@thebasement.org> Sun, 16 Mar 2003 13:45:23 -0800

1
debian/compat vendored
View File

@ -1 +0,0 @@
4

20
debian/control vendored
View File

@ -1,20 +0,0 @@
Source: icecast2
Section: sound
Priority: optional
Maintainer: Rama <rama@r23.cc>
Build-Depends: cdbs, autotools-dev, debhelper (>> 4.1.0), dh-buildinfo, libogg-dev (>> 1.0.0), libvorbis-dev (>> 1.0.0), libxslt-dev, libxml2-dev, libcurl3-dev | libcurl-dev, libtheora-dev (>= 0.0.0.alpha6)
Standards-Version: 3.6.1
Package: icecast2
Architecture: any
Depends: ${shlibs:Depends}
Recommends: ices2
Description: Ogg Vorbis and MP3 streaming media server
Icecast is a streaming media server which currently supports Ogg
Vorbis and MP3 audio streams. It can be used to create an Internet
radio station or a privately running jukebox and many things in
between. It is very versatile in that new formats can be added
relatively easily and supports open standards for communication and
interaction.
.
Website: http://www.icecast.org/

96
debian/copyright vendored
View File

@ -1,96 +0,0 @@
This is Icecast 2.x packaged for Debian.
Upstream source: http://downloads.us.xiph.org/releases/icecast/
Note: Tarball distributed with Debian is currently not pristine: the
subdir "debian" has been stripped to not clash with the official Debian
packaging files.
Upstream Authors: the icecast team <team@icecast.org>
Copyright and license; src/httpd/:
licensed under the lgpl
created by jack moffitt <jack@icecast.org>
Copyright and license; src/avl/:
* Copyright (C) 1995-1997 by Sam Rushing <rushing@nightmare.com>
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice appear in all
* copies and that both that copyright notice and this permission
* notice appear in supporting documentation, and that the name of Sam
* Rushing not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission.
*
* SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Copyright and license; src/thread/:
* Copyright (c) 1999, 2000 the icecast team <team@icecast.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Copyright and license; src/net/:
* Copyright (C) 1999 the icecast team <team@icecast.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Copyright and license; src/httpd/:
lgpl
by jack moffitt <jack@icecast.org>
Copyright and license; other files (found in src/client.c):
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*
* Copyright 2000-2004, Jack Moffitt <jack@xiph.org,
* Michael Smith <msmith@xiph.org>,
* oddsock <oddsock@xiph.org>,
* Karl Heyes <karl@xiph.org>
* and others (see AUTHORS for details).
On Debian systems, the complete text of both the GNU General Public
License (GPL) and the GNU Library General Public License (LGPL) can be
found below `/usr/share/common-licenses/'.

24
debian/icecast2.1 vendored
View File

@ -1,24 +0,0 @@
.\" Hey, EMACS: -*- nroff -*-
.TH ICECAST2 1 "July 28, 2003"
.SH NAME
icecast2 \- an MP3/Ogg Vorbis broadcast streaming media server
.SH SYNOPSIS
.B icecast2
-c
.RI config.xml
.SH DESCRIPTION
\fBicecast2\fP is an audio broadcasting system that streams music in
Ogg Vorbis and/or MPEG 1 Layer III format. It accepts stream input
from sources like ices0 and ices2, and broadcasts to clients like xmms.
.SH OPTIONS
\fBicecast2\fP has no command line options, except to specify the location
of an XML configuration file. All operational aspects of the software
are controlled by this XML configuration file.
.SH SEE ALSO
The example configuration files, provided with the package documentation
are the only reliable source of information on this software.
It is still under very active development;
documentation will be written when it is possible to do so.
.SH AUTHOR
icecast2 was created by the icecast team <team@icecast.org>.
This manual page was written by Keegan Quinn <ice@thebasement.org>.

View File

@ -1,19 +0,0 @@
# Defaults for icecast2 initscript
# sourced by /etc/init.d/icecast2
# installed at /etc/default/icecast2 by the maintainer scripts
#
# This is a POSIX shell fragment
#
# Full path to the server configuration file
CONFIGFILE="/etc/icecast2/icecast.xml"
# Name or ID of the user and group the daemon should run under
USERID=icecast2
GROUPID=icecast
# Edit /etc/icecast2/icecast.xml and change at least the passwords.
# Change this to true when done to enable the init.d script
ENABLE=false

67
debian/icecast2.init vendored
View File

@ -1,67 +0,0 @@
#! /bin/sh
#
# icecast2
#
# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
# Modified for Debian
# by Ian Murdock <imurdock@gnu.ai.mit.edu>.
#
# Further modified by Keegan Quinn <ice@thebasement.org>
# for use with Icecast 2
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/icecast2
NAME=icecast2
DESC=icecast2
test -x $DAEMON || exit 0
# Defaults
CONFIGFILE="/etc/icecast2/icecast.xml"
CONFIGDEFAULTFILE="/etc/default/icecast2"
USERID=icecast2
GROUPID=icecast
ENABLE="false"
# Reads config file (will override defaults above)
[ -r "$CONFIGDEFAULTFILE" ] && . $CONFIGDEFAULTFILE
if [ "$ENABLE" != "true" ]; then
echo "$NAME daemon disabled - read $CONFIGDEFAULTFILE."
exit 0
fi
set -e
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --chuid $USERID:$GROUPID \
--exec $DAEMON -- -b -c $CONFIGFILE
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
echo "$NAME."
;;
reload|force-reload)
echo "Reloading $DESC configuration files."
start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
;;
restart)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
sleep 2
start-stop-daemon --start --quiet --chuid $USERID:$GROUPID \
--exec $DAEMON -- -b -c $CONFIGFILE
echo "$NAME."
;;
*)
echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
exit 1
;;
esac
exit 0

View File

@ -1 +0,0 @@
debian/icecast2.1

View File

@ -1,55 +0,0 @@
#! /bin/sh
# postinst script for icecast2
set -e
case "$1" in
configure)
;;
abort-upgrade|abort-remove|abort-deconfigure)
exit 0
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# Move configuration file to current location, if an old one exists
# and the init.d script configuration file was updated
if [ -f /etc/icecast.xml ] && grep -q /etc/icecast2/ /etc/default/icecast2; then
echo "It seems you have an old configuration lying around at"
echo "/etc/icecast.xml. You will need to manually merge with"
echo "the current configuration at /etc/icecast2/icecast.xml."
echo
echo "See /usr/share/doc/icecast2/examples for new configuration options."
fi
if [ -f /etc/icecast2/icecast.xml ] ; then
echo "* Found existing /etc/icecast2/icecast.xml"
echo "* Moving /etc/icecast2/icecast.xml to /usr/share/icecast2/etc/icecast2"
mv /etc/icecast2/icecast.xml /usr/share/icecast2/etc/icecast2
ln -s /usr/share/icecast2/etc/icecast2/icecast.xml /etc/icecast2/icecast.xml
fi
if ! getent group icecast >/dev/null 2>&1; then
addgroup --system icecast
fi
# Check for an account named 'icecast2'
if ! id icecast2 >/dev/null 2>&1; then
# Create the new system account
adduser --system --disabled-password --disabled-login \
--home /usr/share/icecast2 --no-create-home --ingroup icecast icecast2
fi
chown -R icecast2: /var/log/icecast2 /etc/icecast2 /usr/share/icecast2
chmod -R ug=rw,o=,ug+X /etc/icecast2
#DEBHELPER#
exit 0

View File

@ -1,30 +0,0 @@
#! /bin/sh
# postrm script for icecast2
set -e
case "$1" in
purge)
rm -rf /var/log/icecast2
rm -rf /usr/share/icecast2/log
if id icecast2 >/dev/null 2>&1; then
deluser icecast2
fi
# Remove group only if empty
if getent group icecast | awk -F: ' { print $4 } ' | egrep -cq '^$'; then
groupdel icecast || echo "Error occured removing group icecast, please do it manually."
fi
;;
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
esac
#DEBHELPER#
exit 0

View File

@ -1,27 +0,0 @@
#! /bin/sh
# preinst script for icecast2
set -e
case "$1" in
install|upgrade)
if [ "$1" = "upgrade" ]
then
start-stop-daemon --stop --quiet --oknodo \
--exec /usr/bin/icecast2 2>/dev/null || true
fi
;;
abort-upgrade)
;;
*)
echo "preinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
exit 0

27
debian/rules vendored
View File

@ -1,27 +0,0 @@
#!/usr/bin/make -f
# -*- mode: makefile; coding: utf-8 -*-
# Copyright © 2004 Jonas Smedegaard <dr@jones.dk>
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk
include debian/cdbs/1/rules/buildinfo.mk
DEB_CONFIGURE_SYSCONFDIR = /etc/icecast2
DEB_CONFIGURE_EXTRA_FLAGS = --program-transform-name="s/icecast$$/icecast2/"
DEB_MAKE_INVOKE += PACKAGE=icecast2 docdir=/usr/share/doc/icecast2 pkgdatadir=/usr/share/icecast2
DEB_INSTALL_DIRS_icecast2 = var/log/icecast2
DEB_INSTALL_MANPAGES_icecast2 = debian/icecast2.1
# Debian has a central copy of the GPL, no need to distribute again
common-binary-post-install-arch::
rm -f $(DEB_DESTDIR)/usr/share/doc/icecast2/COPYING
# Move XSLT templates and CSS files to /etc and replace with symlinks
common-binary-post-install-arch::
for file in `cd $(DEB_DESTDIR)/usr/share && find icecast2 -type d \( -name admin -or -name web \)`; do \
ln -s /usr/share/$$file $(DEB_DESTDIR)/etc/$$file; \
done
mkdir $(DEB_DESTDIR)/usr/share/icecast2/log
chown icecast2:icecast $(DEB_DESTDIR)/usr/share/icecast2/log
mkdir -p $(DEB_DESTDIR)/usr/share/icecast2/etc/icecast2
#mv $(DEB_DESTDIR)/etc/icecast2/icecast.xml $(DEB_DESTDIR)/usr/share/icecast2/etc/icecast2
#ln -s /usr/share/icecast2/etc/icecast2/icecast.xml $(DEB_DESTDIR)/etc/icecast2/icecast.xml

3
debian/watch vendored
View File

@ -1,3 +0,0 @@
# Run the "uscan" command to check for upstream updates and more.
version=2
http://downloads.us.xiph.org/releases/icecast/icecast-([\d+\.]+|\d+)(\.tar|\.tgz)(\.gz|\.bz2|) 2.2.0 uupdate

View File

@ -58,6 +58,7 @@ static void command_reset_stats (client_t *client, source_t *source, int respons
static void command_manageauth(client_t *client, source_t *source,
int response);
static void command_buildm3u(client_t *client, const char *mount);
static void command_show_image (client_t *client, const char* mount);
static void command_kill_source(client_t *client, source_t *source,
int response);
static void command_updatemetadata(client_t *client, source_t *source,
@ -355,6 +356,11 @@ int admin_handle_request (client_t *client, const char *uri)
command_buildm3u (client, mount);
return 0;
}
if (strcmp (uri, "showimage") == 0)
{
command_show_image (client, mount);
return 0;
}
/* This is a mount request, but admin user is allowed */
if (client->authenticated == 0)
@ -763,6 +769,29 @@ static void command_show_listeners(client_t *client, source_t *source,
xmlFreeDoc(doc);
}
static void command_show_image (client_t *client, const char *mount)
{
source_t *source;
avl_tree_rlock (global.source_tree);
source = source_find_mount_raw (mount);
if (source && source->format && source->format->get_image)
{
thread_mutex_lock (&source->lock);
avl_tree_unlock (global.source_tree);
if (source->format->get_image (client, source->format) == 0)
{
thread_mutex_unlock (&source->lock);
fserve_add_client (client, NULL);
return;
}
thread_mutex_unlock (&source->lock);
}
else
avl_tree_unlock (global.source_tree);
client_send_404 (client, "No image available");
}
static void command_buildm3u (client_t *client, const char *mount)
{
const char *username = NULL;
@ -961,6 +990,7 @@ static void command_metadata(client_t *client, source_t *source,
format_plugin_t *plugin;
xmlDocPtr doc;
xmlNodePtr node;
int same_ip = 1;
doc = xmlNewDoc(XMLSTR("1.0"));
node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
@ -977,10 +1007,13 @@ static void command_metadata(client_t *client, source_t *source,
thread_mutex_lock (&source->lock);
plugin = source->format;
if (source->client && strcmp (client->con->ip, source->client->con->ip) != 0)
if (response == RAW && connection_check_admin_pass (client->parser) == 0)
same_ip = 0;
do
{
if (plugin == NULL)
if (same_ip == 0 && plugin == NULL)
break;
if (artwork)
stats_event (source->mount, "artwork", artwork);
@ -1026,6 +1059,7 @@ static void command_shoutcast_metadata(client_t *client, source_t *source)
{
const char *action;
const char *value;
int same_ip = 1;
DEBUG0("Got shoutcast metadata update request");
@ -1046,6 +1080,10 @@ static void command_shoutcast_metadata(client_t *client, source_t *source)
return;
}
if (source->client && strcmp (client->con->ip, source->client->con->ip) != 0)
if (connection_check_admin_pass (client->parser) == 0)
same_ip = 0;
if (source->format && source->format->set_tag)
{
httpp_set_query_param (client->parser, "mount", client->server_conn->shoutcast_mount);
@ -1084,7 +1122,7 @@ static void command_stats (client_t *client, const char *filename)
show_mount = httpp_get_query_param (client->parser, "mount");
stats_get_xml(&doc, 1, show_mount);
stats_get_xml(&doc, STATS_ALL, show_mount);
admin_send_response (doc, client, response, filename);
xmlFreeDoc(doc);
}

View File

@ -108,6 +108,8 @@ static void htpasswd_recheckfile (htpasswd_auth_state *htpasswd)
char *sep;
char line [MAX_LINE_LEN];
if (htpasswd->filename == NULL)
return;
if (stat (htpasswd->filename, &file_stat) < 0)
{
WARN1 ("failed to check status of %s", htpasswd->filename);

View File

@ -132,6 +132,14 @@ struct _listener_t
int ssl;
};
typedef struct
{
char *hostname;
int port;
char *username;
char *password;
} ice_master_details;
typedef struct ice_config_tag
{
char *config_filename;
@ -169,6 +177,8 @@ typedef struct ice_config_tag
listener_t *listen_sock;
unsigned int listen_sock_count;
ice_master_details *master;
char *master_server;
int master_server_port;
int master_update_interval;

View File

@ -1129,7 +1129,7 @@ static void _handle_stats_request (client_t *client, char *uri)
client->respcode = 200;
snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
"HTTP/1.0 200 OK\r\n\r\n");
"HTTP/1.0 200 OK\r\ncapability: streamlist\r\n\r\n");
client->refbuf->len = strlen (client->refbuf->data);
fserve_add_client_callback (client, stats_callback, NULL);
}

View File

@ -378,4 +378,3 @@ static int format_prepare_headers (source_t *source, client_t *client)
return 0;
}

View File

@ -53,6 +53,7 @@ typedef struct _format_plugin_tag
void (*set_tag)(struct _format_plugin_tag *plugin, const char *tag, const char *value, const char *charset);
void (*free_plugin)(struct _format_plugin_tag *self);
void (*apply_settings)(client_t *client, struct _format_plugin_tag *format, struct _mount_proxy *mount);
int (*get_image)(client_t *client, struct _format_plugin_tag *format);
/* for internal state management */
void *_state;

View File

@ -38,12 +38,12 @@ typedef struct source_tag source_t;
typedef struct _kate_codec_tag
{
int headers_done;
unsigned int headers_done;
#ifdef HAVE_KATE
kate_info ki;
kate_comment kc;
#endif
int num_headers;
unsigned int num_headers;
int granule_shift;
ogg_int64_t last_iframe;
ogg_int64_t prev_granulepos;

View File

@ -484,12 +484,12 @@ static int complete_read (source_t *source)
}
return 0;
}
rate_add (format->in_bitrate, bytes, global.time);
}
source_mp3->read_count += bytes;
refbuf = source_mp3->read_data;
refbuf->len = source_mp3->read_count;
format->read_bytes += bytes;
rate_add (format->in_bitrate, bytes, global.time);
if (source_mp3->read_count < source_mp3->queue_block_size)
{
@ -586,7 +586,6 @@ static refbuf_t *mp3_get_filter_meta (source_t *source)
sizeof (source_mp3->build_metadata));
source_mp3->build_metadata_offset = 0;
source_mp3->build_metadata_len = 1 + (*src * 16);
rate_add (plugin->in_bitrate, source_mp3->build_metadata_len, global.time);
}
/* do we have all of the metatdata block */

View File

@ -54,6 +54,7 @@ static void format_ogg_free_plugin (format_plugin_t *plugin);
static int create_ogg_client_data(source_t *source, client_t *client);
static void free_ogg_client_data (client_t *client);
static int get_image (client_t *client, struct _format_plugin_tag *format);
static void write_ogg_to_file (struct source_tag *source, refbuf_t *refbuf);
static refbuf_t *ogg_get_buffer (source_t *source);
static int write_buf_to_client (client_t *client);
@ -152,8 +153,7 @@ static void free_ogg_codecs (ogg_state_t *ogg_info)
while (codec)
{
ogg_codec_t *next = codec->next;
if (codec->possible_start)
refbuf_release (codec->possible_start);
refbuf_release (codec->possible_start);
codec->codec_free (ogg_info, codec);
codec = next;
}
@ -177,6 +177,7 @@ int format_ogg_get_plugin (source_t *source)
plugin->write_buf_to_file = write_ogg_to_file;
plugin->create_client_data = create_ogg_client_data;
plugin->free_plugin = format_ogg_free_plugin;
plugin->get_image = get_image;
plugin->set_tag = NULL;
plugin->apply_settings = apply_ogg_settings;
if (strcmp (httpp_getvar (source->parser, "content-type"), "application/x-ogg") == 0)
@ -623,4 +624,25 @@ static void write_ogg_to_file (struct source_tag *source, refbuf_t *refbuf)
write_ogg_data (source, refbuf);
}
static int get_image (client_t *client, struct _format_plugin_tag *format)
{
const char *serialp = httpp_get_query_param (client->parser, "serial");
ogg_state_t *ogg_info = format->_state;
ogg_codec_t *codec = ogg_info->codecs;
long serial;
if (serialp)
serial = atoll (serialp);
while (codec)
{
if (serialp == NULL || serial == codec->os.serialno)
{
int ret = 0;
if (codec->get_image)
ret = codec->get_image (client, codec);
return ret;
}
codec = codec->next;
}
return 0;
}

View File

@ -65,6 +65,7 @@ typedef struct ogg_codec_tag
refbuf_t *(*process_page)(ogg_state_t *ogg_info,
struct ogg_codec_tag *codec, ogg_page *page);
void (*codec_free)(ogg_state_t *ogg_info, struct ogg_codec_tag *codec);
int (*get_image)(client_t *client, struct ogg_codec_tag *codec);
} ogg_codec_t;

View File

@ -31,7 +31,20 @@ typedef struct source_tag source_t;
#define CATMODULE "format-theora"
#include "logging.h"
#ifdef WITH_VIDEO_PREVIEW
#include <png.h>
typedef struct _video_preview_struct
{
png_byte* rgb_image ;
int png_compression_level ;
int video_width ;
int video_height ;
int x_crop_offset ;
int y_crop_offset ;
} video_preview_t;
#endif
typedef struct _theora_codec_tag
{
@ -40,9 +53,255 @@ typedef struct _theora_codec_tag
int granule_shift;
ogg_int64_t last_iframe;
ogg_int64_t prev_granulepos;
#ifdef WITH_VIDEO_PREVIEW
theora_state td;
video_preview_t *video_preview;
int frame_count;
#endif
} theora_codec_t;
/* video_preview.c
* Copyright 2005, Silvano Galliani aka kysucix <kysucix@dyne.org>
*/
#include "logging.h"
#ifdef WITH_VIDEO_PREVIEW
struct preview_details
{
unsigned int total_length;
refbuf_t **last;
};
static void yuv2rgb (yuv_buffer *_yuv, video_preview_t *video_preview);
static int clip (int x);
static void user_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
{
#define BUFFER_BLOCK_SZ 316*1024
struct preview_details *details = png_get_io_ptr (png_ptr);
unsigned int offset = 0;
int c = 0;
if (*details->last == NULL)
{
/* special case */
refbuf_t *r = refbuf_new (BUFFER_BLOCK_SZ);
r->len = 0;
*details->last = r;
c++;
}
while (length)
{
unsigned int amount;
refbuf_t *buffer = *details->last;
if (buffer->len == BUFFER_BLOCK_SZ)
{
refbuf_t *last = buffer;
buffer = refbuf_new (BUFFER_BLOCK_SZ);
buffer->len = 0;
last->next = buffer;
details->last = &last->next;
c++;
}
amount = BUFFER_BLOCK_SZ - buffer->len;
if (amount > length)
amount = length;
memcpy (buffer->data+buffer->len, data+offset, amount);
buffer->len += amount;
offset += amount;
length -= amount;
}
details->total_length += offset;
}
static void user_flush_data (png_structp png_ptr)
{
}
static void user_error (png_structp png_ptr, png_const_charp c)
{
longjmp (png_ptr->jmpbuf, 1);
}
void free_video_preview (video_preview_t *video_preview)
{
DEBUG0 ("freeing video preview");
free (video_preview->rgb_image);
free (video_preview);
}
video_preview_t *init_video_preview (int width, int height, int _x_crop_offset, int _y_crop_offset)
{
DEBUG0("init video preview");
video_preview_t *video_preview = calloc (1, sizeof (video_preview_t));
/* init structure */
video_preview -> rgb_image = NULL;
video_preview -> png_compression_level = Z_BEST_SPEED;
video_preview -> video_width = width;
video_preview -> video_height = height;
video_preview -> x_crop_offset = _x_crop_offset;
video_preview -> y_crop_offset = _y_crop_offset;
/* malloc rgb image */
video_preview -> rgb_image = (png_byte *)calloc (1, video_preview -> video_width * video_preview -> video_height * 4 );
if (video_preview->rgb_image == NULL)
{
ERROR0 ("Can't allocate memory for rgb_image");
free_video_preview (video_preview);
return NULL;
}
return video_preview;
}
static int write_video_preview (client_t *client, video_preview_t *video_preview)
{
int i;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
struct preview_details preview;
preview.total_length = 0;
preview.last = &client->refbuf->next;
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
if (png_ptr == NULL)
return -1;
info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL)
{
png_destroy_write_struct (&png_ptr, (png_infopp)NULL);
return -1;
}
if (setjmp (png_ptr->jmpbuf))
{
png_destroy_write_struct (&png_ptr, (png_infopp)NULL);
return -1;
}
png_set_error_fn (png_ptr, NULL, user_error, user_error);
png_set_write_fn (png_ptr, &preview, user_write_data, user_flush_data);
png_set_filter( png_ptr, 0, PNG_FILTER_NONE );
/* set the zlib compression level */
png_set_compression_level (png_ptr, video_preview->png_compression_level);
png_set_IHDR (png_ptr, info_ptr, video_preview->video_width , video_preview->video_height,
8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info (png_ptr, info_ptr);
ERROR0("finished writing png header");
/* write image to hard disk */
for ( i = 0; i < video_preview -> video_height; i++)
png_write_row (png_ptr,
video_preview->rgb_image + i * (video_preview->video_width) * 4 );
png_write_end (png_ptr, info_ptr);
png_destroy_write_struct (&png_ptr, &info_ptr);
snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE, "HTTP/1.0 200 OK\r\n"
"Content-Length: %d\r\nContentType: image/png\r\n\r\n", preview.total_length);
client->refbuf->len = strlen (client->refbuf->data);
client->respcode = 200;
return 0;
}
static int get_image (client_t *client, struct ogg_codec_tag *codec)
{
theora_codec_t *theora = codec->specific;
return write_video_preview (client, theora->video_preview);
}
/* ok it has to be optimized but for now it's clean, and it's ok ;) */
static void yuv2rgb (yuv_buffer *_yuv, video_preview_t *video_preview)
{
int i,j;
int crop_offset;
int y_offset;
int ypp_offset;
int uv_offset;
/* rgba surface pointer */
unsigned char *prgb;
yuv_buffer *yuv;
unsigned char y;
unsigned char ypp;
unsigned char u;
unsigned char v;
yuv = _yuv;
crop_offset = (video_preview -> x_crop_offset) +
(yuv -> y_stride) * (video_preview -> y_crop_offset);
prgb = (unsigned char *)video_preview -> rgb_image;
for (i = 0; i < video_preview -> video_height; i++ ) {
for ( j = 0; j < video_preview -> video_width / 2; j++ ) {
y_offset = yuv -> y_stride * i + j*2 + crop_offset;
ypp_offset = yuv -> y_stride * i + j*2 + crop_offset + 1;
uv_offset = yuv -> uv_stride * (i/2) + j + crop_offset;
y = *(yuv->y + y_offset);
ypp = *(yuv->y + ypp_offset);
u = *(yuv->u + uv_offset);
v = *(yuv->v + uv_offset);
/* R G B A */
*prgb = clip (y + 1.402f * (v-128)) ;
prgb++;
*prgb = clip (y - 0.34414f * (u-128) - 0.71414f * (v-128)) ;
prgb++;
*prgb = clip (y + 1.772 * (u-128)) ;
prgb++;
*prgb = 255;
prgb++;
/* R G B A */
*prgb = clip (ypp + 1.402f * (v-128)) ;
prgb++;
*prgb = clip (ypp - 0.34414f * (u-128) - 0.71414f * (v-128)) ;
prgb++;
*prgb = clip (ypp + 1.772 * (u-128)) ;
prgb++;
*prgb = 255;
prgb++;
}
}
}
static int clip (int x)
{
if (x > 255)
return 255;
else if (x < 0)
return 0;
return x;
}
#endif
static void theora_codec_free (ogg_state_t *ogg_info, ogg_codec_t *codec)
{
theora_codec_t *theora = codec->specific;
@ -52,6 +311,14 @@ static void theora_codec_free (ogg_state_t *ogg_info, ogg_codec_t *codec)
stats_event (ogg_info->mount, "video_quality", NULL);
stats_event (ogg_info->mount, "frame_rate", NULL);
stats_event (ogg_info->mount, "frame_size", NULL);
#ifdef WITH_VIDEO_PREVIEW
stats_event (ogg_info->mount, "video_preview", NULL);
if (theora->video_preview)
{
free_video_preview (theora->video_preview);
theora_clear (&theora->td);
}
#endif
theora_info_clear (&theora->ti);
theora_comment_clear (&theora->tc);
ogg_stream_clear (&codec->os);
@ -113,7 +380,30 @@ static refbuf_t *process_theora_page (ogg_state_t *ogg_info, ogg_codec_t *codec,
return NULL;
}
if (theora_packet_iskeyframe (&packet))
{
has_keyframe = 1;
#ifdef WITH_VIDEO_PREVIEW
if (theora->video_preview)
{
if (theora->frame_count == -1)
{
theora_decode_init (&theora->td, &theora->ti);
theora->frame_count = 0;
}
if (theora->frame_count % 16)
theora->frame_count++;
else
{
yuv_buffer yuv;
theora_decode_packetin (&theora->td, &packet);
theora_decode_YUVout (&theora->td, &yuv);
yuv2rgb (&yuv, theora->video_preview);
theora->frame_count = 1;
}
}
#endif
}
}
if (header_page)
{
@ -126,8 +416,7 @@ static refbuf_t *process_theora_page (ogg_state_t *ogg_info, ogg_codec_t *codec,
if (granulepos != theora->prev_granulepos || granulepos == 0)
{
if (codec->possible_start)
refbuf_release (codec->possible_start);
refbuf_release (codec->possible_start);
refbuf_addref (refbuf);
codec->possible_start = refbuf;
}
@ -182,6 +471,20 @@ ogg_codec_t *initial_theora_page (format_plugin_t *plugin, ogg_page *page)
codec->filtered = 1;
codec->name = "Theora";
#ifdef WITH_VIDEO_PREVIEW
/* check for video_preview config and video_preview initialization */
if (1)
{
theora_info *ti = &theora_codec->ti;
theora_codec->video_preview = init_video_preview (ti->width, ti->height, ti->offset_x, ti->offset_y);
theora_codec->frame_count = -1;
codec->get_image = get_image;
stats_event_args (ogg_info->mount, "video_preview", "/admin/showimage?mount=%s&serial=%ld", ogg_info->mount, codec->os.serialno);
//theora_decode_init (&theora_codec->td, &theora_codec->ti);
// theora_codec->frame_count = -1;
}
#endif
format_ogg_attach_header (codec, page);
if (codec->filtered == 0)
ogg_info->codec_sync = codec;

View File

@ -296,8 +296,9 @@ static void *fserv_thread_function(void *arg)
client_tree_changed = 1;
continue;
}
client_set_queue (client, refbuf->next);
refbuf = client->refbuf;
refbuf = refbuf->next;
refbuf_release (client->refbuf);
client->refbuf = refbuf;
bytes = refbuf->len;
}
refbuf->len = bytes;

View File

@ -45,8 +45,7 @@ void global_initialize(void)
global.source_tree = avl_tree_new(source_compare_sources, NULL);
thread_mutex_create("global", &_global_mutex);
thread_spin_create ("xyz", &global.spinlock);
/* do a sampling based on 1/10ths of a second */
global.out_bitrate = rate_setup (60);
global.out_bitrate = rate_setup (151, 1000);
}
void global_shutdown(void)
@ -70,10 +69,8 @@ void global_unlock(void)
void global_add_bitrates (struct rate_calc *rate, unsigned long value)
{
time_t t = (time_t)(global.time_ms/100);
thread_spin_lock (&global.spinlock);
rate_add (rate, value, t);
rate_add (rate, value, global.time_ms);
thread_spin_unlock (&global.spinlock);
}
@ -88,7 +85,7 @@ unsigned long global_getrate_avg (struct rate_calc *rate)
{
unsigned long v;
thread_spin_lock (&global.spinlock);
v = rate_avg (rate)*10L;
v = rate_avg (rate);
thread_spin_unlock (&global.spinlock);
return v;
}

View File

@ -35,7 +35,7 @@ void refbuf_shutdown(void)
{
}
refbuf_t *refbuf_new(size_t size)
refbuf_t *refbuf_new (unsigned int size)
{
refbuf_t *refbuf;

View File

@ -35,7 +35,7 @@ typedef struct _refbuf_tag
void refbuf_initialize(void);
void refbuf_shutdown(void);
refbuf_t *refbuf_new(size_t size);
refbuf_t *refbuf_new(unsigned int size);
void refbuf_addref(refbuf_t *self);
void refbuf_release(refbuf_t *self);

View File

@ -1075,12 +1075,17 @@ static void *_slave_thread(void *arg)
update_from_master (config);
thread_mutex_lock (&(config_locks()->relay_lock));
cleanup_relays = update_relays (&global.relays, config->relay);
config_release_config();
}
else
thread_mutex_lock (&(config_locks()->relay_lock));
relay_check_streams (global.relays, cleanup_relays, skip_timer);
relay_check_streams (global.master_relays, NULL, skip_timer);
thread_mutex_unlock (&(config_locks()->relay_lock));
if (update_settings)
{

View File

@ -254,6 +254,8 @@ void source_clear_source (source_t *source)
{
refbuf_t *to_go = p;
p = to_go->next;
if (to_go->_count > 1)
WARN1 ("buffer is %d", to_go->_count);
refbuf_release (to_go);
}
/* the source holds 2 references on the very latest so that one
@ -434,9 +436,9 @@ static void update_source_stats (source_t *source)
unsigned long kbytes_read = source->bytes_read_since_update/1024;
source->format->sent_bytes += kbytes_sent*1024;
stats_event_args (source->mount, "outgoing_bitrate", "%ld",
stats_event_args (source->mount, "outgoing_kbitrate", "%ld",
(8 * rate_avg (source->format->out_bitrate))/1000);
stats_event_args (source->mount, "incoming_bitrate", "%ld", incoming_rate/1000);
stats_event_args (source->mount, "incoming_bitrate", "%ld", incoming_rate);
stats_event_args (source->mount, "total_bytes_read",
"%"PRIu64, source->format->read_bytes);
stats_event_args (source->mount, "total_bytes_sent",
@ -682,7 +684,7 @@ static int send_to_listener (source_t *source, client_t *client, int deletion_ex
total_written += bytes;
}
rate_add (source->format->out_bitrate, total_written, global.time);
rate_add (source->format->out_bitrate, total_written, global.time_ms);
source->bytes_sent_since_update += total_written;
global_add_bitrates (global.out_bitrate, total_written);
@ -778,7 +780,7 @@ static void process_listeners (source_t *source, int fast_clients_only, int dele
}
stats_event_args (source->mount, "listeners", "%lu", source->listeners);
if (source->listeners == 0)
rate_add (source->format->out_bitrate, 0, 0);
rate_reduce (source->format->out_bitrate, 0);
/* change of listener numbers, so reduce scope of global sampling */
global_reduce_bitrate_sampling (global.out_bitrate);
/* do we need to shutdown an on-demand relay */
@ -874,8 +876,8 @@ static void source_init (source_t *source)
thread_mutex_lock (&source->lock);
source->format->in_bitrate = rate_setup (source->avg_bitrate_duration+1);
source->format->out_bitrate = rate_setup (source->avg_bitrate_duration+1);
source->format->in_bitrate = rate_setup (source->avg_bitrate_duration+1, 1);
source->format->out_bitrate = rate_setup (120, 1000);
source->running = 1;
}
@ -1212,10 +1214,17 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
source->avg_bitrate_duration = 60;
/* needs a better mechanism, probably via a client_t handle */
free (source->dumpfilename);
source->dumpfilename = NULL;
if (mountinfo && mountinfo->dumpfile)
{
free (source->dumpfilename);
source->dumpfilename = strdup (mountinfo->dumpfile);
time_t now = time(NULL);
struct tm local;
char buffer[PATH_MAX];
localtime_r (&now, &local);
strftime (buffer, sizeof (buffer), mountinfo->dumpfile, &local);
source->dumpfilename = strdup (buffer);
}
/* handle changes in intro file setting */
if (source->intro_file)
@ -1268,7 +1277,7 @@ void source_update_settings (ice_config_t *config, source_t *source, mount_proxy
/* skip if source is a fallback to file */
if (source->running && source->client == NULL)
{
stats_event_hidden (source->mount, NULL, 1);
stats_event_hidden (source->mount, NULL, NULL, STATS_HIDDEN);
return;
}
/* set global settings first */
@ -1294,13 +1303,6 @@ void source_update_settings (ice_config_t *config, source_t *source, mount_proxy
if (mountinfo)
{
if (mountinfo->hidden)
{
stats_event_hidden (source->mount, NULL, 1);
DEBUG0 ("hidden from public");
}
else
stats_event_hidden (source->mount, NULL, 0);
if (mountinfo->on_connect)
DEBUG1 ("connect script \"%s\"", mountinfo->on_connect);
if (mountinfo->on_disconnect)
@ -1309,12 +1311,21 @@ void source_update_settings (ice_config_t *config, source_t *source, mount_proxy
DEBUG1 ("fallback_when_full to %u", mountinfo->fallback_when_full);
DEBUG1 ("max listeners to %d", mountinfo->max_listeners);
stats_event_args (source->mount, "max_listeners", "%d", mountinfo->max_listeners);
stats_event_hidden (source->mount, "cluster_password", mountinfo->cluster_password, STATS_SLAVE);
if (mountinfo->hidden)
{
stats_event_hidden (source->mount, NULL, NULL, STATS_HIDDEN);
DEBUG0 ("hidden from public");
}
else
stats_event_hidden (source->mount, NULL, NULL, STATS_PUBLIC);
}
else
{
DEBUG0 ("max listeners is not specified");
stats_event (source->mount, "max_listeners", "unlimited");
stats_event_hidden (source->mount, NULL, 0);
stats_event_hidden (source->mount, "cluster_password", NULL, STATS_SLAVE);
stats_event_hidden (source->mount, NULL, NULL, STATS_PUBLIC);
}
DEBUG1 ("public set to %d", source->yp_public);
DEBUG1 ("queue size to %u", source->queue_size_limit);
@ -1459,7 +1470,7 @@ static void *source_fallback_file (void *arg)
httpp_setvar (parser, "content-type", type);
free (type);
stats_event_hidden (source->mount, NULL, 1);
stats_event_hidden (source->mount, NULL, NULL, STATS_HIDDEN);
source->yp_public = 0;
source->intro_file = file;
source->parser = parser;
@ -1522,7 +1533,7 @@ void source_recheck_mounts (int update_all)
}
else if (update_all)
{
stats_event_hidden (mount->mountname, NULL, mount->hidden);
stats_event_hidden (mount->mountname, NULL, NULL, mount->hidden?STATS_HIDDEN:0);
stats_event_args (mount->mountname, "listenurl", "http://%s:%d%s",
config->hostname, config->port, mount->mountname);
stats_event (mount->mountname, "listeners", "0");

File diff suppressed because it is too large Load Diff

View File

@ -21,36 +21,17 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
typedef struct _stats_tag
{
avl_tree *global_tree;
/* global stats
start_time
total_users
max_users
total_sources
max_sources
total_user_connections
total_source_connections
*/
avl_tree *source_tree;
/* stats by source, and for stats
start_time
total_users
max_users
*/
} stats_t;
#define STATS_HIDDEN 1
#define STATS_SLAVE 2
#define STATS_GENERAL 4
#define STATS_COUNTERS 8
#define STATS_PUBLIC (STATS_GENERAL|STATS_COUNTERS)
#define STATS_ALL ~0
void stats_initialize(void);
void stats_shutdown(void);
void stats_global(ice_config_t *config);
stats_t *stats_get_stats(void);
void stats_get_streamlist (char *buffer, size_t remaining);
refbuf_t *stats_get_streams (int prepend);
void stats_clear_virtual_mounts (void);
@ -63,11 +44,11 @@ void stats_event_inc(const char *source, const char *name);
void stats_event_add(const char *source, const char *name, unsigned long value);
void stats_event_sub(const char *source, const char *name, unsigned long value);
void stats_event_dec(const char *source, const char *name);
void stats_event_hidden (const char *source, const char *name, int hidden);
void stats_event_hidden (const char *source, const char *name, const char *value, int hidden);
void stats_event_time (const char *mount, const char *name);
void *stats_connection(void *arg);
void stats_callback (client_t *client, void *notused);
void stats_callback (client_t *client, void *mount);
void stats_global_calc(void);
void stats_transform_xslt(client_t *client, const char *uri);

View File

@ -47,18 +47,18 @@
struct rate_calc_node
{
time_t time;
uint64_t index;
long value;
struct rate_calc_node *next, *prev;
struct rate_calc_node *next;
};
struct rate_calc
{
uint64_t total;
unsigned int seconds;
unsigned int blocks;
unsigned int recalc_total;
struct rate_calc_node *current;
unsigned int samples;
unsigned int ssec;
unsigned int blocks;
};
@ -695,102 +695,90 @@ char *util_conv_string (const char *string, const char *in_charset, const char *
/* setup a rate block of so many seconds, so that an average can be
* determined of that range
*/
struct rate_calc *rate_setup (unsigned int seconds)
struct rate_calc *rate_setup (unsigned int samples, unsigned int ssec)
{
struct rate_calc *calc = calloc (1, sizeof (struct rate_calc));
struct rate_calc_node *start = NULL;
unsigned int i;
if (calc == NULL || seconds == 0)
if (calc == NULL || samples < 2 || ssec == 0)
{
free (calc);
return NULL;
}
for (i=0 ; i<seconds; i++)
{
struct rate_calc_node *node = calloc (1, sizeof (*node));
if (calc->current)
{
calc->current->next = node;
node->next = start;
}
else
start = node;
node->prev = calc->current;
calc->current = node;
}
calc->current->next = start;
start->prev = calc->current;
calc->seconds = seconds;
calc->samples = samples;
calc->ssec = ssec;
return calc;
}
/* */
static void rate_recalc_total (struct rate_calc *calc)
{
int i;
struct rate_calc_node *p = calc->current->prev;
calc->total = 0;
for (i=calc->blocks-1; i; i--)
{
calc->total += p->value;
p = p->prev;
}
}
/* add a value to sampled data, t is used to determine which sample
* block the sample goes into.
*/
void rate_add (struct rate_calc *calc, long value, time_t t)
void rate_add (struct rate_calc *calc, long value, uint64_t sid)
{
if (t == 0)
if (calc->current == NULL || sid != calc->current->index)
{
calc->blocks = 0;
return;
}
if (t != calc->current->time)
{
if (calc->recalc_total)
if (calc->blocks == calc->samples)
{
/* here we keep the number of blocks and recalculate the total */
calc->total += calc->current->value;
calc->current = calc->current->next;
rate_recalc_total (calc);
calc->recalc_total--;
calc->total -= calc->current->value;
calc->current->value = value;
calc->current->index = sid;
return;
}
else
{
/* common case */
calc->total += calc->current->value;
calc->current = calc->current->next;
if (calc->blocks == calc->seconds)
calc->total -= calc->current->value;
struct rate_calc_node *node = calloc (1, sizeof (*node));
node->index = sid;
calc->blocks++;
if (calc->current)
{
node->next = calc->current->next;
calc->current->next = node;
calc->total += calc->current->value;
}
else
calc->blocks++;
{
node->next = node;
}
calc->current = node;
}
calc->current->value = 0;
calc->current->time = t;
}
calc->current->value += value;
}
/* return the average sample value over all the blocks except the
* current one, as that may be incomplete
*/
long rate_avg (struct rate_calc *calc)
{
uint64_t range;
if (calc == NULL || calc->blocks < 2)
return 0;
return (long)(calc->total / (calc->blocks-1));
range = (calc->current->index - calc->current->next->index) / calc->ssec;
if (range < 1)
range = 1;
return (long)(calc->total / range);
}
/* reduce the samples used to calculate average */
void rate_reduce (struct rate_calc *calc, unsigned long count)
void rate_reduce (struct rate_calc *calc, unsigned int count)
{
if (calc && count < calc->blocks && count >= 2)
if (calc && count < calc->blocks)
{
calc->recalc_total = count*2;
calc->blocks = count;
struct rate_calc_node *list = calc->current->next;
for (; calc->blocks > count; calc->blocks--)
{
struct rate_calc_node *to_go = list;
list = to_go->next;
calc->total -= to_go->value;
free (to_go);
}
if (calc->blocks)
calc->current->next = list;
else
calc->current = NULL;
}
}

View File

@ -58,11 +58,11 @@ struct tm *localtime_r (const time_t *timep, struct tm *result);
#endif
char *util_conv_string (const char *string, const char *in_charset, const char *out_charset);
struct rate_calc *rate_setup (unsigned int seconds);
void rate_add (struct rate_calc *calc, long value, time_t t);
struct rate_calc *rate_setup (unsigned int samples, unsigned int ssec);
void rate_add (struct rate_calc *calc, long value, uint64_t t);
long rate_avg (struct rate_calc *calc);
void rate_free (struct rate_calc *calc);
void rate_reduce (struct rate_calc *calc, unsigned long count);
void rate_reduce (struct rate_calc *calc, unsigned int count);
int get_line(FILE *file, char *buf, size_t siz);

View File

@ -925,12 +925,10 @@ void yp_remove (const char *mount)
void yp_touch (const char *mount)
{
struct yp_server *server = (struct yp_server *)active_yps;
time_t trigger;
ypdata_t *search_list = NULL;
thread_rwlock_rlock (&yp_lock);
/* do update in 3 secs, give stats chance to update */
trigger = time(NULL) + 3;
if (server)
search_list = server->mounts;
@ -945,9 +943,9 @@ void yp_touch (const char *mount)
search_list = yp->next;
continue;
}
/* only force if touch */
if (yp->process == do_yp_touch)
yp->next_update = trigger;
/* don't update the directory if there is a touch scheduled soon */
if (yp->process == do_yp_touch && now + yp->touch_interval - yp->next_update > 60)
yp->next_update = now;
}
server = server->next;
if (server)

View File

@ -79,6 +79,17 @@
<xsl:if test="server_url">
<tr><td>Stream URL:</td><td class="streamdata"> <a target="_blank" href="{server_url}"><xsl:value-of select="server_url" /></a></td></tr>
</xsl:if>
<xsl:if test="video_preview">
<xsl:choose>
<xsl:when test="authenticator">
<tr><td>Preview:</td><td class="videopreview"> <a href="auth.xsl"><img src="{video_preview}" border="1" align="left" height="400" width="300" alt="frame preview" title="click to start watching the video!" /></a></td></tr>
</xsl:when>
<xsl:otherwise>
<tr><td>Preview:</td><td class="videopreview"> <a href="{@mount}.m3u"><img src="{video_preview}" border="1" align="left" height="200" alt="frame preview" title="click to start watching the video!" /></a></td></tr>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<tr><td>Current Song:</td><td class="streamdata">
<xsl:if test="artist"><xsl:value-of select="artist" /> - </xsl:if><xsl:value-of select="title" /></td></tr>
</table>

View File

@ -363,10 +363,6 @@ SOURCE=..\src\md5.h
# End Source File
# Begin Source File
SOURCE=..\src\os.h
# End Source File
# Begin Source File
SOURCE=..\src\refbuf.h
# End Source File
# Begin Source File

View File

@ -3,7 +3,7 @@
[Setup]
AppName=Icecast2-KH
AppVerName=Icecast v2.3.2-kh1
AppVerName=Icecast v2.3.2-kh2
AppPublisherURL=http://www.icecast.org
AppSupportURL=http://www.icecast.org
AppUpdatesURL=http://www.icecast.org
@ -13,7 +13,7 @@ AllowNoIcons=yes
LicenseFile=..\COPYING
InfoAfterFile=..\README
OutputDir=.
OutputBaseFilename=icecast2_win32_v2.3.2-kh1_setup
OutputBaseFilename=icecast2_win32_v2.3.2-kh2_setup
WizardImageFile=icecast2logo2.bmp
WizardImageStretch=no
; uncomment the following line if you want your installation to run on NT 3.51 too.