/* GStreamer OGM parsing
 * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>

#include <gst/gst.h>
#include <gst/tag/tag.h>
#include <gst/riff/riff-media.h>
#include <gst/riff/riff-read.h>

#include "gstogg.h"

GST_DEBUG_CATEGORY_STATIC (gst_ogm_parse_debug);
#define GST_CAT_DEFAULT gst_ogm_parse_debug

#define GST_TYPE_OGM_VIDEO_PARSE (gst_ogm_video_parse_get_type())
#define GST_IS_OGM_VIDEO_PARSE(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OGM_VIDEO_PARSE))

#define GST_TYPE_OGM_AUDIO_PARSE (gst_ogm_audio_parse_get_type())
#define GST_IS_OGM_AUDIO_PARSE(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OGM_AUDIO_PARSE))

#define GST_TYPE_OGM_TEXT_PARSE (gst_ogm_text_parse_get_type())
#define GST_IS_OGM_TEXT_PARSE(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OGM_TEXT_PARSE))

#define GST_TYPE_OGM_PARSE (gst_ogm_parse_get_type())
#define GST_OGM_PARSE(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_OGM_PARSE, GstOgmParse))
#define GST_OGM_PARSE_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_OGM_PARSE, GstOgmParse))
#define GST_IS_OGM_PARSE(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OGM_PARSE))
#define GST_IS_OGM_PARSE_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_OGM_PARSE))
#define GST_OGM_PARSE_GET_CLASS(obj) \
  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_OGM_PARSE, GstOgmParseClass))

typedef struct _stream_header_video
{
  gint32 width;
  gint32 height;
} stream_header_video;

typedef struct _stream_header_audio
{
  gint16 channels;
  gint16 blockalign;
  gint32 avgbytespersec;
} stream_header_audio;

/* sizeof(stream_header) might differ due to structure packing and
 * alignment differences on some architectures, so not using that */
#define OGM_STREAM_HEADER_SIZE (8+4+4+8+8+4+4+4+8)

typedef struct _stream_header
{
  gchar streamtype[8];
  gchar subtype[4 + 1];

  /* size of the structure */
  gint32 size;

  /* in reference time */
  gint64 time_unit;

  gint64 samples_per_unit;

  /* in media time */
  gint32 default_len;

  gint32 buffersize;
  gint32 bits_per_sample;

  union
  {
    stream_header_video video;
    stream_header_audio audio;
    /* text has no additional data */
  } s;
} stream_header;

typedef struct _GstOgmParse
{
  GstElement element;

  /* pads */
  GstPad *srcpad, *sinkpad;
  GstPadTemplate *srcpadtempl;

  /* we need to cache events that we receive before creating the source pad */
  GList *cached_events;

  /* audio or video */
  stream_header hdr;

  /* expected next granulepos (used for timestamp guessing) */
  guint64 next_granulepos;
} GstOgmParse;

typedef struct _GstOgmParseClass
{
  GstElementClass parent_class;
} GstOgmParseClass;

static GstStaticPadTemplate sink_factory_video =
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-ogm-video"));
static GstStaticPadTemplate sink_factory_audio =
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-ogm-audio"));
static GstStaticPadTemplate sink_factory_text =
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-ogm-text"));
static GstPadTemplate *video_src_templ, *audio_src_templ, *text_src_templ;

static GType gst_ogm_audio_parse_get_type (void);
static GType gst_ogm_video_parse_get_type (void);
static GType gst_ogm_text_parse_get_type (void);
static GType gst_ogm_parse_get_type (void);

static void gst_ogm_audio_parse_base_init (GstOgmParseClass * klass);
static void gst_ogm_video_parse_base_init (GstOgmParseClass * klass);
static void gst_ogm_text_parse_base_init (GstOgmParseClass * klass);
static void gst_ogm_parse_class_init (GstOgmParseClass * klass);
static void gst_ogm_parse_init (GstOgmParse * ogm);
static void gst_ogm_video_parse_init (GstOgmParse * ogm);
static void gst_ogm_audio_parse_init (GstOgmParse * ogm);
static void gst_ogm_text_parse_init (GstOgmParse * ogm);

static gboolean gst_ogm_parse_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_ogm_parse_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_ogm_parse_sink_convert (GstPad * pad, GstFormat src_format,
    gint64 src_value, GstFormat * dest_format, gint64 * dest_value);

static GstFlowReturn gst_ogm_parse_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);

static GstStateChangeReturn gst_ogm_parse_change_state (GstElement * element,
    GstStateChange transition);

static GstElementClass *parent_class = NULL;

static GType
gst_ogm_parse_get_type (void)
{
  static GType ogm_parse_type = 0;

  if (!ogm_parse_type) {
    static const GTypeInfo ogm_parse_info = {
      sizeof (GstOgmParseClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_ogm_parse_class_init,
      NULL,
      NULL,
      sizeof (GstOgmParse),
      0,
      (GInstanceInitFunc) gst_ogm_parse_init,
    };

    ogm_parse_type =
        g_type_register_static (GST_TYPE_ELEMENT,
        "GstOgmParse", &ogm_parse_info, 0);
  }

  return ogm_parse_type;
}

static GType
gst_ogm_audio_parse_get_type (void)
{
  static GType ogm_audio_parse_type = 0;

  if (!ogm_audio_parse_type) {
    static const GTypeInfo ogm_audio_parse_info = {
      sizeof (GstOgmParseClass),
      (GBaseInitFunc) gst_ogm_audio_parse_base_init,
      NULL,
      NULL,
      NULL,
      NULL,
      sizeof (GstOgmParse),
      0,
      (GInstanceInitFunc) gst_ogm_audio_parse_init,
    };

    ogm_audio_parse_type =
        g_type_register_static (GST_TYPE_OGM_PARSE,
        "GstOgmAudioParse", &ogm_audio_parse_info, 0);
  }

  return ogm_audio_parse_type;
}

static GType
gst_ogm_video_parse_get_type (void)
{
  static GType ogm_video_parse_type = 0;

  if (!ogm_video_parse_type) {
    static const GTypeInfo ogm_video_parse_info = {
      sizeof (GstOgmParseClass),
      (GBaseInitFunc) gst_ogm_video_parse_base_init,
      NULL,
      NULL,
      NULL,
      NULL,
      sizeof (GstOgmParse),
      0,
      (GInstanceInitFunc) gst_ogm_video_parse_init,
    };

    ogm_video_parse_type =
        g_type_register_static (GST_TYPE_OGM_PARSE,
        "GstOgmVideoParse", &ogm_video_parse_info, 0);
  }

  return ogm_video_parse_type;
}

static GType
gst_ogm_text_parse_get_type (void)
{
  static GType ogm_text_parse_type = 0;

  if (!ogm_text_parse_type) {
    static const GTypeInfo ogm_text_parse_info = {
      sizeof (GstOgmParseClass),
      (GBaseInitFunc) gst_ogm_text_parse_base_init,
      NULL,
      NULL,
      NULL,
      NULL,
      sizeof (GstOgmParse),
      0,
      (GInstanceInitFunc) gst_ogm_text_parse_init,
    };

    ogm_text_parse_type =
        g_type_register_static (GST_TYPE_OGM_PARSE,
        "GstOgmTextParse", &ogm_text_parse_info, 0);
  }

  return ogm_text_parse_type;
}

static void
gst_ogm_audio_parse_base_init (GstOgmParseClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstCaps *caps = gst_riff_create_audio_template_caps ();

  gst_element_class_set_static_metadata (element_class,
      "OGM audio stream parser", "Codec/Decoder/Audio",
      "parse an OGM audio header and stream",
      "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");

  gst_element_class_add_static_pad_template (element_class,
      &sink_factory_audio);
  audio_src_templ =
      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
  gst_element_class_add_pad_template (element_class, audio_src_templ);
  gst_caps_unref (caps);
}

static void
gst_ogm_video_parse_base_init (GstOgmParseClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstCaps *caps = gst_riff_create_video_template_caps ();

  gst_element_class_set_static_metadata (element_class,
      "OGM video stream parser", "Codec/Decoder/Video",
      "parse an OGM video header and stream",
      "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");

  gst_element_class_add_static_pad_template (element_class,
      &sink_factory_video);
  video_src_templ =
      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
  gst_element_class_add_pad_template (element_class, video_src_templ);
  gst_caps_unref (caps);
}

static void
gst_ogm_text_parse_base_init (GstOgmParseClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstCaps *caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
      "utf8", NULL);

  gst_element_class_set_static_metadata (element_class,
      "OGM text stream parser", "Codec/Decoder/Subtitle",
      "parse an OGM text header and stream",
      "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");

  gst_element_class_add_static_pad_template (element_class, &sink_factory_text);
  text_src_templ = gst_pad_template_new ("src",
      GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
  gst_element_class_add_pad_template (element_class, text_src_templ);
  gst_caps_unref (caps);
}

static void
gst_ogm_parse_class_init (GstOgmParseClass * klass)
{
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);

  parent_class = g_type_class_peek_parent (klass);

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_ogm_parse_change_state);
}

static void
gst_ogm_parse_init (GstOgmParse * ogm)
{
  memset (&ogm->hdr, 0, sizeof (ogm->hdr));
  ogm->next_granulepos = 0;
  ogm->srcpad = NULL;
  ogm->cached_events = NULL;
}

static void
gst_ogm_audio_parse_init (GstOgmParse * ogm)
{
  ogm->sinkpad = gst_pad_new_from_static_template (&sink_factory_audio, "sink");
  gst_pad_set_query_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_sink_query));
  gst_pad_set_chain_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_chain));
  gst_pad_set_event_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_sink_event));
  gst_element_add_pad (GST_ELEMENT (ogm), ogm->sinkpad);

  ogm->srcpad = NULL;
  ogm->srcpadtempl = audio_src_templ;
}

static void
gst_ogm_video_parse_init (GstOgmParse * ogm)
{
  ogm->sinkpad = gst_pad_new_from_static_template (&sink_factory_video, "sink");
  gst_pad_set_query_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_sink_query));
  gst_pad_set_chain_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_chain));
  gst_pad_set_event_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_sink_event));
  gst_element_add_pad (GST_ELEMENT (ogm), ogm->sinkpad);

  ogm->srcpad = NULL;
  ogm->srcpadtempl = video_src_templ;
}

static void
gst_ogm_text_parse_init (GstOgmParse * ogm)
{
  ogm->sinkpad = gst_pad_new_from_static_template (&sink_factory_text, "sink");
  gst_pad_set_query_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_sink_query));
  gst_pad_set_chain_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_chain));
  gst_pad_set_event_function (ogm->sinkpad,
      GST_DEBUG_FUNCPTR (gst_ogm_parse_sink_event));
  gst_element_add_pad (GST_ELEMENT (ogm), ogm->sinkpad);

  ogm->srcpad = NULL;
  ogm->srcpadtempl = text_src_templ;
}

static gboolean
gst_ogm_parse_sink_convert (GstPad * pad,
    GstFormat src_format, gint64 src_value,
    GstFormat * dest_format, gint64 * dest_value)
{
  gboolean res = FALSE;
  GstOgmParse *ogm = GST_OGM_PARSE (gst_pad_get_parent (pad));

  switch (src_format) {
    case GST_FORMAT_DEFAULT:
      switch (*dest_format) {
        case GST_FORMAT_TIME:
          switch (ogm->hdr.streamtype[0]) {
            case 'a':
              *dest_value = GST_SECOND * src_value / ogm->hdr.samples_per_unit;
              res = TRUE;
              break;
            case 'v':
            case 't':
              *dest_value = (GST_SECOND / 10000000) *
                  ogm->hdr.time_unit * src_value;
              res = TRUE;
              break;
            default:
              break;
          }
          break;
        default:
          break;
      }
      break;
    case GST_FORMAT_TIME:
      switch (*dest_format) {
        case GST_FORMAT_DEFAULT:
          switch (ogm->hdr.streamtype[0]) {
            case 'a':
              *dest_value = ogm->hdr.samples_per_unit * src_value / GST_SECOND;
              res = TRUE;
              break;
            case 'v':
            case 't':
              *dest_value = src_value /
                  ((GST_SECOND / 10000000) * ogm->hdr.time_unit);
              res = TRUE;
              break;
            default:
              break;
          }
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }

  gst_object_unref (ogm);
  return res;
}

static gboolean
gst_ogm_parse_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstOgmParse *ogm = GST_OGM_PARSE (parent);
  GstFormat format;
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      gint64 val;

      gst_query_parse_position (query, &format, NULL);

      if (format != GST_FORMAT_DEFAULT && format != GST_FORMAT_TIME)
        break;

      if ((res = gst_ogm_parse_sink_convert (pad,
                  GST_FORMAT_DEFAULT, ogm->next_granulepos, &format, &val))) {
        /* don't know the total length here.. */
        gst_query_set_position (query, format, val);
      }
      break;
    }
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      /* peel off input */
      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      if ((res = gst_ogm_parse_sink_convert (pad, src_fmt, src_val,
                  &dest_fmt, &dest_val))) {
        gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      }
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

  return res;
}

static GstFlowReturn
gst_ogm_parse_stream_header (GstOgmParse * ogm, const guint8 * data, guint size)
{
  GstCaps *caps = NULL;

  /* stream header */
  if (size < OGM_STREAM_HEADER_SIZE)
    goto buffer_too_small;

  if (!memcmp (data, "video\000\000\000", 8)) {
    ogm->hdr.s.video.width = GST_READ_UINT32_LE (&data[44]);
    ogm->hdr.s.video.height = GST_READ_UINT32_LE (&data[48]);
  } else if (!memcmp (data, "audio\000\000\000", 8)) {
    ogm->hdr.s.audio.channels = GST_READ_UINT32_LE (&data[44]);
    ogm->hdr.s.audio.blockalign = GST_READ_UINT32_LE (&data[46]);
    ogm->hdr.s.audio.avgbytespersec = GST_READ_UINT32_LE (&data[48]);
  } else if (!memcmp (data, "text\000\000\000\000", 8)) {
    /* nothing here */
  } else {
    goto cannot_decode;
  }
  memcpy (ogm->hdr.streamtype, &data[0], 8);
  memcpy (ogm->hdr.subtype, &data[8], 4);
  ogm->hdr.subtype[4] = '\0';
  ogm->hdr.size = GST_READ_UINT32_LE (&data[12]);
  ogm->hdr.time_unit = GST_READ_UINT64_LE (&data[16]);
  ogm->hdr.samples_per_unit = GST_READ_UINT64_LE (&data[24]);
  ogm->hdr.default_len = GST_READ_UINT32_LE (&data[32]);
  ogm->hdr.buffersize = GST_READ_UINT32_LE (&data[36]);
  ogm->hdr.bits_per_sample = GST_READ_UINT32_LE (&data[40]);

  switch (ogm->hdr.streamtype[0]) {
    case 'a':{
      guint codec_id = 0;

      if (sscanf (ogm->hdr.subtype, "%04x", &codec_id) != 1) {
        GST_WARNING_OBJECT (ogm, "cannot parse subtype %s", ogm->hdr.subtype);
      }

      /* FIXME: Need to do something with the reorder map */
      caps =
          gst_riff_create_audio_caps (codec_id, NULL, NULL, NULL, NULL, NULL,
          NULL);

      if (caps == NULL) {
        GST_WARNING_OBJECT (ogm, "no audio caps for codec %u found", codec_id);
        caps = gst_caps_new_simple ("audio/x-ogm-unknown", "codec_id",
            G_TYPE_INT, (gint) codec_id, NULL);
      }

      gst_caps_set_simple (caps,
          "channels", G_TYPE_INT, ogm->hdr.s.audio.channels,
          "rate", G_TYPE_INT, ogm->hdr.samples_per_unit, NULL);

      GST_LOG_OBJECT (ogm, "Type: %s, subtype: 0x%04x, channels: %d, "
          "samplerate: %d, blockalign: %d, bps: %d, caps = %" GST_PTR_FORMAT,
          ogm->hdr.streamtype, codec_id, ogm->hdr.s.audio.channels,
          (gint) ogm->hdr.samples_per_unit, ogm->hdr.s.audio.blockalign,
          ogm->hdr.s.audio.avgbytespersec, caps);
      break;
    }
    case 'v':{
      guint32 fourcc;
      gint time_unit;

      fourcc = GST_MAKE_FOURCC (ogm->hdr.subtype[0],
          ogm->hdr.subtype[1], ogm->hdr.subtype[2], ogm->hdr.subtype[3]);

      caps = gst_riff_create_video_caps (fourcc, NULL, NULL, NULL, NULL, NULL);

      if (caps == NULL) {
        GST_WARNING_OBJECT (ogm, "could not find video caps for fourcc %"
            GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
        caps = gst_caps_new_simple ("video/x-ogm-unknown", "fourcc",
            G_TYPE_STRING, ogm->hdr.subtype, NULL);
        break;
      }

      GST_LOG_OBJECT (ogm, "Type: %s, subtype: %" GST_FOURCC_FORMAT
          ", size: %dx%d, timeunit: %" G_GINT64_FORMAT
          " (fps: %lf), s/u: %" G_GINT64_FORMAT ", "
          "def.len: %d, bufsize: %d, bps: %d, caps = %" GST_PTR_FORMAT,
          ogm->hdr.streamtype, GST_FOURCC_ARGS (fourcc),
          ogm->hdr.s.video.width, ogm->hdr.s.video.height,
          ogm->hdr.time_unit, 10000000. / ogm->hdr.time_unit,
          ogm->hdr.samples_per_unit, ogm->hdr.default_len,
          ogm->hdr.buffersize, ogm->hdr.bits_per_sample, caps);

      /* GST_TYPE_FRACTION contains gint */
      if (ogm->hdr.time_unit > G_MAXINT || ogm->hdr.time_unit < G_MININT)
        GST_WARNING_OBJECT (ogm, "timeunit is out of range");

      time_unit = (gint) CLAMP (ogm->hdr.time_unit, G_MININT, G_MAXINT);
      gst_caps_set_simple (caps,
          "width", G_TYPE_INT, ogm->hdr.s.video.width,
          "height", G_TYPE_INT, ogm->hdr.s.video.height,
          "framerate", GST_TYPE_FRACTION, 10000000, time_unit, NULL);
      break;
    }
    case 't':{
      GST_LOG_OBJECT (ogm, "Type: %s, s/u: %" G_GINT64_FORMAT
          ", timeunit=%" G_GINT64_FORMAT,
          ogm->hdr.streamtype, ogm->hdr.samples_per_unit, ogm->hdr.time_unit);
      caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
          "utf8", NULL);
      break;
    }
    default:
      g_assert_not_reached ();
  }

  if (caps == NULL)
    goto cannot_decode;

  if (ogm->srcpad) {
    GstCaps *current_caps = gst_pad_get_current_caps (ogm->srcpad);

    if (current_caps) {
      if (caps && !gst_caps_is_equal (current_caps, caps)) {
        GST_WARNING_OBJECT (ogm, "Already an existing pad %s:%s",
            GST_DEBUG_PAD_NAME (ogm->srcpad));
        gst_pad_set_active (ogm->srcpad, FALSE);
        gst_element_remove_pad (GST_ELEMENT (ogm), ogm->srcpad);
        ogm->srcpad = NULL;
      } else {
        GST_DEBUG_OBJECT (ogm, "Existing pad has the same caps, do nothing");
      }
      gst_caps_unref (current_caps);
    }
  }

  if (ogm->srcpad == NULL) {
    GList *l, *cached_events;

    ogm->srcpad = gst_pad_new_from_template (ogm->srcpadtempl, "src");
    gst_pad_use_fixed_caps (ogm->srcpad);
    gst_pad_set_active (ogm->srcpad, TRUE);
    gst_pad_set_caps (ogm->srcpad, caps);
    gst_element_add_pad (GST_ELEMENT (ogm), ogm->srcpad);
    GST_INFO_OBJECT (ogm, "Added pad %s:%s with caps %" GST_PTR_FORMAT,
        GST_DEBUG_PAD_NAME (ogm->srcpad), caps);

    GST_OBJECT_LOCK (ogm);
    cached_events = ogm->cached_events;
    ogm->cached_events = NULL;
    GST_OBJECT_UNLOCK (ogm);

    for (l = cached_events; l; l = l->next) {
      GstEvent *event = GST_EVENT_CAST (l->data);

      GST_DEBUG_OBJECT (ogm, "Pushing cached event %" GST_PTR_FORMAT, event);
      gst_pad_push_event (ogm->srcpad, event);
    }
    g_list_free (cached_events);

    {
      GstTagList *tags;

      tags = gst_tag_list_new (GST_TAG_SUBTITLE_CODEC, "Ogm", NULL);
      gst_pad_push_event (ogm->srcpad, gst_event_new_tag (tags));
    }
  }

  gst_caps_unref (caps);

  return GST_FLOW_OK;

/* ERRORS */
buffer_too_small:
  {
    GST_ELEMENT_ERROR (ogm, STREAM, WRONG_TYPE, ("Buffer too small"), (NULL));
    return GST_FLOW_ERROR;
  }
cannot_decode:
  {
    GST_ELEMENT_ERROR (ogm, STREAM, DECODE, (NULL), ("unknown ogm format"));
    return GST_FLOW_ERROR;
  }
}

static GstFlowReturn
gst_ogm_parse_comment_packet (GstOgmParse * ogm, GstBuffer * buf)
{
  GstFlowReturn ret;

  if (ogm->srcpad == NULL) {
    GST_DEBUG ("no source pad");
    return GST_FLOW_FLUSHING;
  }

  /* if this is not a subtitle stream, push the vorbiscomment packet
   * on downstream, the respective decoder will handle it; if it is
   * a subtitle stream, we will have to handle the comment ourself */
  if (ogm->hdr.streamtype[0] == 't') {
    GstTagList *tags;

    tags = gst_tag_list_from_vorbiscomment_buffer (buf,
        (guint8 *) "\003vorbis", 7, NULL);

    if (tags) {
      GST_DEBUG_OBJECT (ogm, "tags = %" GST_PTR_FORMAT, tags);
      gst_pad_push_event (ogm->srcpad, gst_event_new_tag (tags));
    } else {
      GST_DEBUG_OBJECT (ogm, "failed to extract tags from vorbis comment");
    }
    /* do not push packet downstream, just let parent unref it */
    ret = GST_FLOW_OK;
  } else {
    ret = gst_pad_push (ogm->srcpad, buf);
  }

  return ret;
}

static void
gst_ogm_text_parse_strip_trailing_zeroes (GstOgmParse * ogm, GstBuffer * buf)
{
  GstMapInfo map;
  gsize size;

  g_assert (gst_buffer_is_writable (buf));

  /* zeroes are not valid UTF-8 characters, so strip them from output */
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  size = map.size;
  while (size > 0 && map.data[size - 1] == '\0') {
    --size;
  }
  gst_buffer_unmap (buf, &map);
}

static GstFlowReturn
gst_ogm_parse_data_packet (GstOgmParse * ogm, GstBuffer * buf,
    const guint8 * data, gsize size)
{
  GstFlowReturn ret;
  GstBuffer *sbuf;
  gboolean keyframe;
  guint len, n, xsize = 0;

  if ((data[0] & 0x01) != 0)
    goto invalid_startcode;

  /* data - push on */
  len = ((data[0] & 0xc0) >> 6) | ((data[0] & 0x02) << 1);
  keyframe = (((data[0] & 0x08) >> 3) != 0);

  if ((1 + len) > size)
    goto buffer_too_small;

  for (n = len; n > 0; n--) {
    xsize = (xsize << 8) | data[n];
  }

  GST_LOG_OBJECT (ogm, "[0x%02x] samples: %d, hdrbytes: %d, datasize: %"
      G_GSIZE_FORMAT, data[0], xsize, len, size - len - 1);

  sbuf =
      gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, len + 1,
      size - len - 1);

  if (GST_BUFFER_OFFSET_END_IS_VALID (buf))
    ogm->next_granulepos = GST_BUFFER_OFFSET_END (buf);

  switch (ogm->hdr.streamtype[0]) {
    case 't':
    case 'v':{
      GstClockTime ts, next_ts;
      guint samples;

      samples = (ogm->hdr.streamtype[0] == 'v') ? 1 : xsize;

      if (!keyframe) {
        GST_BUFFER_FLAG_SET (sbuf, GST_BUFFER_FLAG_DELTA_UNIT);
      }

      /* shouldn't this be granulepos - samples? (tpm) */
      ts = gst_util_uint64_scale (ogm->next_granulepos,
          ogm->hdr.time_unit * GST_SECOND, 10000000);
      next_ts = gst_util_uint64_scale (ogm->next_granulepos + samples,
          ogm->hdr.time_unit * GST_SECOND, 10000000);

      GST_BUFFER_TIMESTAMP (sbuf) = ts;
      GST_BUFFER_DURATION (sbuf) = next_ts - ts;

      ogm->next_granulepos += samples;

      if (ogm->hdr.streamtype[0] == 't') {
        gst_ogm_text_parse_strip_trailing_zeroes (ogm, sbuf);
      }
      break;
    }
    case 'a':{
      GstClockTime ts, next_ts;

      /* shouldn't this be granulepos - samples? (tpm) */
      ts = gst_util_uint64_scale_int (ogm->next_granulepos,
          GST_SECOND, ogm->hdr.samples_per_unit);
      next_ts = gst_util_uint64_scale_int (ogm->next_granulepos + xsize,
          GST_SECOND, ogm->hdr.samples_per_unit);

      GST_BUFFER_TIMESTAMP (sbuf) = ts;
      GST_BUFFER_DURATION (sbuf) = next_ts - ts;

      ogm->next_granulepos += xsize;
      break;
    }
    default:
      g_assert_not_reached ();
      break;
  }

  if (ogm->srcpad) {
    GST_LOG_OBJECT (ogm, "Pushing buffer with ts=%" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sbuf)));
    ret = gst_pad_push (ogm->srcpad, sbuf);
    if (ret != GST_FLOW_OK) {
      GST_DEBUG_OBJECT (ogm, "Flow on %s:%s = %s",
          GST_DEBUG_PAD_NAME (ogm->srcpad), gst_flow_get_name (ret));
    }
  } else {
    ret = GST_FLOW_FLUSHING;
  }

  return ret;

/* ERRORS */
invalid_startcode:
  {
    GST_ELEMENT_ERROR (ogm, STREAM, DECODE, (NULL),
        ("unexpected packet startcode 0x%02x", data[0]));
    return GST_FLOW_ERROR;
  }
buffer_too_small:
  {
    GST_ELEMENT_ERROR (ogm, STREAM, DECODE, (NULL),
        ("buffer too small, len+1=%u, size=%" G_GSIZE_FORMAT, len + 1, size));
    return GST_FLOW_ERROR;
  }
}

static GstFlowReturn
gst_ogm_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstOgmParse *ogm = GST_OGM_PARSE (parent);
  GstMapInfo map;

  gst_buffer_map (buf, &map, GST_MAP_READ);
  if (map.size < 1)
    goto buffer_too_small;

  GST_LOG_OBJECT (ogm, "Packet with start code 0x%02x", map.data[0]);

  switch (map.data[0]) {
    case 0x01:{
      ret = gst_ogm_parse_stream_header (ogm, map.data + 1, map.size - 1);
      break;
    }
    case 0x03:{
      ret = gst_ogm_parse_comment_packet (ogm, buf);
      break;
    }
    default:{
      ret = gst_ogm_parse_data_packet (ogm, buf, map.data, map.size);
      break;
    }
  }

  gst_buffer_unmap (buf, &map);
  gst_buffer_unref (buf);

  if (ret != GST_FLOW_OK) {
    GST_DEBUG_OBJECT (ogm, "Flow: %s", gst_flow_get_name (ret));
  }

  return ret;

/* ERRORS */
buffer_too_small:
  {
    GST_ELEMENT_ERROR (ogm, STREAM, DECODE, (NULL), ("buffer too small"));
    gst_buffer_unmap (buf, &map);
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
}

static gboolean
gst_ogm_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstOgmParse *ogm = GST_OGM_PARSE (parent);
  gboolean res;

  GST_LOG_OBJECT (ogm, "processing %s event", GST_EVENT_TYPE_NAME (event));

  GST_OBJECT_LOCK (ogm);
  if (ogm->srcpad == NULL) {
    ogm->cached_events = g_list_append (ogm->cached_events, event);
    GST_OBJECT_UNLOCK (ogm);
    res = TRUE;
  } else {
    GST_OBJECT_UNLOCK (ogm);
    res = gst_pad_event_default (pad, parent, event);
  }

  return res;
}

static GstStateChangeReturn
gst_ogm_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstOgmParse *ogm = GST_OGM_PARSE (element);

  ret = parent_class->change_state (element, transition);
  if (ret != GST_STATE_CHANGE_SUCCESS)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      if (ogm->srcpad) {
        gst_pad_set_active (ogm->srcpad, FALSE);
        gst_element_remove_pad (element, ogm->srcpad);
        ogm->srcpad = NULL;
      }
      memset (&ogm->hdr, 0, sizeof (ogm->hdr));
      ogm->next_granulepos = 0;
      g_list_foreach (ogm->cached_events, (GFunc) gst_mini_object_unref, NULL);
      g_list_free (ogm->cached_events);
      ogm->cached_events = NULL;
      break;
    default:
      break;
  }

  return ret;
}

gboolean
gst_ogm_parse_plugin_init (GstPlugin * plugin)
{
  gst_riff_init ();

  GST_DEBUG_CATEGORY_INIT (gst_ogm_parse_debug, "ogmparse", 0, "ogm parser");

  return gst_element_register (plugin, "ogmaudioparse", GST_RANK_PRIMARY,
      GST_TYPE_OGM_AUDIO_PARSE) &&
      gst_element_register (plugin, "ogmvideoparse", GST_RANK_PRIMARY,
      GST_TYPE_OGM_VIDEO_PARSE) &&
      gst_element_register (plugin, "ogmtextparse", GST_RANK_PRIMARY,
      GST_TYPE_OGM_TEXT_PARSE);
}
