/* GStreamer
 * Copyright (C) 2005 Michael Smith <msmith@fluendo.com>
 *
 * gstoggparse.c: ogg stream parser
 *
 * 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/* This ogg parser is essentially a subset of the ogg demuxer - rather than
 * fully demuxing into packets, we only parse out the pages, create one
 * GstBuffer per page, set all the appropriate flags on those pages, set caps
 * appropriately (particularly the 'streamheader' which gives all the header
 * pages required for initialing decode).
 *
 * It's dramatically simpler than the full demuxer as it does not  support 
 * seeking.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <ogg/ogg.h>
#include <string.h>

#include "gstogg.h"
#include "gstoggstream.h"

GST_DEBUG_CATEGORY_STATIC (gst_ogg_parse_debug);
#define GST_CAT_DEFAULT gst_ogg_parse_debug

#define GST_TYPE_OGG_PARSE (gst_ogg_parse_get_type())
#define GST_OGG_PARSE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OGG_PARSE, GstOggParse))
#define GST_OGG_PARSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OGG_PARSE, GstOggParse))
#define GST_IS_OGG_PARSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OGG_PARSE))
#define GST_IS_OGG_PARSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OGG_PARSE))

static GType gst_ogg_parse_get_type (void);

typedef struct _GstOggParse GstOggParse;
typedef struct _GstOggParseClass GstOggParseClass;

struct _GstOggParse
{
  GstElement element;

  GstPad *sinkpad;              /* Sink pad we're reading data from */

  GstPad *srcpad;               /* Source pad we're writing to */

  GSList *oggstreams;           /* list of GstOggStreams for known streams */

  gint64 offset;                /* Current stream offset */

  gboolean in_headers;          /* Set if we're reading headers for streams */

  gboolean last_page_not_bos;   /* Set if we've seen a non-BOS page */

  ogg_sync_state sync;          /* Ogg page synchronisation */

  GstCaps *caps;                /* Our src caps */

  GstOggStream *video_stream;   /* Stream used to construct delta_unit flags */
};

struct _GstOggParseClass
{
  GstElementClass parent_class;
};

static void gst_ogg_parse_base_init (gpointer g_class);
static void gst_ogg_parse_class_init (GstOggParseClass * klass);
static void gst_ogg_parse_init (GstOggParse * ogg);
static GstElementClass *parent_class = NULL;

static GType
gst_ogg_parse_get_type (void)
{
  static GType ogg_parse_type = 0;

  if (!ogg_parse_type) {
    static const GTypeInfo ogg_parse_info = {
      sizeof (GstOggParseClass),
      gst_ogg_parse_base_init,
      NULL,
      (GClassInitFunc) gst_ogg_parse_class_init,
      NULL,
      NULL,
      sizeof (GstOggParse),
      0,
      (GInstanceInitFunc) gst_ogg_parse_init,
    };

    ogg_parse_type = g_type_register_static (GST_TYPE_ELEMENT, "GstOggParse",
        &ogg_parse_info, 0);
  }
  return ogg_parse_type;
}

static void
free_stream (GstOggStream * stream)
{
  g_list_foreach (stream->headers, (GFunc) gst_mini_object_unref, NULL);
  g_list_foreach (stream->unknown_pages, (GFunc) gst_mini_object_unref, NULL);
  g_list_foreach (stream->stored_buffers, (GFunc) gst_mini_object_unref, NULL);

  g_slice_free (GstOggStream, stream);
}

static void
gst_ogg_parse_delete_all_streams (GstOggParse * ogg)
{
  g_slist_foreach (ogg->oggstreams, (GFunc) free_stream, NULL);
  g_slist_free (ogg->oggstreams);
  ogg->oggstreams = NULL;
}

static GstOggStream *
gst_ogg_parse_new_stream (GstOggParse * parser, ogg_page * page)
{
  GstOggStream *stream;
  ogg_packet packet;
  int ret;
  guint32 serialno;

  serialno = ogg_page_serialno (page);

  GST_DEBUG_OBJECT (parser, "creating new stream %08x", serialno);

  stream = g_slice_new0 (GstOggStream);

  stream->serialno = serialno;
  stream->in_headers = 1;

  if (ogg_stream_init (&stream->stream, serialno) != 0) {
    GST_ERROR ("Could not initialize ogg_stream struct for serial %08x.",
        serialno);
    return NULL;
  }

  /* FIXME check return */
  ogg_stream_pagein (&stream->stream, page);

  /* FIXME check return */
  ret = ogg_stream_packetout (&stream->stream, &packet);
  if (ret == 1) {
    gst_ogg_stream_setup_map (stream, &packet);
    if (stream->is_video) {
      parser->video_stream = stream;
    }
  }

  parser->oggstreams = g_slist_append (parser->oggstreams, stream);

  return stream;
}

static GstOggStream *
gst_ogg_parse_find_stream (GstOggParse * parser, guint32 serialno)
{
  GSList *l;

  for (l = parser->oggstreams; l != NULL; l = l->next) {
    GstOggStream *stream = (GstOggStream *) l->data;

    if (stream->serialno == serialno)
      return stream;
  }
  return NULL;
}

/* signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  ARG_0
      /* FILL ME */
};

static GstStaticPadTemplate ogg_parse_src_template_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/ogg")
    );

static GstStaticPadTemplate ogg_parse_sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/ogg")
    );

static void gst_ogg_parse_dispose (GObject * object);
static GstStateChangeReturn gst_ogg_parse_change_state (GstElement * element,
    GstStateChange transition);
static GstFlowReturn gst_ogg_parse_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);

static void
gst_ogg_parse_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_set_static_metadata (element_class,
      "Ogg parser", "Codec/Parser",
      "parse ogg streams into pages (info about ogg: http://xiph.org)",
      "Michael Smith <msmith@fluendo.com>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&ogg_parse_sink_template_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&ogg_parse_src_template_factory));
}

static void
gst_ogg_parse_class_init (GstOggParseClass * klass)
{
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  parent_class = g_type_class_peek_parent (klass);

  gstelement_class->change_state = gst_ogg_parse_change_state;

  gobject_class->dispose = gst_ogg_parse_dispose;
}

static void
gst_ogg_parse_init (GstOggParse * ogg)
{
  /* create the sink and source pads */
  ogg->sinkpad =
      gst_pad_new_from_static_template (&ogg_parse_sink_template_factory,
      "sink");
  ogg->srcpad =
      gst_pad_new_from_static_template (&ogg_parse_src_template_factory, "src");

  /* TODO: Are there any events we must handle? */
  /* gst_pad_set_event_function (ogg->sinkpad, gst_ogg_parse_handle_event); */
  gst_pad_set_chain_function (ogg->sinkpad, gst_ogg_parse_chain);

  gst_element_add_pad (GST_ELEMENT (ogg), ogg->sinkpad);
  gst_element_add_pad (GST_ELEMENT (ogg), ogg->srcpad);

  ogg->oggstreams = NULL;
}

static void
gst_ogg_parse_dispose (GObject * object)
{
  GstOggParse *ogg = GST_OGG_PARSE (object);

  GST_LOG_OBJECT (ogg, "Disposing of object %p", ogg);

  ogg_sync_clear (&ogg->sync);
  gst_ogg_parse_delete_all_streams (ogg);

  if (ogg->caps) {
    gst_caps_unref (ogg->caps);
    ogg->caps = NULL;
  }

  if (G_OBJECT_CLASS (parent_class)->dispose)
    G_OBJECT_CLASS (parent_class)->dispose (object);
}

/* submit the given buffer to the ogg sync */
static GstFlowReturn
gst_ogg_parse_submit_buffer (GstOggParse * ogg, GstBuffer * buffer)
{
  gsize size;
  gchar *oggbuffer;
  GstFlowReturn ret = GST_FLOW_OK;

  size = gst_buffer_get_size (buffer);

  GST_DEBUG_OBJECT (ogg, "submitting %" G_GSIZE_FORMAT " bytes", size);
  if (G_UNLIKELY (size == 0))
    goto done;

  oggbuffer = ogg_sync_buffer (&ogg->sync, size);
  if (G_UNLIKELY (oggbuffer == NULL)) {
    GST_ELEMENT_ERROR (ogg, STREAM, DECODE,
        (NULL), ("failed to get ogg sync buffer"));
    ret = GST_FLOW_ERROR;
    goto done;
  }

  size = gst_buffer_extract (buffer, 0, oggbuffer, size);
  if (G_UNLIKELY (ogg_sync_wrote (&ogg->sync, size) < 0)) {
    GST_ELEMENT_ERROR (ogg, STREAM, DECODE, (NULL),
        ("failed to write %" G_GSIZE_FORMAT " bytes to the sync buffer", size));
    ret = GST_FLOW_ERROR;
  }

done:
  gst_buffer_unref (buffer);

  return ret;
}

static void
gst_ogg_parse_append_header (GValue * array, GstBuffer * buf)
{
  GValue value = { 0 };
  /* We require a copy to avoid circular refcounts */
  GstBuffer *buffer = gst_buffer_copy (buf);

  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);

  g_value_init (&value, GST_TYPE_BUFFER);
  gst_value_set_buffer (&value, buffer);
  gst_value_array_append_value (array, &value);
  g_value_unset (&value);

}

typedef enum
{
  PAGE_HEADER,                  /* Header page */
  PAGE_DATA,                    /* Data page */
  PAGE_PENDING,                 /* We don't know yet, we'll have to see some future pages */
} page_type;

static page_type
gst_ogg_parse_is_header (GstOggParse * ogg, GstOggStream * stream,
    ogg_page * page)
{
  ogg_int64_t gpos = ogg_page_granulepos (page);

  if (gpos < 0)
    return PAGE_PENDING;

  /* This is good enough for now, but technically requires codec-specific
   * behaviour to be perfect. This is where we need the mooted library for 
   * this stuff, which nobody has written.
   */
  if (gpos > 0)
    return PAGE_DATA;
  else
    return PAGE_HEADER;
}

static GstBuffer *
gst_ogg_parse_buffer_from_page (ogg_page * page,
    guint64 offset, GstClockTime timestamp)
{
  int size = page->header_len + page->body_len;
  GstBuffer *buf = gst_buffer_new_and_alloc (size);

  gst_buffer_fill (buf, 0, page->header, page->header_len);
  gst_buffer_fill (buf, page->header_len, page->body, page->body_len);

  GST_BUFFER_TIMESTAMP (buf) = timestamp;
  GST_BUFFER_OFFSET (buf) = offset;
  GST_BUFFER_OFFSET_END (buf) = offset + size;

  return buf;
}


/* Reads in buffers, parses them, reframes into one-buffer-per-ogg-page, submits
 * pages to output pad.
 */
static GstFlowReturn
gst_ogg_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstOggParse *ogg;
  GstFlowReturn result = GST_FLOW_OK;
  gint ret = -1;
  guint32 serialno;
  GstBuffer *pagebuffer;
  GstClockTime buffertimestamp = GST_BUFFER_TIMESTAMP (buffer);

  ogg = GST_OGG_PARSE (parent);

  GST_LOG_OBJECT (ogg,
      "Chain function received buffer of size %" G_GSIZE_FORMAT,
      gst_buffer_get_size (buffer));

  gst_ogg_parse_submit_buffer (ogg, buffer);

  while (ret != 0 && result == GST_FLOW_OK) {
    ogg_page page;

    /* We use ogg_sync_pageseek() rather than ogg_sync_pageout() so that we can
     * track how many bytes the ogg layer discarded (in the case of sync errors,
     * etc.); this allows us to accurately track the current stream offset
     */
    ret = ogg_sync_pageseek (&ogg->sync, &page);
    if (ret == 0) {
      /* need more data, that's fine... */
      break;
    } else if (ret < 0) {
      /* discontinuity; track how many bytes we skipped (-ret) */
      ogg->offset -= ret;
    } else {
      gint64 granule = ogg_page_granulepos (&page);
#ifndef GST_DISABLE_GST_DEBUG
      int bos = ogg_page_bos (&page);
#endif
      guint64 startoffset = ogg->offset;
      GstOggStream *stream;
      gboolean keyframe;

      serialno = ogg_page_serialno (&page);
      stream = gst_ogg_parse_find_stream (ogg, serialno);

      GST_LOG_OBJECT (ogg, "Timestamping outgoing buffer as %" GST_TIME_FORMAT,
          GST_TIME_ARGS (buffertimestamp));

      if (stream) {
        buffertimestamp = gst_ogg_stream_get_end_time_for_granulepos (stream,
            granule);
        if (ogg->video_stream) {
          if (stream == ogg->video_stream) {
            keyframe = gst_ogg_stream_granulepos_is_key_frame (stream, granule);
          } else {
            keyframe = FALSE;
          }
        } else {
          keyframe = TRUE;
        }
      } else {
        buffertimestamp = GST_CLOCK_TIME_NONE;
        keyframe = TRUE;
      }
      pagebuffer = gst_ogg_parse_buffer_from_page (&page, startoffset,
          buffertimestamp);

      /* We read out 'ret' bytes, so we set the next offset appropriately */
      ogg->offset += ret;

      GST_LOG_OBJECT (ogg,
          "processing ogg page (serial %08x, pageno %ld, "
          "granule pos %" G_GUINT64_FORMAT ", bos %d, offset %"
          G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT ") keyframe=%d",
          serialno, ogg_page_pageno (&page),
          granule, bos, startoffset, ogg->offset, keyframe);

      if (ogg_page_bos (&page)) {
        /* If we've seen this serialno before, this is technically an error,
         * we log this case but accept it - this one replaces the previous
         * stream with this serialno. We can do this since we're streaming, and
         * not supporting seeking...
         */
        GstOggStream *stream = gst_ogg_parse_find_stream (ogg, serialno);

        if (stream != NULL) {
          GST_LOG_OBJECT (ogg, "Incorrect stream; repeats serial number %08x "
              "at offset %" G_GINT64_FORMAT, serialno, ogg->offset);
        }

        if (ogg->last_page_not_bos) {
          GST_LOG_OBJECT (ogg, "Deleting all referenced streams, found a new "
              "chain starting with serial %u", serialno);
          gst_ogg_parse_delete_all_streams (ogg);
        }

        stream = gst_ogg_parse_new_stream (ogg, &page);

        ogg->last_page_not_bos = FALSE;

        gst_buffer_ref (pagebuffer);
        stream->headers = g_list_append (stream->headers, pagebuffer);

        if (!ogg->in_headers) {
          GST_LOG_OBJECT (ogg,
              "Found start of new chain at offset %" G_GUINT64_FORMAT,
              startoffset);
          ogg->in_headers = 1;
        }

        /* For now, we just keep the header buffer in the stream->headers list;
         * it actually gets output once we've collected the entire set
         */
      } else {
        /* Non-BOS page. Either: we're outside headers, and this isn't a 
         * header (normal data), outside headers and this is (error!), inside
         * headers, this is (append header), or inside headers and this isn't 
         * (we've found the end of headers; flush the lot!)
         *
         * Before that, we flag that the last page seen (this one) was not a 
         * BOS page; that way we know that when we next see a BOS page it's a
         * new chain, and we can flush all existing streams.
         */
        page_type type;
        GstOggStream *stream = gst_ogg_parse_find_stream (ogg, serialno);

        if (!stream) {
          GST_LOG_OBJECT (ogg,
              "Non-BOS page unexpectedly found at %" G_GINT64_FORMAT,
              ogg->offset);
          goto failure;
        }

        ogg->last_page_not_bos = TRUE;

        type = gst_ogg_parse_is_header (ogg, stream, &page);

        if (type == PAGE_PENDING && ogg->in_headers) {
          gst_buffer_ref (pagebuffer);

          stream->unknown_pages = g_list_append (stream->unknown_pages,
              pagebuffer);
        } else if (type == PAGE_HEADER) {
          if (!ogg->in_headers) {
            GST_LOG_OBJECT (ogg, "Header page unexpectedly found outside "
                "headers at offset %" G_GINT64_FORMAT, ogg->offset);
            goto failure;
          } else {
            /* Append the header to the buffer list, after any unknown previous
             * pages
             */
            stream->headers = g_list_concat (stream->headers,
                stream->unknown_pages);
            g_list_free (stream->unknown_pages);
            gst_buffer_ref (pagebuffer);
            stream->headers = g_list_append (stream->headers, pagebuffer);
          }
        } else {                /* PAGE_DATA, or PAGE_PENDING but outside headers */
          if (ogg->in_headers) {
            /* First non-header page... set caps, flush headers.
             *
             * First up, we build a single GValue list of all the pagebuffers
             * we're using for the headers, in order.
             * Then we set this on the caps structure. Then we can start pushing
             * buffers for the headers, and finally we send this non-header
             * page.
             */
            GstCaps *caps;
            GstStructure *structure;
            GValue array = { 0 };
            gint count = 0;
            gboolean found_pending_headers = FALSE;
            GSList *l;

            g_value_init (&array, GST_TYPE_ARRAY);

            for (l = ogg->oggstreams; l != NULL; l = l->next) {
              GstOggStream *stream = (GstOggStream *) l->data;

              if (g_list_length (stream->headers) == 0) {
                GST_LOG_OBJECT (ogg, "No primary header found for stream %08x",
                    stream->serialno);
                goto failure;
              }

              gst_ogg_parse_append_header (&array,
                  GST_BUFFER (stream->headers->data));
              count++;
            }

            for (l = ogg->oggstreams; l != NULL; l = l->next) {
              GstOggStream *stream = (GstOggStream *) l->data;
              GList *j;

              /* already appended the first header, now do headers 2-N */
              for (j = stream->headers->next; j != NULL; j = j->next) {
                gst_ogg_parse_append_header (&array, GST_BUFFER (j->data));
                count++;
              }
            }

            caps = gst_pad_query_caps (ogg->srcpad, NULL);
            caps = gst_caps_make_writable (caps);

            structure = gst_caps_get_structure (caps, 0);
            gst_structure_take_value (structure, "streamheader", &array);

            gst_pad_set_caps (ogg->srcpad, caps);

            if (ogg->caps)
              gst_caps_unref (ogg->caps);
            ogg->caps = caps;

            GST_LOG_OBJECT (ogg, "Set \"streamheader\" caps with %d buffers "
                "(one per page)", count);

            /* Now, we do the same thing, but push buffers... */
            for (l = ogg->oggstreams; l != NULL; l = l->next) {
              GstOggStream *stream = (GstOggStream *) l->data;
              GstBuffer *buf = GST_BUFFER (stream->headers->data);

              result = gst_pad_push (ogg->srcpad, buf);
              if (result != GST_FLOW_OK)
                return result;
            }
            for (l = ogg->oggstreams; l != NULL; l = l->next) {
              GstOggStream *stream = (GstOggStream *) l->data;
              GList *j;

              /* pushed the first one for each stream already, now do 2-N */
              for (j = stream->headers->next; j != NULL; j = j->next) {
                GstBuffer *buf = GST_BUFFER (j->data);

                result = gst_pad_push (ogg->srcpad, buf);
                if (result != GST_FLOW_OK)
                  return result;
              }
            }

            ogg->in_headers = 0;

            /* And finally the pending data pages */
            for (l = ogg->oggstreams; l != NULL; l = l->next) {
              GstOggStream *stream = (GstOggStream *) l->data;
              GList *k;

              if (stream->unknown_pages == NULL)
                continue;

              if (found_pending_headers) {
                GST_WARNING_OBJECT (ogg, "Incorrectly muxed headers found at "
                    "approximate offset %" G_GINT64_FORMAT, ogg->offset);
              }
              found_pending_headers = TRUE;

              GST_LOG_OBJECT (ogg, "Pushing %d pending pages after headers",
                  g_list_length (stream->unknown_pages) + 1);

              for (k = stream->unknown_pages; k != NULL; k = k->next) {
                GstBuffer *buf = GST_BUFFER (k->data);

                result = gst_pad_push (ogg->srcpad, buf);
                if (result != GST_FLOW_OK)
                  return result;
              }
              g_list_foreach (stream->unknown_pages,
                  (GFunc) gst_mini_object_unref, NULL);
              g_list_free (stream->unknown_pages);
              stream->unknown_pages = NULL;
            }
          }

          if (granule == -1) {
            stream->stored_buffers = g_list_append (stream->stored_buffers,
                pagebuffer);
          } else {
            while (stream->stored_buffers) {
              GstBuffer *buf = stream->stored_buffers->data;

              buf = gst_buffer_make_writable (buf);

              GST_BUFFER_TIMESTAMP (buf) = buffertimestamp;
              if (!keyframe) {
                GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
              } else {
                keyframe = FALSE;
              }

              result = gst_pad_push (ogg->srcpad, buf);
              if (result != GST_FLOW_OK)
                return result;

              stream->stored_buffers =
                  g_list_delete_link (stream->stored_buffers,
                  stream->stored_buffers);
            }

            pagebuffer = gst_buffer_make_writable (pagebuffer);
            if (!keyframe) {
              GST_BUFFER_FLAG_SET (pagebuffer, GST_BUFFER_FLAG_DELTA_UNIT);
            } else {
              keyframe = FALSE;
            }

            result = gst_pad_push (ogg->srcpad, pagebuffer);
            if (result != GST_FLOW_OK)
              return result;
          }
        }
      }
    }
  }

  return result;

failure:
  gst_pad_push_event (GST_PAD (ogg->srcpad), gst_event_new_eos ());
  return GST_FLOW_ERROR;
}

static GstStateChangeReturn
gst_ogg_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstOggParse *ogg;
  GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;

  ogg = GST_OGG_PARSE (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      ogg_sync_init (&ogg->sync);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      ogg_sync_reset (&ogg->sync);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  result = parent_class->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      ogg_sync_clear (&ogg->sync);
      break;
    default:
      break;
  }
  return result;
}

gboolean
gst_ogg_parse_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_ogg_parse_debug, "oggparse", 0, "ogg parser");

  return gst_element_register (plugin, "oggparse", GST_RANK_NONE,
      GST_TYPE_OGG_PARSE);
}
