[xiph-commits] r14778 - in icecast/trunk/icecast: . src

karl at svn.xiph.org karl at svn.xiph.org
Fri Apr 18 19:11:37 PDT 2008


Author: karl
Date: 2008-04-18 19:11:37 -0700 (Fri, 18 Apr 2008)
New Revision: 14778

Added:
   icecast/trunk/icecast/src/format_kate.c
   icecast/trunk/icecast/src/format_kate.h
   icecast/trunk/icecast/src/format_skeleton.c
   icecast/trunk/icecast/src/format_skeleton.h
Modified:
   icecast/trunk/icecast/configure.in
   icecast/trunk/icecast/src/Makefile.am
   icecast/trunk/icecast/src/format_ogg.c
Log:
Add Kate and Skeleton codecs to ogg handler. patch by ogg.k.ogg.k


Modified: icecast/trunk/icecast/configure.in
===================================================================
--- icecast/trunk/icecast/configure.in	2008-04-19 02:04:17 UTC (rev 14777)
+++ icecast/trunk/icecast/configure.in	2008-04-19 02:11:37 UTC (rev 14778)
@@ -81,6 +81,19 @@
     [ AC_MSG_WARN([Speex support disabled!])
     ])
 
+AC_CHECK_LIB(kate, kate_decode_init,[have_kate=yes],[have_kate=no], -logg)
+if test "x$have_kate" == "xyes"
+then
+  AC_CHECK_LIB(oggkate, kate_ogg_decode_headerin,[have_kate=yes],[have_kate=no],-lkate -logg)
+  if test "x$have_kate" == "xyes"
+  then
+    KATE_LIBS="-loggkate -lkate -logg"
+    AC_DEFINE([HAVE_KATE],[1],[Define if you have libkate])
+  fi
+fi
+dnl we still use format_kate as it doesn't need libkate to work
+#ICECAST_OPTIONAL="$ICECAST_OPTIONAL format_kate.o"
+
 ACX_PTHREAD(, AC_MSG_ERROR([POSIX threads missing]))
 XIPH_VAR_APPEND([XIPH_CFLAGS],[$PTHREAD_CFLAGS])
 XIPH_VAR_APPEND([XIPH_CPPFLAGS],[$PTHREAD_CPPFLAGS])
@@ -133,6 +146,8 @@
 AC_SUBST(CFLAGS)
 AC_SUBST(PROFILE)
 AC_SUBST(ICECAST_OPTIONAL)
+AC_SUBST(HAVE_KATE)
+AC_SUBST(KATE_LIBS)
 
 AC_OUTPUT([Makefile conf/Makefile debian/Makefile src/Makefile src/avl/Makefile
 src/httpp/Makefile src/thread/Makefile src/log/Makefile

Modified: icecast/trunk/icecast/src/Makefile.am
===================================================================
--- icecast/trunk/icecast/src/Makefile.am	2008-04-19 02:04:17 UTC (rev 14777)
+++ icecast/trunk/icecast/src/Makefile.am	2008-04-19 02:11:37 UTC (rev 14778)
@@ -11,23 +11,24 @@
     compat.h fserve.h xslt.h yp.h event.h md5.h \
     auth.h auth_htpasswd.h auth_url.h \
     format.h format_ogg.h format_mp3.h \
-    format_vorbis.h format_theora.h format_flac.h format_speex.h format_midi.h
+    format_vorbis.h format_theora.h format_flac.h format_speex.h format_midi.h \
+    format_kate.h format_skeleton.h
 icecast_SOURCES = cfgfile.c main.c logging.c sighandler.c connection.c global.c \
     util.c slave.c source.c stats.c refbuf.c client.c \
     xslt.c fserve.c event.c admin.c md5.c \
     format.c format_ogg.c format_mp3.c format_midi.c format_flac.c \
-    auth.c auth_htpasswd.c
+    auth.c auth_htpasswd.c format_kate.c format_skeleton.c
 EXTRA_icecast_SOURCES = yp.c \
     auth_url.c \
     format_vorbis.c format_theora.c format_speex.c
-    
+
 icecast_DEPENDENCIES = @ICECAST_OPTIONAL@ net/libicenet.la thread/libicethread.la \
     httpp/libicehttpp.la log/libicelog.la avl/libiceavl.la timing/libicetiming.la
-icecast_LDADD = $(icecast_DEPENDENCIES) @XIPH_LIBS@
+icecast_LDADD = $(icecast_DEPENDENCIES) @XIPH_LIBS@ @KATE_LIBS@
 
 AM_CFLAGS = @XIPH_CFLAGS@
 AM_CPPFLAGS = @XIPH_CPPFLAGS@
-AM_LDFLAGS = @XIPH_LDFLAGS@
+AM_LDFLAGS = @XIPH_LDFLAGS@ @KATE_LIBS@
 
 
 debug:

Added: icecast/trunk/icecast/src/format_kate.c
===================================================================
--- icecast/trunk/icecast/src/format_kate.c	                        (rev 0)
+++ icecast/trunk/icecast/src/format_kate.c	2008-04-19 02:11:37 UTC (rev 14778)
@@ -0,0 +1,232 @@
+/* Icecast
+ *
+ * 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 at xiph.org, 
+ *                      Michael Smith <msmith at xiph.org>,
+ *                      oddsock <oddsock at xiph.org>,
+ *                      Karl Heyes <karl at xiph.org>
+ *                      and others (see AUTHORS for details).
+ */
+
+
+/* Ogg codec handler for kate logical streams */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
+#ifdef HAVE_KATE
+#include <kate/oggkate.h>
+#endif
+
+typedef struct source_tag source_t;
+
+#include "refbuf.h"
+#include "format_ogg.h"
+#include "format_kate.h"
+#include "client.h"
+#include "stats.h"
+
+#define CATMODULE "format-kate"
+#include "logging.h"
+
+
+typedef struct _kate_codec_tag
+{
+    int             headers_done;
+#ifdef HAVE_KATE
+    kate_info       ki;
+    kate_comment    kc;
+#endif
+    int             num_headers;
+    int             granule_shift;
+    ogg_int64_t     last_iframe;
+    ogg_int64_t     prev_granulepos;
+} kate_codec_t;
+
+
+static void kate_codec_free (ogg_state_t *ogg_info, ogg_codec_t *codec)
+{
+    kate_codec_t *kate = codec->specific;
+
+    DEBUG0 ("freeing kate codec");
+    /* TODO: should i replace with something or just remove
+    stats_event (ogg_info->mount, "video_bitrate", NULL);
+    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 HAVE_KATE
+    kate_info_clear (&kate->ki);
+    kate_comment_clear (&kate->kc);
+#endif
+    ogg_stream_clear (&codec->os);
+    free (kate);
+    free (codec);
+}
+
+
+/* kate pages are not rebuilt, so here we just for headers and then
+ * pass them straight through to the the queue
+ */
+static refbuf_t *process_kate_page (ogg_state_t *ogg_info, ogg_codec_t *codec, ogg_page *page)
+{
+    kate_codec_t *kate = codec->specific;
+    ogg_packet packet;
+    int header_page = 0;
+    refbuf_t *refbuf = NULL;
+    ogg_int64_t granulepos;
+
+    if (ogg_stream_pagein (&codec->os, page) < 0)
+    {
+        ogg_info->error = 1;
+        return NULL;
+    }
+    granulepos = ogg_page_granulepos (page);
+
+    while (ogg_stream_packetout (&codec->os, &packet) > 0)
+    {
+        if (!kate->headers_done)
+        {
+#ifdef HAVE_KATE
+            int ret = kate_ogg_decode_headerin (&kate->ki, &kate->kc, &packet);
+            if (ret < 0)
+            {
+                ogg_info->error = 1;
+                WARN0 ("problem with kate header");
+                return NULL;
+            }
+            header_page = 1;
+            kate->num_headers = kate->ki.num_headers;
+            codec->headers++;
+            if (ret > 0)
+            {
+                kate->headers_done = 1;
+                /* TODO: what to replace this with ?
+                ogg_info->bitrate += theora->ti.target_bitrate;
+                stats_event_args (ogg_info->mount, "video_bitrate", "%ld",
+                        (long)theora->ti.target_bitrate);
+                stats_event_args (ogg_info->mount, "video_quality", "%ld",
+                        (long)theora->ti.quality);
+                stats_event_args (ogg_info->mount, "frame_size", "%ld x %ld",
+                        (long)theora->ti.frame_width,
+                        (long)theora->ti.frame_height);
+                stats_event_args (ogg_info->mount, "frame_rate", "%.2f",
+                        (float)theora->ti.fps_numerator/theora->ti.fps_denominator);
+                */
+            }
+            continue;
+#else
+            header_page = (packet.bytes>0 && (packet.packet[0]&0x80));
+            if (!header_page)
+                break;
+            codec->headers++;
+            if (packet.packet[0]==0x80)
+            {
+                if (packet.bytes<64) return NULL;
+                /* we peek for the number of headers to expect */
+                kate->num_headers = packet.packet[11];
+            }
+            continue;
+#endif
+        }
+
+        if (codec->headers < kate->num_headers)
+        {
+            ogg_info->error = 1;
+            ERROR0 ("Not enough header packets");
+            return NULL;
+        }
+    }
+    if (header_page)
+    {
+        format_ogg_attach_header (ogg_info, page);
+        return NULL;
+    }
+
+    refbuf = make_refbuf_with_page (page);
+    /* DEBUG3 ("refbuf %p has pageno %ld, %llu", refbuf, ogg_page_pageno (page), (uint64_t)granulepos); */
+
+    if (codec->possible_start)
+    {
+        /* we don't bother trying to know where we can start, we'll just
+           start whenever we have to, video's more important and in the majority
+           of the cases it's ok if we lose an event we're seeking in the middle
+           of, as we won't have display artifacts as we'd have with video */
+        codec->possible_start->sync_point = 1;
+        refbuf_release (codec->possible_start);
+        codec->possible_start = NULL;
+    }
+    if (granulepos != kate->prev_granulepos || granulepos == 0)
+    {
+        if (codec->possible_start)
+            refbuf_release (codec->possible_start);
+        refbuf_addref (refbuf);
+        codec->possible_start = refbuf;
+    }
+    kate->prev_granulepos = granulepos;
+
+    return refbuf;
+}
+
+
+/* Check if specified BOS page is the start of a kate stream and
+ * if so, create a codec structure for handling it
+ */
+ogg_codec_t *initial_kate_page (format_plugin_t *plugin, ogg_page *page)
+{
+    ogg_state_t *ogg_info = plugin->_state;
+    ogg_codec_t *codec = calloc (1, sizeof (ogg_codec_t));
+    ogg_packet packet;
+
+    kate_codec_t *kate_codec = calloc (1, sizeof (kate_codec_t));
+
+    ogg_stream_init (&codec->os, ogg_page_serialno (page));
+    ogg_stream_pagein (&codec->os, page);
+
+#ifdef HAVE_KATE
+    kate_info_init (&kate_codec->ki);
+    kate_comment_init (&kate_codec->kc);
+#endif
+
+    ogg_stream_packetout (&codec->os, &packet);
+
+    DEBUG0("checking for kate codec");
+#ifdef HAVE_KATE
+    if (kate_ogg_decode_headerin (&kate_codec->ki, &kate_codec->kc, &packet) < 0)
+    {
+        kate_info_clear (&kate_codec->ki);
+        kate_comment_clear (&kate_codec->kc);
+        ogg_stream_clear (&codec->os);
+        free (kate_codec);
+        free (codec);
+        return NULL;
+    }
+#else
+    /* we don't have libkate, so we examine the packet magic by hand */
+    if ((packet.bytes<9) || memcmp(packet.packet, "\x80kate\0\0\0\0", 9))
+    {
+        ogg_stream_clear (&codec->os);
+        free (kate_codec);
+        free (codec);
+        return NULL;
+    }
+#endif
+
+    INFO0 ("seen initial kate header");
+    codec->specific = kate_codec;
+    codec->process_page = process_kate_page;
+    codec->codec_free = kate_codec_free;
+    codec->headers = 1;
+    codec->name = "Kate";
+
+    format_ogg_attach_header (ogg_info, page);
+    ogg_info->codec_sync = codec;
+    return codec;
+}
+

Added: icecast/trunk/icecast/src/format_kate.h
===================================================================
--- icecast/trunk/icecast/src/format_kate.h	                        (rev 0)
+++ icecast/trunk/icecast/src/format_kate.h	2008-04-19 02:11:37 UTC (rev 14778)
@@ -0,0 +1,21 @@
+/* Icecast
+ *
+ * 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 at xiph.org, 
+ *                      Michael Smith <msmith at xiph.org>,
+ *                      oddsock <oddsock at xiph.org>,
+ *                      Karl Heyes <karl at xiph.org>
+ *                      and others (see AUTHORS for details).
+ */
+
+
+#ifndef __FORMAT_KATE_H
+#define __FORMAT_KATE_H
+
+#include "format_ogg.h"
+
+ogg_codec_t *initial_kate_page (format_plugin_t *plugin, ogg_page *page);
+
+#endif /* __FORMAT_KATE_H */

Modified: icecast/trunk/icecast/src/format_ogg.c
===================================================================
--- icecast/trunk/icecast/src/format_ogg.c	2008-04-19 02:04:17 UTC (rev 14777)
+++ icecast/trunk/icecast/src/format_ogg.c	2008-04-19 02:11:37 UTC (rev 14778)
@@ -42,6 +42,8 @@
 #endif
 #include "format_midi.h"
 #include "format_flac.h"
+#include "format_kate.h"
+#include "format_skeleton.h"
 
 #ifdef _WIN32
 #define snprintf _snprintf
@@ -237,6 +239,12 @@
         if (codec)
             break;
 #endif
+        codec = initial_kate_page (plugin, page);
+        if (codec)
+            break;
+        codec = initial_skeleton_page (plugin, page);
+        if (codec)
+            break;
 
         /* any others */
         ERROR0 ("Seen BOS page with unknown type");

Added: icecast/trunk/icecast/src/format_skeleton.c
===================================================================
--- icecast/trunk/icecast/src/format_skeleton.c	                        (rev 0)
+++ icecast/trunk/icecast/src/format_skeleton.c	2008-04-19 02:11:37 UTC (rev 14778)
@@ -0,0 +1,114 @@
+/* Icecast
+ *
+ * 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 at xiph.org, 
+ *                      Michael Smith <msmith at xiph.org>,
+ *                      oddsock <oddsock at xiph.org>,
+ *                      Karl Heyes <karl at xiph.org>
+ *                      and others (see AUTHORS for details).
+ */
+
+
+/* Ogg codec handler for skeleton logical streams */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
+
+typedef struct source_tag source_t;
+
+#include "refbuf.h"
+#include "format_ogg.h"
+#include "format_skeleton.h"
+#include "client.h"
+#include "stats.h"
+
+#define CATMODULE "format-skeleton"
+#include "logging.h"
+
+
+typedef struct _skeleton_codec_tag
+{
+} skeleton_codec_t;
+
+
+static void skeleton_codec_free (ogg_state_t *ogg_info, ogg_codec_t *codec)
+{
+    skeleton_codec_t *skeleton = codec->specific;
+
+    DEBUG0 ("freeing skeleton codec");
+    ogg_stream_clear (&codec->os);
+    free (skeleton);
+    free (codec);
+}
+
+
+/* skeleton pages are not rebuilt, so here we just for headers and then
+ * pass them straight through to the the queue
+ */
+static refbuf_t *process_skeleton_page (ogg_state_t *ogg_info, ogg_codec_t *codec, ogg_page *page)
+{
+    ogg_packet packet;
+
+    if (ogg_stream_pagein (&codec->os, page) < 0)
+    {
+        ogg_info->error = 1;
+        return NULL;
+    }
+
+    while (ogg_stream_packetout (&codec->os, &packet) > 0)
+    {
+        codec->headers++;
+    }
+
+    /* all skeleon packets are headers */
+    format_ogg_attach_header (ogg_info, page);
+    return NULL;
+}
+
+
+/* Check if specified BOS page is the start of a skeleton stream and
+ * if so, create a codec structure for handling it
+ */
+ogg_codec_t *initial_skeleton_page (format_plugin_t *plugin, ogg_page *page)
+{
+    ogg_state_t *ogg_info = plugin->_state;
+    ogg_codec_t *codec = calloc (1, sizeof (ogg_codec_t));
+    ogg_packet packet;
+
+    skeleton_codec_t *skeleton_codec = calloc (1, sizeof (skeleton_codec_t));
+
+    ogg_stream_init (&codec->os, ogg_page_serialno (page));
+    ogg_stream_pagein (&codec->os, page);
+
+
+    ogg_stream_packetout (&codec->os, &packet);
+
+    DEBUG0("checking for skeleton codec");
+
+    if ((packet.bytes<8) || memcmp(packet.packet, "fishead\0", 8))
+    {
+        ogg_stream_clear (&codec->os);
+        free (skeleton_codec);
+        free (codec);
+        return NULL;
+    }
+
+    INFO0 ("seen initial skeleton header");
+    codec->specific = skeleton_codec;
+    codec->process_page = process_skeleton_page;
+    codec->codec_free = skeleton_codec_free;
+    codec->headers = 1;
+    codec->name = "Skeleton";
+
+    format_ogg_attach_header (ogg_info, page);
+    ogg_info->codec_sync = codec;
+    return codec;
+}
+

Added: icecast/trunk/icecast/src/format_skeleton.h
===================================================================
--- icecast/trunk/icecast/src/format_skeleton.h	                        (rev 0)
+++ icecast/trunk/icecast/src/format_skeleton.h	2008-04-19 02:11:37 UTC (rev 14778)
@@ -0,0 +1,21 @@
+/* Icecast
+ *
+ * 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 at xiph.org, 
+ *                      Michael Smith <msmith at xiph.org>,
+ *                      oddsock <oddsock at xiph.org>,
+ *                      Karl Heyes <karl at xiph.org>
+ *                      and others (see AUTHORS for details).
+ */
+
+
+#ifndef __FORMAT_SKELETON_H
+#define __FORMAT_SKELETON_H
+
+#include "format_ogg.h"
+
+ogg_codec_t *initial_skeleton_page (format_plugin_t *plugin, ogg_page *page);
+
+#endif /* __FORMAT_SKELETON_H */



More information about the commits mailing list