/* GStreamer
 * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
 * Copyright (C) 2006 Andy Wingo <wingo@pobox.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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-theoraparse
 * @title: theoraparse
 * @see_also: theoradec, oggdemux, vorbisparse
 *
 * The theoraparse element will parse the header packets of the Theora
 * stream and put them as the streamheader in the caps. This is used in the
 * multifdsink case where you want to stream live theora streams to multiple
 * clients, each client has to receive the streamheaders first before they can
 * consume the theora packets.
 *
 * This element also makes sure that the buffers that it pushes out are properly
 * timestamped and that their offset and offset_end are set. The buffers that
 * theoraparse outputs have all of the metadata that oggmux expects to receive,
 * which allows you to (for example) remux an ogg/theora file.
 *
 * In addition, this element allows you to fix badly synchronized streams. You
 * pass in an array of (granule time, buffer time) synchronization points via
 * the synchronization-points GValueArray property, and this element will adjust
 * the granulepos values that it outputs. The adjustment will be made by
 * offsetting all buffers that it outputs by a specified amount, and updating
 * that offset from the value array whenever a keyframe is processed.
 *
 * ## Example pipelines
 * |[
 * gst-launch-1.0 -v filesrc location=video.ogg ! oggdemux ! theoraparse ! fakesink
 * ]|
 *  This pipeline shows that the streamheader is set in the caps, and that each
 * buffer has the timestamp, duration, offset, and offset_end set.
 * |[
 * gst-launch-1.0 filesrc location=video.ogg ! oggdemux ! theoraparse \
 *            ! oggmux ! filesink location=video-remuxed.ogg
 * ]|
 *  This pipeline shows remuxing. video-remuxed.ogg might not be exactly the same
 * as video.ogg, but they should produce exactly the same decoded data.
 *
 */

/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
 * with newer GLib versions (>= 2.31.0) */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

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

#include "gsttheoraparse.h"

#define GST_CAT_DEFAULT theoraparse_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

static GstStaticPadTemplate theora_parse_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-theora")
    );

static GstStaticPadTemplate theora_parse_src_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-theora")
    );

enum
{
  PROP_0,
  PROP_SYNCHRONIZATION_POINTS
};

#define gst_theora_parse_parent_class parent_class
G_DEFINE_TYPE (GstTheoraParse, gst_theora_parse, GST_TYPE_ELEMENT);

static void theora_parse_dispose (GObject * object);

#if 0
static void theora_parse_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void theora_parse_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
#endif

static GstFlowReturn theora_parse_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static GstStateChangeReturn theora_parse_change_state (GstElement * element,
    GstStateChange transition);
static gboolean theora_parse_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean theora_parse_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);

static void
gst_theora_parse_class_init (GstTheoraParseClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);

  gobject_class->dispose = theora_parse_dispose;

#if 0
  gobject_class->get_property = theora_parse_get_property;
  gobject_class->set_property = theora_parse_set_property;

  /**
   * GstTheoraParse:sychronization-points
   *
   * An array of (granuletime, buffertime) pairs
   */
  g_object_class_install_property (gobject_class, PROP_SYNCHRONIZATION_POINTS,
      g_param_spec_value_array ("synchronization-points",
          "Synchronization points",
          "An array of (granuletime, buffertime) pairs",
          g_param_spec_uint64 ("time", "Time",
              "Time (either granuletime or buffertime)", 0, G_MAXUINT64, 0,
              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
#endif

  gst_element_class_add_static_pad_template (gstelement_class,
      &theora_parse_src_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &theora_parse_sink_factory);
  gst_element_class_set_static_metadata (gstelement_class,
      "Theora video parser", "Codec/Parser/Video", "parse raw theora streams",
      "Andy Wingo <wingo@pobox.com>");

  gstelement_class->change_state = theora_parse_change_state;

  GST_DEBUG_CATEGORY_INIT (theoraparse_debug, "theoraparse", 0,
      "Theora parser");
}

static void
gst_theora_parse_init (GstTheoraParse * parse)
{
  parse->sinkpad =
      gst_pad_new_from_static_template (&theora_parse_sink_factory, "sink");
  gst_pad_set_chain_function (parse->sinkpad, theora_parse_chain);
  gst_pad_set_event_function (parse->sinkpad, theora_parse_sink_event);
  gst_element_add_pad (GST_ELEMENT (parse), parse->sinkpad);

  parse->srcpad =
      gst_pad_new_from_static_template (&theora_parse_src_factory, "src");
  gst_pad_set_query_function (parse->srcpad, theora_parse_src_query);
  gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
}

static void
theora_parse_dispose (GObject * object)
{
  GstTheoraParse *parse = GST_THEORA_PARSE (object);

  g_free (parse->times);
  parse->times = NULL;

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

#if 0
static void
theora_parse_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstTheoraParse *parse = GST_THEORA_PARSE (object);

  switch (prop_id) {
    case PROP_SYNCHRONIZATION_POINTS:
    {
      GValueArray *array;
      guint i;

      array = g_value_get_boxed (value);

      if (array) {
        if (array->n_values % 2)
          goto odd_values;

        g_free (parse->times);
        parse->times = g_new (GstClockTime, array->n_values);
        parse->npairs = array->n_values / 2;
        for (i = 0; i < array->n_values; i++)
          parse->times[i] = g_value_get_uint64 (&array->values[i]);
      } else {
        g_free (parse->times);
        parse->npairs = 0;
      }
    }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  return;

odd_values:
  {
    g_critical ("expected an even number of time values for "
        "synchronization-points");
    return;
  }
}

static void
theora_parse_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstTheoraParse *parse = GST_THEORA_PARSE (object);

  switch (prop_id) {
    case PROP_SYNCHRONIZATION_POINTS:
    {
      GValueArray *array = NULL;
      guint i;

      array = g_value_array_new (parse->npairs * 2);

      for (i = 0; i < parse->npairs; i++) {
        GValue v = { 0, };

        g_value_init (&v, G_TYPE_UINT64);
        g_value_set_uint64 (&v, parse->times[i * 2]);
        g_value_array_append (array, &v);
        g_value_set_uint64 (&v, parse->times[i * 2 + 1]);
        g_value_array_append (array, &v);
        g_value_unset (&v);
      }

      g_value_take_boxed (value, array);
    }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
#endif

static void
theora_parse_set_header_on_caps (GstTheoraParse * parse, GstCaps * caps)
{
  GstBuffer **bufs;
  GstStructure *structure;
  gint i;
  GValue array = { 0 };
  GValue value = { 0 };

  bufs = parse->streamheader;
  structure = gst_caps_get_structure (caps, 0);
  g_value_init (&array, GST_TYPE_ARRAY);

  for (i = 0; i < 3; i++) {
    if (bufs[i] == NULL)
      continue;

    bufs[i] = gst_buffer_make_writable (bufs[i]);
    GST_BUFFER_FLAG_SET (bufs[i], GST_BUFFER_FLAG_HEADER);

    g_value_init (&value, GST_TYPE_BUFFER);
    gst_value_set_buffer (&value, bufs[i]);
    gst_value_array_append_value (&array, &value);
    g_value_unset (&value);
  }

  gst_structure_take_value (structure, "streamheader", &array);
}

/* two tasks to do here: set the streamheader on the caps, and use libtheora to
   parse the headers */
static void
theora_parse_set_streamheader (GstTheoraParse * parse)
{
  GstCaps *caps;
  gint i;
  guint32 bitstream_version;
  th_setup_info *setup = NULL;

  g_assert (!parse->streamheader_received);

  caps = gst_caps_make_writable (gst_pad_query_caps (parse->srcpad, NULL));
  theora_parse_set_header_on_caps (parse, caps);
  GST_DEBUG_OBJECT (parse, "here are the caps: %" GST_PTR_FORMAT, caps);
  gst_pad_set_caps (parse->srcpad, caps);
  gst_caps_unref (caps);

  for (i = 0; i < 3; i++) {
    ogg_packet packet;
    GstBuffer *buf;
    int ret;
    GstMapInfo map;

    buf = parse->streamheader[i];
    if (buf == NULL)
      continue;

    gst_buffer_map (buf, &map, GST_MAP_READ);
    packet.packet = map.data;
    packet.bytes = map.size;
    packet.granulepos = GST_BUFFER_OFFSET_END (buf);
    packet.packetno = i + 1;
    packet.e_o_s = 0;
    packet.b_o_s = (i == 0);
    ret = th_decode_headerin (&parse->info, &parse->comment, &setup, &packet);
    gst_buffer_unmap (buf, &map);
    if (ret < 0) {
      GST_WARNING_OBJECT (parse, "Failed to decode Theora header %d: %d",
          i + 1, ret);
    }
  }
  if (setup) {
    th_setup_free (setup);
  }

  parse->fps_n = parse->info.fps_numerator;
  parse->fps_d = parse->info.fps_denominator;
  parse->shift = parse->info.keyframe_granule_shift;

  /* With libtheora-1.0beta1 the granulepos scheme was changed:
   * where earlier the granulepos referred to the index/beginning
   * of a frame, it now refers to the end, which matches the use
   * in vorbis/speex. We check the bitstream version from the header so
   * we know which way to interpret the incoming granuepos
   */
  bitstream_version = (parse->info.version_major << 16) |
      (parse->info.version_minor << 8) | parse->info.version_subminor;
  parse->is_old_bitstream = (bitstream_version <= 0x00030200);

  parse->streamheader_received = TRUE;
}

static void
theora_parse_drain_event_queue (GstTheoraParse * parse)
{
  while (parse->event_queue->length) {
    GstEvent *event;

    event = GST_EVENT_CAST (g_queue_pop_head (parse->event_queue));
    gst_pad_event_default (parse->sinkpad, GST_OBJECT_CAST (parse), event);
  }
}

static void
theora_parse_push_headers (GstTheoraParse * parse)
{
  gint i;

  if (!parse->streamheader_received)
    theora_parse_set_streamheader (parse);

  theora_parse_drain_event_queue (parse);

  /* ignore return values, we pass along the result of pushing data packets only
   */
  for (i = 0; i < 3; i++) {
    GstBuffer *buf;

    if ((buf = parse->streamheader[i])) {
      gst_pad_push (parse->srcpad, buf);
      parse->streamheader[i] = NULL;
    }
  }
}

static void
theora_parse_clear_queue (GstTheoraParse * parse)
{
  while (parse->buffer_queue->length) {
    GstBuffer *buf;

    buf = GST_BUFFER_CAST (g_queue_pop_head (parse->buffer_queue));
    gst_buffer_unref (buf);
  }
  while (parse->event_queue->length) {
    GstEvent *event;

    event = GST_EVENT_CAST (g_queue_pop_head (parse->event_queue));
    gst_event_unref (event);
  }
}

static gint64
make_granulepos (GstTheoraParse * parse, gint64 keyframe, gint64 frame)
{
  gint64 iframe;

  if (keyframe == -1)
    keyframe = 0;
  /* If using newer theora, offset the granulepos by +1, see comment in
   * theora_parse_set_streamheader.
   * 
   * We don't increment keyframe directly, as internally we always index frames
   * starting from 0 and we do some sanity checking below. */
  if (!parse->is_old_bitstream)
    iframe = keyframe + 1;
  else
    iframe = keyframe;

  g_return_val_if_fail (frame >= keyframe, -1);
  g_return_val_if_fail (frame - keyframe < 1 << parse->shift, -1);

  return (iframe << parse->shift) + (frame - keyframe);
}

static void
parse_granulepos (GstTheoraParse * parse, gint64 granulepos,
    gint64 * keyframe, gint64 * frame)
{
  gint64 kf;

  kf = granulepos >> parse->shift;
  /* If using newer theora, offset the granulepos by -1, see comment
   * in theora_parse_set_streamheader */
  if (!parse->is_old_bitstream)
    kf -= 1;
  if (keyframe)
    *keyframe = kf;
  if (frame)
    *frame = kf + (granulepos & ((1 << parse->shift) - 1));
}

static gboolean
is_keyframe (GstBuffer * buf)
{
  gsize size;
  guint8 data[1];

  size = gst_buffer_get_size (buf);
  if (size == 0)
    return FALSE;

  gst_buffer_extract (buf, 0, data, 1);

  return ((data[0] & 0x40) == 0);
}

static void
theora_parse_munge_granulepos (GstTheoraParse * parse, GstBuffer * buf,
    gint64 keyframe, gint64 frame)
{
  gint64 frames_diff;
  GstClockTimeDiff time_diff;

  if (keyframe == frame) {
    gint i;

    /* update granule_offset */
    for (i = 0; i < parse->npairs; i++) {
      if (parse->times[i * 2] >= GST_BUFFER_OFFSET (buf))
        break;
    }
    if (i > 0) {
      /* time_diff gets reset below */
      time_diff = parse->times[i * 2 - 1] - parse->times[i * 2 - 2];
      parse->granule_offset = gst_util_uint64_scale (time_diff,
          parse->fps_n, parse->fps_d * GST_SECOND);
      parse->granule_offset <<= parse->shift;
    }
  }

  frames_diff = parse->granule_offset >> parse->shift;
  time_diff = gst_util_uint64_scale_int (GST_SECOND * frames_diff,
      parse->fps_d, parse->fps_n);

  GST_DEBUG_OBJECT (parse, "offsetting theora stream by %" G_GINT64_FORMAT
      " frames (%" GST_TIME_FORMAT ")", frames_diff, GST_TIME_ARGS (time_diff));

  GST_BUFFER_OFFSET_END (buf) += parse->granule_offset;
  GST_BUFFER_OFFSET (buf) += time_diff;
  GST_BUFFER_TIMESTAMP (buf) += time_diff;
}

static GstFlowReturn
theora_parse_push_buffer (GstTheoraParse * parse, GstBuffer * buf,
    gint64 keyframe, gint64 frame)
{

  GstClockTime this_time, next_time;

  this_time = gst_util_uint64_scale_int (GST_SECOND * frame,
      parse->fps_d, parse->fps_n);

  next_time = gst_util_uint64_scale_int (GST_SECOND * (frame + 1),
      parse->fps_d, parse->fps_n);

  GST_BUFFER_OFFSET_END (buf) = make_granulepos (parse, keyframe, frame);
  GST_BUFFER_OFFSET (buf) = this_time;
  GST_BUFFER_TIMESTAMP (buf) = this_time;
  GST_BUFFER_DURATION (buf) = next_time - this_time;

  if (parse->times)
    theora_parse_munge_granulepos (parse, buf, keyframe, frame);

  GST_DEBUG_OBJECT (parse, "pushing buffer with granulepos %" G_GINT64_FORMAT
      "|%" G_GINT64_FORMAT, keyframe, frame - keyframe);

  return gst_pad_push (parse->srcpad, buf);
}

static GstFlowReturn
theora_parse_drain_queue_prematurely (GstTheoraParse * parse)
{
  GstFlowReturn ret = GST_FLOW_OK;

  /* got an EOS event, make sure to push out any buffers that were in the queue
   * -- won't normally be the case, but this catches the
   * didn't-get-a-granulepos-on-the-last-packet case. Assuming a continuous
   * stream. */

  GST_DEBUG_OBJECT (parse, "got EOS, draining queue");

  /* if we get an eos before pushing the streamheaders, drain our events before
   * eos */
  theora_parse_drain_event_queue (parse);

  while (!g_queue_is_empty (parse->buffer_queue)) {
    GstBuffer *buf;

    buf = GST_BUFFER_CAST (g_queue_pop_head (parse->buffer_queue));

    parse->prev_frame++;

    if (is_keyframe (buf))
      /* we have a keyframe */
      parse->prev_keyframe = parse->prev_frame;
    else
      GST_BUFFER_FLAGS (buf) |= GST_BUFFER_FLAG_DELTA_UNIT;

    if (parse->prev_keyframe < 0) {
      if (GST_BUFFER_OFFSET_END_IS_VALID (buf)) {
        parse_granulepos (parse, GST_BUFFER_OFFSET_END (buf),
            &parse->prev_keyframe, NULL);
      } else {
        /* No previous keyframe known; can't extract one from this frame. That
         * means we can't do any valid output for this frame, just continue to
         * the next frame.
         */
        gst_buffer_unref (buf);
        continue;
      }
    }

    ret = theora_parse_push_buffer (parse, buf, parse->prev_keyframe,
        parse->prev_frame);

    if (ret != GST_FLOW_OK)
      goto done;
  }

done:
  return ret;
}

static GstFlowReturn
theora_parse_drain_queue (GstTheoraParse * parse, gint64 granulepos)
{
  GstFlowReturn ret = GST_FLOW_OK;
  gint64 keyframe, prev_frame, frame;

  parse_granulepos (parse, granulepos, &keyframe, &frame);

  GST_DEBUG ("draining queue of length %d",
      g_queue_get_length (parse->buffer_queue));

  GST_LOG_OBJECT (parse, "gp %" G_GINT64_FORMAT ", kf %" G_GINT64_FORMAT
      ", frame %" G_GINT64_FORMAT, granulepos, keyframe, frame);

  prev_frame = frame - g_queue_get_length (parse->buffer_queue);

  GST_LOG_OBJECT (parse,
      "new prev %" G_GINT64_FORMAT ", prev %" G_GINT64_FORMAT, prev_frame,
      parse->prev_frame);

  if (prev_frame < parse->prev_frame) {
    GST_WARNING ("jumped %" G_GINT64_FORMAT
        " frames backwards! not sure what to do here",
        parse->prev_frame - prev_frame);
    parse->prev_frame = prev_frame;
  } else if (prev_frame > parse->prev_frame) {
    GST_INFO ("discontinuity detected (%" G_GINT64_FORMAT
        " frames)", prev_frame - parse->prev_frame);
    if (keyframe <= prev_frame && keyframe > parse->prev_keyframe)
      parse->prev_keyframe = keyframe;
    parse->prev_frame = prev_frame;
  }

  while (!g_queue_is_empty (parse->buffer_queue)) {
    GstBuffer *buf;

    parse->prev_frame++;
    g_assert (parse->prev_frame >= 0);

    buf = GST_BUFFER_CAST (g_queue_pop_head (parse->buffer_queue));

    if (is_keyframe (buf))
      /* we have a keyframe */
      parse->prev_keyframe = parse->prev_frame;
    else
      GST_BUFFER_FLAGS (buf) |= GST_BUFFER_FLAG_DELTA_UNIT;

    ret = theora_parse_push_buffer (parse, buf, parse->prev_keyframe,
        parse->prev_frame);

    if (ret != GST_FLOW_OK)
      goto done;
  }

done:
  return ret;
}

static GstFlowReturn
theora_parse_queue_buffer (GstTheoraParse * parse, GstBuffer * buf)
{
  GstFlowReturn ret = GST_FLOW_OK;

  buf = gst_buffer_make_writable (buf);

  g_queue_push_tail (parse->buffer_queue, buf);

  if (GST_BUFFER_OFFSET_END_IS_VALID (buf)) {
    if (parse->prev_keyframe < 0) {
      parse_granulepos (parse, GST_BUFFER_OFFSET_END (buf),
          &parse->prev_keyframe, NULL);
    }
    ret = theora_parse_drain_queue (parse, GST_BUFFER_OFFSET_END (buf));
  }

  return ret;
}

static GstFlowReturn
theora_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstFlowReturn ret;
  GstTheoraParse *parse;
  GstMapInfo map;
  guint8 header;
  gboolean have_header;

  parse = GST_THEORA_PARSE (parent);

  have_header = FALSE;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  header = map.data[0];
  gst_buffer_unmap (buffer, &map);

  if (map.size >= 1) {
    if (header & 0x80)
      have_header = TRUE;
  }

  if (have_header) {
    if (parse->send_streamheader) {
      /* we need to collect the headers still */
      /* so put it on the streamheader list and return */
      if (header >= 0x80 && header <= 0x82)
        parse->streamheader[header - 0x80] = buffer;
    }
    ret = GST_FLOW_OK;
  } else {
    /* data packet, push the headers we collected before */
    if (parse->send_streamheader) {
      theora_parse_push_headers (parse);
      parse->send_streamheader = FALSE;
    }

    ret = theora_parse_queue_buffer (parse, buffer);
  }

  return ret;
}

static gboolean
theora_parse_queue_event (GstTheoraParse * parse, GstEvent * event)
{
  g_queue_push_tail (parse->event_queue, event);
  return TRUE;
}

static gboolean
theora_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean ret;
  GstTheoraParse *parse;

  parse = GST_THEORA_PARSE (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      theora_parse_clear_queue (parse);
      parse->prev_keyframe = -1;
      parse->prev_frame = -1;
      ret = gst_pad_event_default (pad, parent, event);
      break;
    case GST_EVENT_EOS:
      theora_parse_drain_queue_prematurely (parse);
      ret = gst_pad_event_default (pad, parent, event);
      break;
    default:
      if (parse->send_streamheader && GST_EVENT_IS_SERIALIZED (event)
          && GST_EVENT_TYPE (event) > GST_EVENT_CAPS)
        ret = theora_parse_queue_event (parse, event);
      else
        ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

static gboolean
theora_parse_src_convert (GstPad * pad,
    GstFormat src_format, gint64 src_value,
    GstFormat * dest_format, gint64 * dest_value)
{
  gboolean res = TRUE;
  GstTheoraParse *parse;
  guint64 scale = 1;

  if (src_format == *dest_format) {
    *dest_value = src_value;
    return TRUE;
  }

  parse = GST_THEORA_PARSE (gst_pad_get_parent (pad));

  /* we need the info part before we can done something */
  if (!parse->streamheader_received)
    goto no_header;

  switch (src_format) {
    case GST_FORMAT_BYTES:
      switch (*dest_format) {
        case GST_FORMAT_DEFAULT:
          *dest_value = gst_util_uint64_scale_int (src_value, 2,
              parse->info.pic_height * parse->info.pic_width * 3);
          break;
        case GST_FORMAT_TIME:
          /* seems like a rather silly conversion, implement me if you like */
        default:
          res = FALSE;
      }
      break;
    case GST_FORMAT_TIME:
      switch (*dest_format) {
        case GST_FORMAT_BYTES:
          scale = 3 * (parse->info.pic_width * parse->info.pic_height) / 2;
        case GST_FORMAT_DEFAULT:
          *dest_value = scale * gst_util_uint64_scale (src_value,
              parse->info.fps_numerator,
              parse->info.fps_denominator * GST_SECOND);
          break;
        default:
          GST_DEBUG_OBJECT (parse, "cannot convert to format %s",
              gst_format_get_name (*dest_format));
          res = FALSE;
      }
      break;
    case GST_FORMAT_DEFAULT:
      switch (*dest_format) {
        case GST_FORMAT_TIME:
          *dest_value = gst_util_uint64_scale (src_value,
              GST_SECOND * parse->info.fps_denominator,
              parse->info.fps_numerator);
          break;
        case GST_FORMAT_BYTES:
          *dest_value = gst_util_uint64_scale_int (src_value,
              3 * parse->info.pic_width * parse->info.pic_height, 2);
          break;
        default:
          res = FALSE;
      }
      break;
    default:
      res = FALSE;
  }
done:
  gst_object_unref (parse);
  return res;

  /* ERRORS */
no_header:
  {
    GST_DEBUG_OBJECT (parse, "no header yet, cannot convert");
    res = FALSE;
    goto done;
  }
}

static gboolean
theora_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstTheoraParse *parse;
  gboolean res = FALSE;

  parse = GST_THEORA_PARSE (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      gint64 frame, value;
      GstFormat my_format, format;
      gint64 time;

      frame = parse->prev_frame;

      GST_LOG_OBJECT (parse,
          "query %p: we have current frame: %" G_GINT64_FORMAT, query, frame);

      /* parse format */
      gst_query_parse_position (query, &format, NULL);

      /* and convert to the final format in two steps with time as the 
       * intermediate step */
      my_format = GST_FORMAT_TIME;
      if (!(res =
              theora_parse_src_convert (parse->sinkpad, GST_FORMAT_DEFAULT,
                  frame, &my_format, &time)))
        goto error;

      /* fixme: handle segments
         time = (time - parse->segment.start) + parse->segment.time;
       */

      GST_LOG_OBJECT (parse,
          "query %p: our time: %" GST_TIME_FORMAT " (conv to %s)",
          query, GST_TIME_ARGS (time), gst_format_get_name (format));

      if (!(res =
              theora_parse_src_convert (pad, my_format, time, &format, &value)))
        goto error;

      gst_query_set_position (query, format, value);

      GST_LOG_OBJECT (parse,
          "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
          format);

      break;
    }
    case GST_QUERY_DURATION:
      /* forward to peer for total */
      if (!(res = gst_pad_query (GST_PAD_PEER (parse->sinkpad), query)))
        goto error;
      break;
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      if (!(res =
              theora_parse_src_convert (pad, src_fmt, src_val, &dest_fmt,
                  &dest_val)))
        goto error;

      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
done:

  return res;

  /* ERRORS */
error:
  {
    GST_DEBUG_OBJECT (parse, "query failed");
    goto done;
  }
}

static GstStateChangeReturn
theora_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstTheoraParse *parse = GST_THEORA_PARSE (element);
  GstStateChangeReturn ret;
  gint i;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      th_info_init (&parse->info);
      th_comment_init (&parse->comment);
      parse->send_streamheader = TRUE;
      parse->buffer_queue = g_queue_new ();
      parse->event_queue = g_queue_new ();
      parse->prev_keyframe = -1;
      parse->prev_frame = -1;
      parse->granule_offset = 0;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      th_info_clear (&parse->info);
      th_comment_clear (&parse->comment);
      theora_parse_clear_queue (parse);
      g_queue_free (parse->buffer_queue);
      g_queue_free (parse->event_queue);
      parse->buffer_queue = NULL;
      for (i = 0; i < 3; i++) {
        if (parse->streamheader[i]) {
          gst_buffer_unref (parse->streamheader[i]);
          parse->streamheader[i] = NULL;
        }
      }
      parse->streamheader_received = FALSE;
      break;
    default:
      break;
  }

  return ret;
}
