vorbisdec: also support ivorbis tremor decoder
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Mon, 15 Feb 2010 11:09:53 +0000 (12:09 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Mon, 15 Feb 2010 11:11:35 +0000 (12:11 +0100)
... which only needs a bit of refactoring and extracting to support
the minor difference in (i)vorbis interface.

Fixes #609063.

configure.ac
ext/Makefile.am
ext/vorbis/Makefile.am
ext/vorbis/gstivorbisdec.c [new file with mode: 0644]
ext/vorbis/gstvorbisdec.c
ext/vorbis/gstvorbisdec.h
ext/vorbis/gstvorbisdeclib.c [new file with mode: 0644]
ext/vorbis/gstvorbisdeclib.h [new file with mode: 0644]

index 93dbddf99dd8834888e93cfb49744cb113acddb1..ea6f5dfec22ec87d5b7d950698670739b40d5fbd 100644 (file)
@@ -584,6 +584,29 @@ AG_GST_CHECK_FEATURE(GNOME_VFS, [GNOME VFS], gnomevfs, [
     )
 ])
 
+dnl *** ivorbis ***
+dnl AM_PATH_IVORBIS only takes two options
+translit(dnm, m, l) AM_CONDITIONAL(USE_IVORBIS, true)
+AG_GST_CHECK_FEATURE(IVORBIS, [integer vorbis plug-in], ivorbisdec, [
+  AG_GST_PKG_CHECK_MODULES(IVORBIS, vorbisidec)
+  if test $HAVE_IVORBIS = no
+  then
+    IVORBIS_LIBS=
+    IVORBIS_CFLAGS=
+    AC_CHECK_LIB(vorbisidec, vorbis_block_init,
+      [IVORBIS_LIBS=-lvorbisidec
+      HAVE_IVORBIS=yes
+      case $host in
+      arm-*-*)
+        IVORBIS_CFLAGS="-D_ARM_ASSEM_ $IVORBIS_CFLAGS"
+      esac
+      ],
+      HAVE_IVORBIS=no)
+    AC_SUBST(IVORBIS_LIBS)
+    AC_SUBST(IVORBIS_CFLAGS)
+  fi
+])
+
 dnl *** libgio ***
 translit(dnm, m, l) AM_CONDITIONAL(USE_GIO, true)
 AG_GST_CHECK_FEATURE(GIO, [GIO library], gio, [
index 05a603fdb5f1a437b0681196888de90de5df568c..7c006ff72a19497ca9b0ae3f833fa6e757cd8343 100644 (file)
@@ -42,9 +42,17 @@ endif
 
 if USE_VORBIS
 VORBIS_DIR=vorbis
-else
+endif
+
+if USE_IVORBIS
+VORBIS_DIR=vorbis
+endif
+
+if !USE_VORBIS
+if !USE_IVORBIS
 VORBIS_DIR=
 endif
+endif
 
 if USE_THEORA
 THEORA_DIR=theora
index 078eb98e10715571ebe081ff1e2d804206597003..fc285a8d7eb9f333c8d0d9b71fd0aa83894b3e84 100644 (file)
@@ -1,13 +1,17 @@
-plugin_LTLIBRARIES = libgstvorbis.la
+plugin_LTLIBRARIES =
+
+if USE_VORBIS
+plugin_LTLIBRARIES += libgstvorbis.la
 
 libgstvorbis_la_SOURCES = gstvorbis.c \
                          gstvorbisdec.c \
+                         gstvorbisdeclib.c \
                          gstvorbisenc.c \
                          gstvorbisparse.c \
                          gstvorbistag.c \
                          gstvorbiscommon.c
 
-libgstvorbis_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(VORBIS_CFLAGS) 
+libgstvorbis_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(VORBIS_CFLAGS)
 ## AM_PATH_VORBIS also sets VORBISENC_LIBS
 libgstvorbis_la_LIBADD = \
        $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \
@@ -16,9 +20,26 @@ libgstvorbis_la_LIBADD = \
        $(VORBIS_LIBS) $(VORBISENC_LIBS)
 libgstvorbis_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstvorbis_la_LIBTOOLFLAGS = --tag=disable-static
+endif
+
+if USE_IVORBIS
+plugin_LTLIBRARIES += libgstivorbisdec.la
+
+libgstivorbisdec_la_SOURCES = gstivorbisdec.c \
+       gstvorbisdec.c gstvorbisdeclib.c gstvorbiscommon.c
+libgstivorbisdec_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+       -DTREMOR $(IVORBIS_CFLAGS)
+libgstivorbisdec_la_LIBADD = \
+       $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \
+       $(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_MAJORMINOR@.la \
+       $(GST_LIBS) $(IVORBIS_LIBS)
+libgstivorbisdec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstivorbisdec_la_LIBTOOLFLAGS = --tag=disable-static
+endif
 
 noinst_HEADERS = gstvorbisenc.h \
                 gstvorbisdec.h \
+                gstvorbisdeclib.h \
                 gstvorbisparse.h \
                 gstvorbistag.h \
                 gstvorbiscommon.h
diff --git a/ext/vorbis/gstivorbisdec.c b/ext/vorbis/gstivorbisdec.c
new file mode 100644 (file)
index 0000000..5bf9a01
--- /dev/null
@@ -0,0 +1,47 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * 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 Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstvorbisdec.h"
+
+GST_DEBUG_CATEGORY (vorbisdec_debug);
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+
+  /* if tremor is around, there is probably good reason for it, so preferred */
+  if (!gst_element_register (plugin, "ivorbisdec", GST_RANK_PRIMARY + 1,
+          gst_vorbis_dec_get_type ()))
+    return FALSE;
+
+  GST_DEBUG_CATEGORY_INIT (vorbisdec_debug, "ivorbisdec", 0,
+      "vorbis decoding element (integer decoder)");
+
+  return TRUE;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    "ivorbisdec",
+    "Vorbis Tremor decoder",
+    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
index a8a46fa61fa754fe3c2e1abc1da588e9559c2a81..85f36d09221e1ff882f476828f1520b8482c3549 100644 (file)
@@ -52,25 +52,13 @@ GST_DEBUG_CATEGORY_EXTERN (vorbisdec_debug);
 #define GST_CAT_DEFAULT vorbisdec_debug
 
 static const GstElementDetails vorbis_dec_details =
-GST_ELEMENT_DETAILS ("Vorbis audio decoder",
-    "Codec/Decoder/Audio",
-    "decode raw vorbis streams to float audio",
-    "Benjamin Otte <in7y118@public.uni-hamburg.de>");
+    GST_VORBIS_DEC_ELEMENT_DETAILS;
 
 static GstStaticPadTemplate vorbis_dec_src_factory =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("audio/x-raw-float, "
-        "rate = (int) [ 1, MAX ], "
-        "channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, "
-/* no ifdef in macros, please
-#ifdef GST_VORBIS_DEC_SEQUENTIAL
-      "layout = \"sequential\", "
-#endif
-*/
-        "width = (int) 32")
-    );
+    GST_VORBIS_DEC_SRC_CAPS);
 
 static GstStaticPadTemplate vorbis_dec_sink_factory =
 GST_STATIC_PAD_TEMPLATE ("sink",
@@ -79,7 +67,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS ("audio/x-vorbis")
     );
 
-GST_BOILERPLATE (GstVorbisDec, gst_vorbis_dec, GstElement, GST_TYPE_ELEMENT);
+GST_BOILERPLATE (GST_VORBIS_DEC_GLIB_TYPE_NAME, gst_vorbis_dec, GstElement,
+    GST_TYPE_ELEMENT);
 
 static void vorbis_dec_finalize (GObject * object);
 static gboolean vorbis_dec_sink_event (GstPad * pad, GstEvent * event);
@@ -560,6 +549,7 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
 {
   GstCaps *caps;
   const GstAudioChannelPosition *pos = NULL;
+  gint width = GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH;
 
   switch (vd->vi.channels) {
     case 1:
@@ -589,11 +579,24 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
     }
   }
 
-  vd->width = 4;
+  /* negotiate width with downstream */
+  caps = gst_pad_get_allowed_caps (vd->srcpad);
+  if (caps) {
+    if (!gst_caps_is_empty (caps)) {
+      GstStructure *s;
+
+      s = gst_caps_get_structure (caps, 0);
+      /* template ensures 16 or 32 */
+      gst_structure_get_int (s, "width", &width);
+    }
+    gst_caps_unref (caps);
+  }
+  vd->width = width >> 3;
 
   caps = gst_caps_copy (gst_pad_get_pad_template_caps (vd->srcpad));
   gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate,
-      "channels", G_TYPE_INT, vd->vi.channels);
+      "channels", G_TYPE_INT, vd->vi.channels,
+      "width", G_TYPE_INT, width, NULL);
 
   if (pos) {
     gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
@@ -620,8 +623,8 @@ vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
   GST_DEBUG_OBJECT (vd, "parsing comment packet");
 
   buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = packet->packet;
-  GST_BUFFER_SIZE (buf) = packet->bytes;
+  GST_BUFFER_DATA (buf) = gst_ogg_packet_data (packet);
+  GST_BUFFER_SIZE (buf) = gst_ogg_packet_size (packet);
 
   list =
       gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
@@ -738,12 +741,12 @@ vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet)
   GST_DEBUG_OBJECT (vd, "parsing header packet");
 
   /* Packetno = 0 if the first byte is exactly 0x01 */
-  packet->b_o_s = (packet->packet[0] == 0x1) ? 1 : 0;
+  packet->b_o_s = ((gst_ogg_packet_data (packet))[0] == 0x1) ? 1 : 0;
 
   if ((ret = vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet)))
     goto header_read_error;
 
-  switch (packet->packet[0]) {
+  switch ((gst_ogg_packet_data (packet))[0]) {
     case 0x01:
       res = vorbis_handle_identification_packet (vd);
       break;
@@ -770,27 +773,6 @@ header_read_error:
   }
 }
 
-/* These samples can be outside of the float -1.0 -- 1.0 range, this
- * is allowed, downstream elements are supposed to clip */
-static void
-copy_samples (float *out, float **in, guint samples, gint channels)
-{
-  gint i, j;
-
-#ifdef GST_VORBIS_DEC_SEQUENTIAL
-  for (i = 0; i < channels; i++) {
-    memcpy (out, in[i], samples * sizeof (float));
-    out += samples;
-  }
-#else
-  for (j = 0; j < samples; j++) {
-    for (i = 0; i < channels; i++) {
-      *out++ = in[i][j];
-    }
-  }
-#endif
-}
-
 static GstFlowReturn
 vorbis_dec_push_forward (GstVorbisDec * dec, GstBuffer * buf)
 {
@@ -855,7 +837,7 @@ static GstFlowReturn
 vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
     GstClockTime timestamp, GstClockTime duration)
 {
-  float **pcm;
+  vorbis_sample_t **pcm;
   guint sample_count;
   GstBuffer *out;
   GstFlowReturn result;
@@ -899,8 +881,8 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
     goto wrong_samples;
 
   /* copy samples in buffer */
-  copy_samples ((float *) GST_BUFFER_DATA (out), pcm, sample_count,
-      vd->vi.channels);
+  copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm, sample_count,
+      vd->vi.channels, vd->width);
 
   GST_LOG_OBJECT (vd, "setting output size to %d", size);
   GST_BUFFER_SIZE (out) = size;
@@ -952,22 +934,24 @@ wrong_samples:
 static GstFlowReturn
 vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
 {
-  ogg_packet packet;
+  ogg_packet *packet;
+  ogg_packet_wrapper packet_wrapper;
   GstFlowReturn result = GST_FLOW_OK;
 
   /* make ogg_packet out of the buffer */
-  packet.packet = GST_BUFFER_DATA (buffer);
-  packet.bytes = GST_BUFFER_SIZE (buffer);
-  packet.granulepos = -1;
-  packet.packetno = 0;          /* we don't care */
+  gst_ogg_packet_wrapper_from_buffer (&packet_wrapper, buffer);
+  packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
+  /* set some more stuff */
+  packet->granulepos = -1;
+  packet->packetno = 0;         /* we don't care */
   /* EOS does not matter, it is used in vorbis to implement clipping the last
    * block of samples based on the granulepos. We clip based on segments. */
-  packet.e_o_s = 0;
+  packet->e_o_s = 0;
 
-  GST_LOG_OBJECT (vd, "decode buffer of size %ld", packet.bytes);
+  GST_LOG_OBJECT (vd, "decode buffer of size %ld", packet->bytes);
 
   /* error out on empty header packets, but just skip empty data packets */
-  if (G_UNLIKELY (packet.bytes == 0)) {
+  if (G_UNLIKELY (packet->bytes == 0)) {
     if (vd->initialized)
       goto empty_buffer;
     else
@@ -975,19 +959,19 @@ vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
   }
 
   /* switch depending on packet type */
-  if (packet.packet[0] & 1) {
+  if ((gst_ogg_packet_data (packet))[0] & 1) {
     if (vd->initialized) {
       GST_WARNING_OBJECT (vd, "Already initialized, so ignoring header packet");
       goto done;
     }
-    result = vorbis_handle_header_packet (vd, &packet);
+    result = vorbis_handle_header_packet (vd, packet);
   } else {
     GstClockTime timestamp, duration;
 
     timestamp = GST_BUFFER_TIMESTAMP (buffer);
     duration = GST_BUFFER_DURATION (buffer);
 
-    result = vorbis_handle_data_packet (vd, &packet, timestamp, duration);
+    result = vorbis_handle_data_packet (vd, packet, timestamp, duration);
   }
 
 done:
index c4e2d951f4195312d8741d4661a8bccd0d7060fc..1c3ddad36841ca2cdda263807a3d229eafe0ad7d 100644 (file)
@@ -24,7 +24,7 @@
 
 
 #include <gst/gst.h>
-#include <vorbis/codec.h>
+#include "gstvorbisdeclib.h"
 
 G_BEGIN_DECLS
 
diff --git a/ext/vorbis/gstvorbisdeclib.c b/ext/vorbis/gstvorbisdeclib.c
new file mode 100644 (file)
index 0000000..9f3331c
--- /dev/null
@@ -0,0 +1,122 @@
+/* GStreamer
+ * Copyright (C) 2010 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *   Contact: Stefan Kost <stefan.kost@nokia.com>
+ *
+ * Tremor modifications <2006>:
+ *   Chris Lord, OpenedHand Ltd. <chris@openedhand.com>, http://www.o-hand.com/
+ *
+ * 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 Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstvorbisdeclib.h"
+
+#ifndef TREMOR
+/* These samples can be outside of the float -1.0 -- 1.0 range, this
+ * is allowed, downstream elements are supposed to clip */
+void
+copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
+    gint channels, gint width)
+{
+  gint i, j;
+
+  g_assert (width == 4);
+
+#ifdef GST_VORBIS_DEC_SEQUENTIAL
+  for (i = 0; i < channels; i++) {
+    memcpy (out, in[i], samples * sizeof (float));
+    out += samples;
+  }
+#else
+  for (j = 0; j < samples; j++) {
+    for (i = 0; i < channels; i++) {
+      *out++ = in[i][j];
+    }
+  }
+#endif
+}
+
+#else
+
+/* Taken from Tremor, misc.h */
+#ifdef _ARM_ASSEM_
+static inline ogg_int32_t
+CLIP_TO_15 (ogg_int32_t x)
+{
+  int tmp;
+  asm volatile ("subs  %1, %0, #32768\n\t"
+      "movpl   %0, #0x7f00\n\t"
+      "orrpl   %0, %0, #0xff\n"
+      "adds    %1, %0, #32768\n\t"
+      "movmi   %0, #0x8000":"+r" (x), "=r" (tmp)
+      ::"cc");
+
+  return (x);
+}
+#else
+static inline ogg_int32_t
+CLIP_TO_15 (ogg_int32_t x)
+{
+  int ret = x;
+
+  ret -= ((x <= 32767) - 1) & (x - 32767);
+  ret -= ((x >= -32768) - 1) & (x + 32768);
+  return (ret);
+}
+#endif
+
+static void
+copy_samples_32 (gint32 * out, ogg_int32_t ** in, guint samples, gint channels)
+{
+  gint i, j;
+
+  for (j = 0; j < samples; j++) {
+    for (i = 0; i < channels; i++) {
+      *out++ = CLIP_TO_15 (in[i][j] >> 9);
+    }
+  }
+}
+
+static void
+copy_samples_16 (gint16 * out, ogg_int32_t ** in, guint samples, gint channels)
+{
+  gint i, j;
+
+  for (j = 0; j < samples; j++) {
+    for (i = 0; i < channels; i++) {
+      *out++ = CLIP_TO_15 (in[i][j] >> 9);
+    }
+  }
+}
+
+void
+copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
+    gint channels, gint width)
+{
+  if (width == 4) {
+    copy_samples_32 ((gint32 *) out, in, samples, channels);
+  } else if (width == 2) {
+    copy_samples_16 ((gint16 *) out, in, samples, channels);
+  } else {
+    g_assert_not_reached ();
+  }
+}
+
+#endif
diff --git a/ext/vorbis/gstvorbisdeclib.h b/ext/vorbis/gstvorbisdeclib.h
new file mode 100644 (file)
index 0000000..a438fa8
--- /dev/null
@@ -0,0 +1,163 @@
+/* GStreamer
+ * Copyright (C) 2010 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *   Contact: Stefan Kost <stefan.kost@nokia.com>
+ *
+ * Tremor modifications <2006>:
+ *   Chris Lord, OpenedHand Ltd. <chris@openedhand.com>, http://www.o-hand.com/
+ *
+ * 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 Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_VORBIS_DEC_LIB_H__
+#define __GST_VORBIS_DEC_LIB_H__
+
+#include <gst/gst.h>
+
+#ifndef TREMOR
+
+#include <vorbis/codec.h>
+
+typedef float                          vorbis_sample_t;
+typedef ogg_packet                     ogg_packet_wrapper;
+
+#define GST_VORBIS_DEC_ELEMENT_DETAILS \
+GST_ELEMENT_DETAILS ("Vorbis audio decoder",       \
+    "Codec/Decoder/Audio",                         \
+    "decode raw vorbis streams to float audio",    \
+    "Benjamin Otte <in7y118@public.uni-hamburg.de>")
+
+#define GST_VORBIS_DEC_SRC_CAPS \
+    GST_STATIC_CAPS ("audio/x-raw-float, " "rate = (int) [ 1, MAX ], " \
+        "channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, " \
+        "width = (int) 32")
+
+#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH           (32)
+
+#define GST_VORBIS_DEC_GLIB_TYPE_NAME      GstVorbisDec
+
+static inline guint8 *
+gst_ogg_packet_data (ogg_packet * p)
+{
+  return (guint8 *) p->packet;
+}
+
+static inline gint
+gst_ogg_packet_size (ogg_packet * p)
+{
+  return p->bytes;
+}
+
+static inline void
+gst_ogg_packet_wrapper_from_buffer (ogg_packet * packet, GstBuffer * buffer)
+{
+  packet->packet = GST_BUFFER_DATA (buffer);
+  packet->bytes = GST_BUFFER_SIZE (buffer);
+}
+
+static inline ogg_packet *
+gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet)
+{
+  return packet;
+}
+
+#else
+
+#include <tremor/ivorbiscodec.h>
+
+typedef ogg_int32_t                    vorbis_sample_t;
+typedef struct _ogg_packet_wrapper     ogg_packet_wrapper;
+
+struct _ogg_packet_wrapper {
+  ogg_packet          packet;
+  ogg_reference       ref;
+  ogg_buffer          buf;
+};
+
+#define GST_VORBIS_DEC_ELEMENT_DETAILS \
+GST_ELEMENT_DETAILS ("Vorbis audio decoder",           \
+    "Codec/Decoder/Audio",                             \
+    "decode raw vorbis streams to integer audio",      \
+    "Benjamin Otte <in7y118@public.uni-hamburg.de>\n"  \
+    "Chris Lord <chris@openedhand.com>")
+
+#define GST_VORBIS_DEC_SRC_CAPS \
+    GST_STATIC_CAPS ("audio/x-raw-int, "   \
+        "rate = (int) [ 1, MAX ], "        \
+        "channels = (int) [ 1, 6 ], "      \
+        "endianness = (int) BYTE_ORDER, "  \
+        "width = (int) { 16, 32 }, "       \
+        "depth = (int) 16, " "signed = (boolean) true")
+
+#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH           (16)
+
+/* we need a different type name here */
+#define GST_VORBIS_DEC_GLIB_TYPE_NAME      GstIVorbisDec
+
+/* and still have it compile */
+typedef struct _GstVorbisDec               GstIVorbisDec;
+typedef struct _GstVorbisDecClass          GstIVorbisDecClass;
+
+/* compensate minor variation */
+#define vorbis_synthesis(a, b)             vorbis_synthesis (a, b, 1)
+
+static inline guint8 *
+gst_ogg_packet_data (ogg_packet * p)
+{
+  return (guint8 *) p->packet->buffer->data;
+}
+
+static inline gint
+gst_ogg_packet_size (ogg_packet * p)
+{
+  return p->packet->buffer->size;
+}
+
+static inline void
+gst_ogg_packet_wrapper_from_buffer (ogg_packet_wrapper * packet,
+    GstBuffer * buffer)
+{
+  ogg_reference *ref = &packet->ref;
+  ogg_buffer *buf = &packet->buf;
+
+  buf->data = GST_BUFFER_DATA (buffer);
+  buf->size = GST_BUFFER_SIZE (buffer);
+  buf->refcount = 1;
+  buf->ptr.owner = NULL;
+  buf->ptr.next = NULL;
+
+  ref->buffer = buf;
+  ref->begin = 0;
+  ref->length = buf->size;
+  ref->next = NULL;
+
+  packet->packet.packet = ref;
+  packet->packet.bytes = ref->length;
+}
+
+static inline ogg_packet *
+gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet)
+{
+  return &(packet->packet);
+}
+
+#endif
+
+void  copy_samples        (vorbis_sample_t *out, vorbis_sample_t **in,
+                           guint samples, gint channels, gint width);
+
+
+#endif /* __GST_VORBIS_DEC_LIB_H__ */