From 0fce619138a38b19c58b68ed8e585ac50bca49df Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 24 May 2012 16:04:27 +0000 Subject: [PATCH] Add opus support. This is David Richards' support patch for Ogg encapsulated Opus streams. From https://github.com/krad-radio/icecast-oneman/commit/35927ca52f8e538eb20d8a185b8c10f1f2e9118a svn path=/icecast/branches/icecast-webm/; revision=18302 --- src/Makefile.am | 4 +-- src/format_ogg.c | 4 +++ src/format_opus.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++ src/format_opus.h | 21 +++++++++++ 4 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/format_opus.c create mode 100644 src/format_opus.h diff --git a/src/Makefile.am b/src/Makefile.am index 3ed529e1..e790f55b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,14 +10,14 @@ noinst_HEADERS = admin.h cfgfile.h logging.h sighandler.h connection.h \ global.h util.h slave.h source.h stats.h refbuf.h client.h \ 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_ebml.h\ + format.h format_ogg.h format_mp3.h format_ebml.h format_opus.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 format_ebml.c\ - auth.c auth_htpasswd.c format_kate.c format_skeleton.c + auth.c auth_htpasswd.c format_kate.c format_skeleton.c format_opus.c EXTRA_icecast_SOURCES = yp.c \ auth_url.c \ format_vorbis.c format_theora.c format_speex.c diff --git a/src/format_ogg.c b/src/format_ogg.c index b7c8b658..45eea359 100644 --- a/src/format_ogg.c +++ b/src/format_ogg.c @@ -40,6 +40,7 @@ #ifdef HAVE_SPEEX #include "format_speex.h" #endif +#include "format_opus.h" #include "format_midi.h" #include "format_flac.h" #include "format_kate.h" @@ -246,6 +247,9 @@ static int process_initial_page (format_plugin_t *plugin, ogg_page *page) if (codec) break; codec = initial_skeleton_page (plugin, page); + if (codec) + break; + codec = initial_opus_page (plugin, page); if (codec) break; diff --git a/src/format_opus.c b/src/format_opus.c new file mode 100644 index 00000000..acc90288 --- /dev/null +++ b/src/format_opus.c @@ -0,0 +1,88 @@ +/* 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 , + * Michael Smith , + * oddsock , + * Karl Heyes + * and others (see AUTHORS for details). + */ + + +/* Ogg codec handler for opus streams */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +typedef struct source_tag source_t; + +#include "format_opus.h" +#include "refbuf.h" +#include "client.h" + +#define CATMODULE "format-opus" +#include "logging.h" + +static void opus_codec_free (ogg_state_t *ogg_info, ogg_codec_t *codec) +{ + ogg_stream_clear (&codec->os); + free (codec); +} + + +static refbuf_t *process_opus_page (ogg_state_t *ogg_info, + ogg_codec_t *codec, ogg_page *page) +{ + refbuf_t *refbuf; + + if (codec->headers < 2) + { + ogg_packet packet; + + ogg_stream_pagein (&codec->os, page); + while (ogg_stream_packetout (&codec->os, &packet) > 0) + { + /* first time around (normal case) yields comments */ + codec->headers++; + } + /* add header page to associated list */ + format_ogg_attach_header (ogg_info, page); + return NULL; + } + refbuf = make_refbuf_with_page (page); + return refbuf; +} + + +ogg_codec_t *initial_opus_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; + + ogg_stream_init (&codec->os, ogg_page_serialno (page)); + ogg_stream_pagein (&codec->os, page); + + ogg_stream_packetout (&codec->os, &packet); + + DEBUG0("checking for opus codec"); + if (strncmp((char *)packet.packet, "OpusHead", 8) != 0) + { + ogg_stream_clear (&codec->os); + free (codec); + return NULL; + } + INFO0 ("seen initial opus header"); + codec->process_page = process_opus_page; + codec->codec_free = opus_codec_free; + codec->headers = 1; + format_ogg_attach_header (ogg_info, page); + return codec; +} + diff --git a/src/format_opus.h b/src/format_opus.h new file mode 100644 index 00000000..c268d725 --- /dev/null +++ b/src/format_opus.h @@ -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 , + * oddsock , + * Karl Heyes + * and others (see AUTHORS for details). + */ + + +#ifndef __FORMAT_OPUS_H +#define __FORMAT_OPUS_H + +#include "format_ogg.h" + +ogg_codec_t *initial_opus_page (format_plugin_t *plugin, ogg_page *page); + +#endif /* __FORMAT_OPUS_H */