/* OGG muxer plugin for GStreamer
 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
 * Copyright (C) 2006 Thomas Vander Stichele <thomas at apestaart dot org>
 *
 * 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-oggmux
 * @see_also: <link linkend="gst-plugins-base-plugins-oggdemux">oggdemux</link>
 *
 * This element merges streams (audio and video) into ogg files.
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 v4l2src num-buffers=500 ! video/x-raw,width=320,height=240 ! videoconvert ! videorate ! theoraenc ! oggmux ! filesink location=video.ogg
 * ]| Encodes a video stream captured from a v4l2-compatible camera to Ogg/Theora
 * (the encoding will stop automatically after 500 frames)
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/base/gstbytewriter.h>
#include <gst/audio/audio.h>
#include <gst/tag/tag.h>

#include "gstoggmux.h"

/* memcpy - if someone knows a way to get rid of it, please speak up
 * note: the ogg docs even say you need this... */
#include <string.h>
#include <time.h>
#include <stdlib.h>             /* rand, srand, atoi */

GST_DEBUG_CATEGORY_STATIC (gst_ogg_mux_debug);
#define GST_CAT_DEFAULT gst_ogg_mux_debug

/* This isn't generally what you'd want with an end-time macro, because
   technically the end time of a buffer with invalid duration is invalid. But
   for sorting ogg pages this is what we want. */
#define GST_BUFFER_END_TIME(buf) \
    (GST_BUFFER_DURATION_IS_VALID (buf) \
    ? GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf) \
    : GST_BUFFER_TIMESTAMP (buf))

#define GST_GP_FORMAT "[gp %8" G_GINT64_FORMAT "]"
#define GST_GP_CAST(_gp) ((gint64) _gp)

/* set to 0.5 seconds by default */
#define DEFAULT_MAX_DELAY       G_GINT64_CONSTANT(500000000)
#define DEFAULT_MAX_PAGE_DELAY  G_GINT64_CONSTANT(500000000)
#define DEFAULT_MAX_TOLERANCE   G_GINT64_CONSTANT(40000000)
#define DEFAULT_SKELETON        FALSE

enum
{
  ARG_0,
  ARG_MAX_DELAY,
  ARG_MAX_PAGE_DELAY,
  ARG_MAX_TOLERANCE,
  ARG_SKELETON
};

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

static GstStaticPadTemplate video_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("video_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("video/x-theora; "
        "application/x-ogm-video; video/x-dirac; "
        "video/x-smoke; video/x-vp8; video/x-daala")
    );

static GstStaticPadTemplate audio_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("audio_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS
    ("audio/x-vorbis; audio/x-flac; audio/x-speex; audio/x-celt; "
        "application/x-ogm-audio; audio/x-opus")
    );

static GstStaticPadTemplate subtitle_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("text/x-cmml, encoded = (boolean) TRUE; "
        "subtitle/x-kate; application/x-kate")
    );

static void gst_ogg_mux_finalize (GObject * object);

static GstFlowReturn gst_ogg_mux_collected (GstCollectPads * pads,
    GstOggMux * ogg_mux);
static gboolean gst_ogg_mux_sink_event (GstCollectPads * pads,
    GstCollectData * pad, GstEvent * event, gpointer user_data);
static gboolean gst_ogg_mux_handle_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstPad *gst_ogg_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gst_ogg_mux_release_pad (GstElement * element, GstPad * pad);
static void gst_ogg_pad_data_reset (GstOggMux * ogg_mux,
    GstOggPadData * pad_data);

static void gst_ogg_mux_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_ogg_mux_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_ogg_mux_change_state (GstElement * element,
    GstStateChange transition);

/*static guint gst_ogg_mux_signals[LAST_SIGNAL] = { 0 }; */
#define gst_ogg_mux_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstOggMux, gst_ogg_mux, GST_TYPE_ELEMENT,
    G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));

static void
gst_ogg_mux_class_init (GstOggMuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  gobject_class->finalize = gst_ogg_mux_finalize;
  gobject_class->get_property = gst_ogg_mux_get_property;
  gobject_class->set_property = gst_ogg_mux_set_property;

  gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &video_sink_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &audio_sink_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &subtitle_sink_factory);

  gst_element_class_set_static_metadata (gstelement_class,
      "Ogg muxer", "Codec/Muxer",
      "mux ogg streams (info about ogg: http://xiph.org)",
      "Wim Taymans <wim@fluendo.com>");

  gstelement_class->request_new_pad = gst_ogg_mux_request_new_pad;
  gstelement_class->release_pad = gst_ogg_mux_release_pad;

  g_object_class_install_property (gobject_class, ARG_MAX_DELAY,
      g_param_spec_uint64 ("max-delay", "Max delay",
          "Maximum delay in multiplexing streams", 0, G_MAXUINT64,
          DEFAULT_MAX_DELAY,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_MAX_PAGE_DELAY,
      g_param_spec_uint64 ("max-page-delay", "Max page delay",
          "Maximum delay for sending out a page", 0, G_MAXUINT64,
          DEFAULT_MAX_PAGE_DELAY,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_MAX_TOLERANCE,
      g_param_spec_uint64 ("max-tolerance", "Max time tolerance",
          "Maximum timestamp difference for maintaining perfect granules",
          0, G_MAXUINT64, DEFAULT_MAX_TOLERANCE,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_SKELETON,
      g_param_spec_boolean ("skeleton", "Skeleton",
          "Whether to include a Skeleton track",
          DEFAULT_SKELETON,
          (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state = gst_ogg_mux_change_state;

}

static void
gst_ogg_mux_clear (GstOggMux * ogg_mux)
{
  ogg_mux->pulling = NULL;
  ogg_mux->need_headers = TRUE;
  ogg_mux->need_start_events = TRUE;
  ogg_mux->delta_pad = NULL;
  ogg_mux->offset = 0;
  ogg_mux->next_ts = 0;
  ogg_mux->last_ts = GST_CLOCK_TIME_NONE;
}

static void
gst_ogg_mux_init (GstOggMux * ogg_mux)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (ogg_mux);

  ogg_mux->srcpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "src"), "src");
  gst_pad_set_event_function (ogg_mux->srcpad, gst_ogg_mux_handle_src_event);
  gst_element_add_pad (GST_ELEMENT (ogg_mux), ogg_mux->srcpad);

  /* seed random number generator for creation of serial numbers */
  srand (time (NULL));

  ogg_mux->collect = gst_collect_pads_new ();
  gst_collect_pads_set_function (ogg_mux->collect,
      (GstCollectPadsFunction) GST_DEBUG_FUNCPTR (gst_ogg_mux_collected),
      ogg_mux);
  gst_collect_pads_set_event_function (ogg_mux->collect,
      (GstCollectPadsEventFunction) GST_DEBUG_FUNCPTR (gst_ogg_mux_sink_event),
      ogg_mux);

  ogg_mux->max_delay = DEFAULT_MAX_DELAY;
  ogg_mux->max_page_delay = DEFAULT_MAX_PAGE_DELAY;
  ogg_mux->max_tolerance = DEFAULT_MAX_TOLERANCE;

  gst_ogg_mux_clear (ogg_mux);
}

static void
gst_ogg_mux_finalize (GObject * object)
{
  GstOggMux *ogg_mux;

  ogg_mux = GST_OGG_MUX (object);

  if (ogg_mux->collect) {
    gst_object_unref (ogg_mux->collect);
    ogg_mux->collect = NULL;
  }

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

static void
gst_ogg_mux_ogg_pad_destroy_notify (GstCollectData * data)
{
  GstOggPadData *oggpad = (GstOggPadData *) data;
  GstBuffer *buf;

  ogg_stream_clear (&oggpad->map.stream);
  gst_caps_replace (&oggpad->map.caps, NULL);

  if (oggpad->pagebuffers) {
    while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) {
      gst_buffer_unref (buf);
    }
    g_queue_free (oggpad->pagebuffers);
    oggpad->pagebuffers = NULL;
  }
}

static GstPadLinkReturn
gst_ogg_mux_sinkconnect (GstPad * pad, GstObject * parent, GstPad * peer)
{
  GstOggMux *ogg_mux;

  ogg_mux = GST_OGG_MUX (parent);

  GST_DEBUG_OBJECT (ogg_mux, "sinkconnect triggered on %s", GST_PAD_NAME (pad));

  return GST_PAD_LINK_OK;
}

static void
gst_ogg_mux_flush (GstOggMux * ogg_mux)
{
  GSList *walk;

  for (walk = ogg_mux->collect->data; walk; walk = g_slist_next (walk)) {
    GstOggPadData *pad;

    pad = (GstOggPadData *) walk->data;

    gst_ogg_pad_data_reset (ogg_mux, pad);
  }

  gst_ogg_mux_clear (ogg_mux);
}

static gboolean
gst_ogg_mux_sink_event (GstCollectPads * pads, GstCollectData * pad,
    GstEvent * event, gpointer user_data)
{
  GstOggMux *ogg_mux = GST_OGG_MUX (user_data);
  GstOggPadData *ogg_pad = (GstOggPadData *) pad;

  GST_DEBUG_OBJECT (pad->pad, "Got %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      const GstSegment *segment;

      gst_event_parse_segment (event, &segment);

      /* We don't support non time NEWSEGMENT events */
      if (segment->format != GST_FORMAT_TIME) {
        gst_event_unref (event);
        event = NULL;
        break;
      }

      gst_segment_copy_into (segment, &ogg_pad->segment);
      break;
    }
    case GST_EVENT_FLUSH_STOP:{
      /* only a single flush-stop is forwarded from collect pads */
      gst_ogg_mux_flush (ogg_mux);
      break;
    }
    case GST_EVENT_TAG:{
      GstTagList *tags;

      gst_event_parse_tag (event, &tags);
      tags = gst_tag_list_merge (ogg_pad->tags, tags, GST_TAG_MERGE_APPEND);
      if (ogg_pad->tags)
        gst_tag_list_unref (ogg_pad->tags);
      ogg_pad->tags = tags;

      GST_DEBUG_OBJECT (ogg_mux, "Got tags %" GST_PTR_FORMAT, ogg_pad->tags);
      break;
    }
    default:
      break;
  }

  /* now GstCollectPads can take care of the rest, e.g. EOS */
  if (event != NULL)
    return gst_collect_pads_event_default (pads, pad, event, FALSE);

  return TRUE;
}

static gboolean
gst_ogg_mux_is_serialno_present (GstOggMux * ogg_mux, guint32 serialno)
{
  GSList *walk;

  walk = ogg_mux->collect->data;
  while (walk) {
    GstOggPadData *pad = (GstOggPadData *) walk->data;
    if (pad->map.serialno == serialno)
      return TRUE;
    walk = walk->next;
  }

  return FALSE;
}

static void
gst_ogg_pad_data_reset (GstOggMux * ogg_mux, GstOggPadData * oggpad)
{
  oggpad->packetno = 0;
  oggpad->pageno = 0;
  oggpad->eos = FALSE;

  /* we assume there will be some control data first for this pad */
  oggpad->state = GST_OGG_PAD_STATE_CONTROL;
  oggpad->new_page = TRUE;
  oggpad->first_delta = FALSE;
  oggpad->prev_delta = FALSE;
  oggpad->data_pushed = FALSE;
  oggpad->map.headers = NULL;
  oggpad->map.queued = NULL;
  oggpad->next_granule = 0;
  oggpad->keyframe_granule = -1;
  ogg_stream_clear (&oggpad->map.stream);
  ogg_stream_init (&oggpad->map.stream, oggpad->map.serialno);

  if (oggpad->pagebuffers) {
    GstBuffer *buf;

    while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) {
      gst_buffer_unref (buf);
    }
  } else if (GST_STATE (ogg_mux) > GST_STATE_READY) {
    /* This will be initialized in init_collectpads when going from ready
     * paused state */
    oggpad->pagebuffers = g_queue_new ();
  }

  gst_segment_init (&oggpad->segment, GST_FORMAT_TIME);
}

static guint32
gst_ogg_mux_generate_serialno (GstOggMux * ogg_mux)
{
  guint32 serialno;

  do {
    serialno = g_random_int_range (0, G_MAXINT32);
  } while (gst_ogg_mux_is_serialno_present (ogg_mux, serialno));

  return serialno;
}

static GstPad *
gst_ogg_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
  GstOggMux *ogg_mux;
  GstPad *newpad;
  GstElementClass *klass;

  g_return_val_if_fail (templ != NULL, NULL);

  if (templ->direction != GST_PAD_SINK)
    goto wrong_direction;

  g_return_val_if_fail (GST_IS_OGG_MUX (element), NULL);
  ogg_mux = GST_OGG_MUX (element);

  klass = GST_ELEMENT_GET_CLASS (element);

  if (templ != gst_element_class_get_pad_template (klass, "video_%u") &&
      templ != gst_element_class_get_pad_template (klass, "audio_%u") &&
      templ != gst_element_class_get_pad_template (klass, "subtitle_%u")) {
    goto wrong_template;
  }

  {
    guint32 serial;
    gchar *name = NULL;

    if (req_name == NULL || strlen (req_name) < 6) {
      /* no name given when requesting the pad, use random serial number */
      serial = gst_ogg_mux_generate_serialno (ogg_mux);
    } else {
      /* parse serial number from requested padname */
      unsigned long long_serial;
      char *endptr = NULL;
      long_serial = strtoul (&req_name[5], &endptr, 10);
      if ((endptr && *endptr) || (long_serial & ~0xffffffff)) {
        GST_WARNING_OBJECT (ogg_mux, "Invalid serial number specification: %s",
            req_name + 5);
        return NULL;
      }
      serial = (guint32) long_serial;
    }
    /* create new pad with the name */
    GST_DEBUG_OBJECT (ogg_mux, "Creating new pad for serial %d", serial);

    if (templ == gst_element_class_get_pad_template (klass, "video_%u")) {
      name = g_strdup_printf ("video_%u", serial);
    } else if (templ == gst_element_class_get_pad_template (klass, "audio_%u")) {
      name = g_strdup_printf ("audio_%u", serial);
    } else if (templ == gst_element_class_get_pad_template (klass,
            "subtitle_%u")) {
      name = g_strdup_printf ("subtitle_%u", serial);
    }
    newpad = gst_pad_new_from_template (templ, name);
    g_free (name);

    /* construct our own wrapper data structure for the pad to
     * keep track of its status */
    {
      GstOggPadData *oggpad;

      oggpad = (GstOggPadData *)
          gst_collect_pads_add_pad (ogg_mux->collect, newpad,
          sizeof (GstOggPadData), gst_ogg_mux_ogg_pad_destroy_notify, FALSE);
      ogg_mux->active_pads++;

      oggpad->map.serialno = serial;
      gst_ogg_pad_data_reset (ogg_mux, oggpad);
    }
  }

  /* setup some pad functions */
  gst_pad_set_link_function (newpad, gst_ogg_mux_sinkconnect);

  /* dd the pad to the element */
  gst_element_add_pad (element, newpad);

  return newpad;

  /* ERRORS */
wrong_direction:
  {
    g_warning ("ogg_mux: request pad that is not a SINK pad\n");
    return NULL;
  }
wrong_template:
  {
    g_warning ("ogg_mux: this is not our template!\n");
    return NULL;
  }
}

static void
gst_ogg_mux_release_pad (GstElement * element, GstPad * pad)
{
  GstOggMux *ogg_mux;

  ogg_mux = GST_OGG_MUX (gst_pad_get_parent (pad));

  gst_collect_pads_remove_pad (ogg_mux->collect, pad);
  gst_element_remove_pad (element, pad);

  gst_object_unref (ogg_mux);
}

/* handle events */
static gboolean
gst_ogg_mux_handle_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean res = FALSE;
  GstOggMux *ogg_mux = GST_OGG_MUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:{
      GstSeekFlags flags;

      gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);
      if (!ogg_mux->need_headers && (flags & GST_SEEK_FLAG_FLUSH) != 0) {
        /* don't allow flushing seeks once we started */
        gst_event_unref (event);
        event = NULL;
      }
      break;
    }
    default:
      break;
  }

  if (event != NULL)
    res = gst_pad_event_default (pad, parent, event);

  return res;
}

static GstBuffer *
gst_ogg_mux_buffer_from_page (GstOggMux * mux, ogg_page * page, gboolean delta)
{
  GstBuffer *buffer;

  /* allocate space for header and body */
  buffer = gst_buffer_new_and_alloc (page->header_len + page->body_len);
  gst_buffer_fill (buffer, 0, page->header, page->header_len);
  gst_buffer_fill (buffer, page->header_len, page->body, page->body_len);

  /* Here we set granulepos as our OFFSET_END to give easy direct access to
   * this value later. Before we push it, we reset this to OFFSET + SIZE
   * (see gst_ogg_mux_push_buffer). */
  GST_BUFFER_OFFSET_END (buffer) = ogg_page_granulepos (page);
  if (delta)
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);

  GST_LOG_OBJECT (mux, GST_GP_FORMAT
      " created buffer %p from ogg page",
      GST_GP_CAST (ogg_page_granulepos (page)), buffer);

  return buffer;
}

static GstFlowReturn
gst_ogg_mux_push_buffer (GstOggMux * mux, GstBuffer * buffer,
    GstOggPadData * oggpad)
{
  /* fix up OFFSET and OFFSET_END again */
  GST_BUFFER_OFFSET (buffer) = mux->offset;
  mux->offset += gst_buffer_get_size (buffer);
  GST_BUFFER_OFFSET_END (buffer) = mux->offset;

  /* Ensure we have monotonically increasing timestamps in the output. */
  if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
    gint64 run_time = GST_BUFFER_TIMESTAMP (buffer);
    if (mux->last_ts != GST_CLOCK_TIME_NONE && run_time < mux->last_ts)
      GST_BUFFER_TIMESTAMP (buffer) = mux->last_ts;
    else
      mux->last_ts = run_time;
  }

  GST_LOG_OBJECT (mux->srcpad, "pushing %p, last_ts=%" GST_TIME_FORMAT,
      buffer, GST_TIME_ARGS (mux->last_ts));

  return gst_pad_push (mux->srcpad, buffer);
}

/* if all queues have at least one page, dequeue the page with the lowest
 * timestamp */
static gboolean
gst_ogg_mux_dequeue_page (GstOggMux * mux, GstFlowReturn * flowret)
{
  GSList *walk;
  GstOggPadData *opad = NULL;   /* "oldest" pad */
  GstClockTime oldest = GST_CLOCK_TIME_NONE;
  GstBuffer *buf = NULL;
  gboolean ret = FALSE;

  *flowret = GST_FLOW_OK;

  walk = mux->collect->data;
  while (walk) {
    GstOggPadData *pad = (GstOggPadData *) walk->data;

    /* We need each queue to either be at EOS, or have one or more pages
     * available with a set granulepos (i.e. not -1), otherwise we don't have
     * enough data yet to determine which stream needs to go next for correct
     * time ordering. */
    if (pad->pagebuffers->length == 0) {
      if (pad->eos) {
        GST_LOG_OBJECT (pad->collect.pad,
            "pad is EOS, skipping for dequeue decision");
      } else {
        GST_LOG_OBJECT (pad->collect.pad,
            "no pages in this queue, can't dequeue");
        return FALSE;
      }
    } else {
      /* We then need to check for a non-negative granulepos */
      gboolean valid = FALSE;
      GList *l;

      for (l = pad->pagebuffers->head; l != NULL; l = l->next) {
        buf = l->data;
        /* Here we check the OFFSET_END, which is actually temporarily the
         * granulepos value for this buffer */
        if (GST_BUFFER_OFFSET_END_IS_VALID (buf)) {
          valid = TRUE;
          break;
        }
      }
      if (!valid) {
        GST_LOG_OBJECT (pad->collect.pad,
            "No page timestamps in queue, can't dequeue");
        return FALSE;
      }
    }

    walk = g_slist_next (walk);
  }

  walk = mux->collect->data;
  while (walk) {
    GstOggPadData *pad = (GstOggPadData *) walk->data;

    /* any page with a granulepos of -1 can be pushed immediately.
     * TODO: it CAN be, but it seems silly to do so? */
    buf = g_queue_peek_head (pad->pagebuffers);
    while (buf && GST_BUFFER_OFFSET_END (buf) == -1) {
      GST_LOG_OBJECT (pad->collect.pad, "[gp        -1] pushing page");
      g_queue_pop_head (pad->pagebuffers);
      *flowret = gst_ogg_mux_push_buffer (mux, buf, pad);
      buf = g_queue_peek_head (pad->pagebuffers);
      ret = TRUE;
    }

    if (buf) {
      /* if no oldest buffer yet, take this one */
      if (oldest == GST_CLOCK_TIME_NONE) {
        GST_LOG_OBJECT (mux, "no oldest yet, taking buffer %p from pad %"
            GST_PTR_FORMAT " with gp time %" GST_TIME_FORMAT,
            buf, pad->collect.pad, GST_TIME_ARGS (GST_BUFFER_OFFSET (buf)));
        oldest = GST_BUFFER_OFFSET (buf);
        opad = pad;
      } else {
        /* if we have an oldest, compare with this one */
        if (GST_BUFFER_OFFSET (buf) < oldest) {
          GST_LOG_OBJECT (mux, "older buffer %p, taking from pad %"
              GST_PTR_FORMAT " with gp time %" GST_TIME_FORMAT,
              buf, pad->collect.pad, GST_TIME_ARGS (GST_BUFFER_OFFSET (buf)));
          oldest = GST_BUFFER_OFFSET (buf);
          opad = pad;
        }
      }
    }
    walk = g_slist_next (walk);
  }

  if (oldest != GST_CLOCK_TIME_NONE) {
    g_assert (opad);
    buf = g_queue_pop_head (opad->pagebuffers);
    GST_LOG_OBJECT (opad->collect.pad,
        GST_GP_FORMAT " pushing oldest page buffer %p (granulepos time %"
        GST_TIME_FORMAT ")", GST_BUFFER_OFFSET_END (buf), buf,
        GST_TIME_ARGS (GST_BUFFER_OFFSET (buf)));
    *flowret = gst_ogg_mux_push_buffer (mux, buf, opad);
    ret = TRUE;
  }

  return ret;
}

/* put the given ogg page on a per-pad queue, timestamping it correctly.
 * after that, dequeue and push as many pages as possible.
 * Caller should make sure:
 * pad->timestamp     was set with the timestamp of the first packet put
 *                    on the page
 * pad->timestamp_end was set with the timestamp + duration of the last packet
 *                    put on the page
 * pad->gp_time       was set with the time matching the gp of the last
 *                    packet put on the page
 *
 * will also reset timestamp and timestamp_end, so caller func can restart
 * counting.
 */
static GstFlowReturn
gst_ogg_mux_pad_queue_page (GstOggMux * mux, GstOggPadData * pad,
    ogg_page * page, gboolean delta)
{
  GstFlowReturn ret;
  GstBuffer *buffer = gst_ogg_mux_buffer_from_page (mux, page, delta);

  /* take the timestamp of the first packet on this page */
  GST_BUFFER_TIMESTAMP (buffer) = pad->timestamp;
  GST_BUFFER_DURATION (buffer) = pad->timestamp_end - pad->timestamp;
  /* take the gp time of the last completed packet on this page */
  GST_BUFFER_OFFSET (buffer) = pad->gp_time;

  /* the next page will start where the current page's end time leaves off */
  pad->timestamp = pad->timestamp_end;

  g_queue_push_tail (pad->pagebuffers, buffer);
  GST_LOG_OBJECT (pad->collect.pad, GST_GP_FORMAT
      " queued buffer page %p (gp time %"
      GST_TIME_FORMAT ", timestamp %" GST_TIME_FORMAT
      "), %d page buffers queued", GST_GP_CAST (ogg_page_granulepos (page)),
      buffer, GST_TIME_ARGS (GST_BUFFER_OFFSET (buffer)),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      g_queue_get_length (pad->pagebuffers));

  while (gst_ogg_mux_dequeue_page (mux, &ret)) {
    if (ret != GST_FLOW_OK)
      break;
  }

  return ret;
}

/*
 * Given two pads, compare the buffers queued on it.
 * Returns:
 *  0 if they have an equal priority
 * -1 if the first is better
 *  1 if the second is better
 * Priority decided by: a) validity, b) older timestamp, c) smaller number
 * of muxed pages
 */
static gint
gst_ogg_mux_compare_pads (GstOggMux * ogg_mux, GstOggPadData * first,
    GstOggPadData * second)
{
  guint64 firsttime, secondtime;

  /* if the first pad doesn't contain anything or is even NULL, return
   * the second pad as best candidate and vice versa */
  if (first == NULL)
    return 1;
  if (second == NULL)
    return -1;

  /* no timestamp on first buffer, it must go first */
  firsttime = GST_BUFFER_TIMESTAMP (first->buffer);
  if (firsttime == GST_CLOCK_TIME_NONE)
    return -1;

  /* no timestamp on second buffer, it must go first */
  secondtime = GST_BUFFER_TIMESTAMP (second->buffer);
  if (secondtime == GST_CLOCK_TIME_NONE)
    return 1;

  /* first buffer has higher timestamp, second one should go first */
  if (secondtime < firsttime)
    return 1;
  /* second buffer has higher timestamp, first one should go first */
  else if (secondtime > firsttime)
    return -1;
  else {
    /* buffers with equal timestamps, prefer the pad that has the
     * least number of pages muxed */
    if (second->pageno < first->pageno)
      return 1;
    else if (second->pageno > first->pageno)
      return -1;
  }

  /* same priority if all of the above failed */
  return 0;
}

static GstBuffer *
gst_ogg_mux_decorate_buffer (GstOggMux * ogg_mux, GstOggPadData * pad,
    GstBuffer * buf)
{
  GstClockTime time, end_time;
  gint64 duration, granule, limit;
  GstClockTime next_time;
  GstClockTimeDiff diff;
  GstMapInfo map;
  ogg_packet packet;
  gboolean end_clip = TRUE;
  GstAudioClippingMeta *meta;

  /* ensure messing with metadata is ok */
  buf = gst_buffer_make_writable (buf);

  /* convert time to running time, so we need no longer bother about that */
  time = GST_BUFFER_TIMESTAMP (buf);
  if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (time))) {
    time = gst_segment_to_running_time (&pad->segment, GST_FORMAT_TIME, time);
    if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time))) {
      gst_buffer_unref (buf);
      return NULL;
    } else {
      GST_BUFFER_TIMESTAMP (buf) = time;
    }
  }

  /* now come up with granulepos stuff corresponding to time */
  if (!pad->have_type ||
      pad->map.granulerate_n <= 0 || pad->map.granulerate_d <= 0)
    goto no_granule;

  gst_buffer_map (buf, &map, GST_MAP_READ);
  packet.packet = map.data;
  packet.bytes = map.size;

  gst_ogg_stream_update_stats (&pad->map, &packet);

  duration = gst_ogg_stream_get_packet_duration (&pad->map, &packet);

  gst_buffer_unmap (buf, &map);

  /* give up if no duration can be determined, relying on upstream */
  if (G_UNLIKELY (duration < 0)) {
    /* well, if some day we really could handle sparse input ... */
    if (pad->map.is_sparse) {
      limit = 1;
      diff = 2;
      goto resync;
    }
    GST_WARNING_OBJECT (pad->collect.pad,
        "failed to determine packet duration");
    goto no_granule;
  }

  /* The last packet may have clipped samples. We need to test against
   * the segment to ensure we do not use a granpos that encompasses those.
   */
  if (pad->map.audio_clipping) {
    GstAudioClippingMeta *cmeta = gst_buffer_get_audio_clipping_meta (buf);

    g_assert (!cmeta || cmeta->format == GST_FORMAT_DEFAULT);
    if (cmeta && cmeta->end && cmeta->end < duration) {
      GST_DEBUG_OBJECT (pad->collect.pad,
          "Clipping %" G_GUINT64_FORMAT " samples at the end", cmeta->end);
      duration -= cmeta->end;
      end_clip = FALSE;
    }
  }

  if (end_clip) {
    end_time =
        gst_ogg_stream_granule_to_time (&pad->map,
        pad->next_granule + duration);
    meta = gst_buffer_get_audio_clipping_meta (buf);
    if (meta && meta->end) {
      if (meta->format == GST_FORMAT_DEFAULT) {
        if (meta->end > duration) {
          GST_WARNING_OBJECT (pad->collect.pad,
              "Clip meta tries to clip more sample than exist in the buffer, clipping all");
          duration = 0;
        } else {
          duration -= meta->end;
        }
      } else {
        GST_WARNING_OBJECT (pad->collect.pad,
            "Unsupported format in clip meta");
      }
    }
    if (end_time > pad->segment.stop
        && !GST_CLOCK_TIME_IS_VALID (gst_segment_to_running_time (&pad->segment,
                GST_FORMAT_TIME, pad->segment.start + end_time))) {
      gint64 actual_duration =
          gst_util_uint64_scale_round (pad->segment.stop - time,
          pad->map.granulerate_n,
          GST_SECOND * pad->map.granulerate_d);
      GST_INFO_OBJECT (ogg_mux,
          "Got clipped last packet of duration %" G_GINT64_FORMAT " (%"
          G_GINT64_FORMAT " clipped)", actual_duration,
          duration - actual_duration);
      duration = actual_duration;
    }
  }

  GST_LOG_OBJECT (pad->collect.pad, "buffer ts %" GST_TIME_FORMAT
      ", duration %" GST_TIME_FORMAT ", granule duration %" G_GINT64_FORMAT,
      GST_TIME_ARGS (time), GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
      duration);

  /* determine granule corresponding to time,
   * using the inverse of oggdemux' granule -> time */

  /* see if interpolated granule matches good enough */
  granule = pad->next_granule;
  next_time = gst_ogg_stream_granule_to_time (&pad->map, pad->next_granule);
  diff = GST_CLOCK_DIFF (next_time, time);

  /* we tolerate deviation up to configured or within granule granularity */
  limit = gst_ogg_stream_granule_to_time (&pad->map, 1) / 2;
  limit = MAX (limit, ogg_mux->max_tolerance);

  GST_LOG_OBJECT (pad->collect.pad, "expected granule %" G_GINT64_FORMAT " == "
      "time %" GST_TIME_FORMAT " --> ts diff %" GST_STIME_FORMAT
      " < tolerance %" GST_TIME_FORMAT " (?)",
      granule, GST_TIME_ARGS (next_time), GST_STIME_ARGS (diff),
      GST_TIME_ARGS (limit));

resync:
  /* if not good enough, determine granule based on time */
  if (diff > limit || diff < -limit) {
    granule = gst_util_uint64_scale_round (time, pad->map.granulerate_n,
        GST_SECOND * pad->map.granulerate_d);
    GST_DEBUG_OBJECT (pad->collect.pad,
        "resyncing to determined granule %" G_GINT64_FORMAT, granule);
  }

  if (pad->map.is_ogm || pad->map.is_sparse) {
    pad->next_granule = granule;
  } else {
    granule += duration;
    pad->next_granule = granule;
  }

  /* track previous keyframe */
  if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT))
    pad->keyframe_granule = granule;

  /* determine corresponding time and granulepos */
  GST_BUFFER_OFFSET (buf) = gst_ogg_stream_granule_to_time (&pad->map, granule);
  GST_BUFFER_OFFSET_END (buf) =
      gst_ogg_stream_granule_to_granulepos (&pad->map, granule,
      pad->keyframe_granule);

  GST_LOG_OBJECT (pad->collect.pad,
      GST_GP_FORMAT " decorated buffer %p (granulepos time %" GST_TIME_FORMAT
      ")", GST_BUFFER_OFFSET_END (buf), buf,
      GST_TIME_ARGS (GST_BUFFER_OFFSET (buf)));

  return buf;

  /* ERRORS */
no_granule:
  {
    GST_DEBUG_OBJECT (pad->collect.pad, "could not determine granulepos, "
        "falling back to upstream provided metadata");
    return buf;
  }
}


/* make sure at least one buffer is queued on all pads, two if possible
 * 
 * if pad->buffer == NULL, pad->next_buffer !=  NULL, then
 *   we do not know if the buffer is the last or not
 * if pad->buffer != NULL, pad->next_buffer != NULL, then
 *   pad->buffer is not the last buffer for the pad
 * if pad->buffer != NULL, pad->next_buffer == NULL, then
 *   pad->buffer if the last buffer for the pad
 * 
 * returns a pointer to an oggpad that holds the best buffer, or
 * NULL when no pad was usable. "best" means the buffer marked
 * with the lowest timestamp. If best->buffer == NULL then either
 * we're at EOS (popped = FALSE), or a buffer got dropped, so retry. */
static GstOggPadData *
gst_ogg_mux_queue_pads (GstOggMux * ogg_mux, gboolean * popped)
{
  GstOggPadData *bestpad = NULL;
  GSList *walk;

  *popped = FALSE;

  /* try to make sure we have a buffer from each usable pad first */
  walk = ogg_mux->collect->data;
  while (walk) {
    GstOggPadData *pad;
    GstCollectData *data;

    data = (GstCollectData *) walk->data;
    pad = (GstOggPadData *) data;

    walk = g_slist_next (walk);

    GST_LOG_OBJECT (data->pad, "looking at pad for buffer");

    /* try to get a new buffer for this pad if needed and possible */
    if (pad->buffer == NULL) {
      GstBuffer *buf;

      buf = gst_collect_pads_pop (ogg_mux->collect, data);
      GST_LOG_OBJECT (data->pad, "popped buffer %" GST_PTR_FORMAT, buf);

      /* On EOS we get a NULL buffer */
      if (buf != NULL) {
        *popped = TRUE;

        if (ogg_mux->delta_pad == NULL &&
            GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT))
          ogg_mux->delta_pad = pad;

        /* if we need headers */
        if (pad->state == GST_OGG_PAD_STATE_CONTROL) {
          /* and we have one */
          ogg_packet packet;
          gboolean is_header;
          GstMapInfo map;

          gst_buffer_map (buf, &map, GST_MAP_READ);
          packet.packet = map.data;
          packet.bytes = map.size;

          /* if we're not yet in data mode, ensure we're setup on the first packet */
          if (!pad->have_type) {
            GstCaps *caps;

            /* Use headers in caps, if any; this will allow us to be resilient
             * to starting streams on the fly, and some streams (like VP8
             * at least) do not send headers packets, as other muxers don't
             * expect/need them. */
            caps = gst_pad_get_current_caps (GST_PAD_CAST (data->pad));
            GST_DEBUG_OBJECT (data->pad, "checking caps: %" GST_PTR_FORMAT,
                caps);

            pad->have_type =
                gst_ogg_stream_setup_map_from_caps_headers (&pad->map, caps);

            if (!pad->have_type) {
              /* fallback on the packet */
              pad->have_type = gst_ogg_stream_setup_map (&pad->map, &packet);
            }
            if (!pad->have_type) {
              /* fallback 2 to try to get the mapping from the caps */
              pad->have_type =
                  gst_ogg_stream_setup_map_from_caps (&pad->map, caps);
            }
            if (!pad->have_type) {
              GST_ERROR_OBJECT (data->pad,
                  "mapper didn't recognise input stream " "(pad caps: %"
                  GST_PTR_FORMAT ")", caps);
            } else {
              GST_DEBUG_OBJECT (data->pad, "caps detected: %" GST_PTR_FORMAT,
                  pad->map.caps);

              if (pad->map.is_sparse) {
                GST_DEBUG_OBJECT (data->pad, "Pad is sparse, marking as such");
                gst_collect_pads_set_waiting (ogg_mux->collect,
                    (GstCollectData *) pad, FALSE);
              }

              if (pad->map.is_video && ogg_mux->delta_pad == NULL) {
                ogg_mux->delta_pad = pad;
                GST_INFO_OBJECT (data->pad, "selected delta pad");
              }
            }
            if (caps)
              gst_caps_unref (caps);
          }

          if (pad->have_type)
            is_header = gst_ogg_stream_packet_is_header (&pad->map, &packet);
          else                  /* fallback (FIXME 0.11: remove IN_CAPS hack) */
            is_header = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_HEADER);

          gst_buffer_unmap (buf, &map);

          if (is_header) {
            GST_DEBUG_OBJECT (ogg_mux,
                "got header buffer in control state, ignoring");
            /* just ignore */
            pad->map.n_header_packets_seen++;
            gst_buffer_unref (buf);
            buf = NULL;
          } else {
            GST_DEBUG_OBJECT (ogg_mux,
                "got data buffer in control state, switching to data mode");
            /* this is a data buffer so switch to data state */
            pad->state = GST_OGG_PAD_STATE_DATA;

            /* check if this type of stream allows generating granulepos
             * metadata here, if not, upstream will have to provide */
            if (gst_ogg_stream_granule_to_granulepos (&pad->map, 1, 1) < 0) {
              GST_WARNING_OBJECT (data->pad, "can not generate metadata; "
                  "relying on upstream");
              /* disable metadata code path, otherwise not used anyway */
              pad->map.granulerate_n = 0;
            }
          }
        }

        /* so now we should have a real data packet;
         * see that it is properly decorated */
        if (G_LIKELY (buf)) {
          buf = gst_ogg_mux_decorate_buffer (ogg_mux, pad, buf);
          if (G_UNLIKELY (!buf))
            GST_DEBUG_OBJECT (data->pad, "buffer clipped");
        }
      }

      pad->buffer = buf;
    }

    /* we should have a buffer now, see if it is the best pad to
     * pull on. Our best pad can't be eos */
    if (pad->buffer && !pad->eos) {
      if (gst_ogg_mux_compare_pads (ogg_mux, bestpad, pad) > 0) {
        GST_LOG_OBJECT (data->pad,
            "new best pad, with buffer %" GST_PTR_FORMAT, pad->buffer);

        bestpad = pad;
      }
    }
  }

  return bestpad;
}

static GList *
gst_ogg_mux_get_headers (GstOggPadData * pad)
{
  GList *res = NULL;
  GstStructure *structure;
  GstCaps *caps;
  const GValue *streamheader;
  GstPad *thepad;
  GstBuffer *header;

  thepad = pad->collect.pad;

  GST_LOG_OBJECT (thepad, "getting headers");

  caps = gst_pad_get_current_caps (thepad);
  if (caps == NULL) {
    GST_INFO_OBJECT (thepad, "got empty caps as negotiated format");
    return NULL;
  }

  structure = gst_caps_get_structure (caps, 0);
  streamheader = gst_structure_get_value (structure, "streamheader");
  if (streamheader != NULL) {
    GST_LOG_OBJECT (thepad, "got header");
    if (G_VALUE_TYPE (streamheader) == GST_TYPE_ARRAY) {
      GArray *bufarr = g_value_peek_pointer (streamheader);
      gint i;

      GST_LOG_OBJECT (thepad, "got fixed list");

      for (i = 0; i < bufarr->len; i++) {
        GValue *bufval = &g_array_index (bufarr, GValue, i);

        GST_LOG_OBJECT (thepad, "item %d", i);
        if (G_VALUE_TYPE (bufval) == GST_TYPE_BUFFER) {
          GstBuffer *buf = g_value_peek_pointer (bufval);

          GST_LOG_OBJECT (thepad, "adding item %d to header list", i);

          gst_buffer_ref (buf);
          res = g_list_append (res, buf);
        }
      }
    } else {
      GST_LOG_OBJECT (thepad, "streamheader is not fixed list");
    }

  } else if (gst_structure_has_name (structure, "video/x-dirac")) {
    res = g_list_append (res, pad->buffer);
    pad->buffer = NULL;
  } else if (pad->have_type
      && (header = gst_ogg_stream_get_headers (&pad->map))) {
    res = g_list_append (res, header);
  } else {
    GST_LOG_OBJECT (thepad, "caps don't have streamheader");
  }
  gst_caps_unref (caps);

  return res;
}

static GstCaps *
gst_ogg_mux_set_header_on_caps (GstCaps * caps, GList * buffers)
{
  GstStructure *structure;
  GValue array = { 0 };
  GList *walk = buffers;

  caps = gst_caps_make_writable (caps);

  structure = gst_caps_get_structure (caps, 0);

  /* put buffers in a fixed list */
  g_value_init (&array, GST_TYPE_ARRAY);

  while (walk) {
    GstBuffer *buf = GST_BUFFER (walk->data);
    GValue value = { 0 };

    walk = walk->next;

    /* mark buffer */
    GST_LOG ("Setting HEADER on buffer of length %" G_GSIZE_FORMAT,
        gst_buffer_get_size (buf));
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);

    g_value_init (&value, GST_TYPE_BUFFER);
    gst_value_set_buffer (&value, buf);
    gst_value_array_append_value (&array, &value);
    g_value_unset (&value);
  }
  gst_structure_take_value (structure, "streamheader", &array);

  return caps;
}

static void
gst_ogg_mux_create_header_packet_with_flags (ogg_packet * packet,
    gboolean bos, gboolean eos)
{
  packet->granulepos = 0;
  /* mark BOS and packet number */
  packet->b_o_s = bos;
  /* mark EOS */
  packet->e_o_s = eos;
}

static void
gst_ogg_mux_create_header_packet (ogg_packet * packet, GstOggPadData * pad)
{
  gst_ogg_mux_create_header_packet_with_flags (packet, pad->packetno == 0, 0);
  packet->packetno = pad->packetno++;
}

static void
gst_ogg_mux_submit_skeleton_header_packet (GstOggMux * mux,
    ogg_stream_state * os, GstBuffer * buf, gboolean bos, gboolean eos)
{
  ogg_packet packet;
  GstMapInfo map;

  gst_buffer_map (buf, &map, GST_MAP_READ);
  packet.packet = map.data;
  packet.bytes = map.size;
  gst_ogg_mux_create_header_packet_with_flags (&packet, bos, eos);
  ogg_stream_packetin (os, &packet);
  gst_buffer_unmap (buf, &map);
  gst_buffer_unref (buf);
}

static void
gst_ogg_mux_make_fishead (GstOggMux * mux, ogg_stream_state * os)
{
  GstByteWriter bw;
  GstBuffer *fishead;
  gboolean handled = TRUE;

  GST_DEBUG_OBJECT (mux, "Creating fishead");

  gst_byte_writer_init_with_size (&bw, 64, TRUE);
  handled &= gst_byte_writer_put_string_utf8 (&bw, "fishead");
  handled &= gst_byte_writer_put_int16_le (&bw, 3);     /* version major */
  handled &= gst_byte_writer_put_int16_le (&bw, 0);     /* version minor */
  handled &= gst_byte_writer_put_int64_le (&bw, 0);     /* presentation time numerator */
  handled &= gst_byte_writer_put_int64_le (&bw, 1000);  /* ...and denominator */
  handled &= gst_byte_writer_put_int64_le (&bw, 0);     /* base time numerator */
  handled &= gst_byte_writer_put_int64_le (&bw, 1000);  /* ...and denominator */
  handled &= gst_byte_writer_fill (&bw, ' ', 20);       /* UTC time */
  g_assert (handled && gst_byte_writer_get_pos (&bw) == 64);
  fishead = gst_byte_writer_reset_and_get_buffer (&bw);
  gst_ogg_mux_submit_skeleton_header_packet (mux, os, fishead, 1, 0);
}

static void
gst_ogg_mux_byte_writer_put_string_utf8 (GstByteWriter * bw, const char *s)
{
  if (!gst_byte_writer_put_data (bw, (const guint8 *) s, strlen (s)))
    GST_ERROR ("put_data failed");
}

static void
gst_ogg_mux_add_fisbone_message_header (GstOggMux * mux, GstByteWriter * bw,
    const char *tag, const char *value)
{
  /* It is valid to pass NULL as the value to omit the tag */
  if (!value)
    return;
  GST_DEBUG_OBJECT (mux, "Adding fisbone message header %s: %s", tag, value);
  gst_ogg_mux_byte_writer_put_string_utf8 (bw, tag);
  gst_ogg_mux_byte_writer_put_string_utf8 (bw, ": ");
  gst_ogg_mux_byte_writer_put_string_utf8 (bw, value);
  gst_ogg_mux_byte_writer_put_string_utf8 (bw, "\r\n");
}

static void
gst_ogg_mux_add_fisbone_message_header_from_tags (GstOggMux * mux,
    GstByteWriter * bw, const char *header, const char *tag,
    const GstTagList * tags)
{
  GString *s;
  guint size = gst_tag_list_get_tag_size (tags, tag), n;
  GST_DEBUG_OBJECT (mux, "Found %u tags for name %s", size, tag);
  if (size == 0)
    return;
  s = g_string_new ("");
  for (n = 0; n < size; ++n) {
    gchar *tmp;
    if (n)
      g_string_append (s, ", ");
    if (gst_tag_list_get_string_index (tags, tag, n, &tmp)) {
      g_string_append (s, tmp);
      g_free (tmp);
    } else {
      GST_WARNING_OBJECT (mux, "Tag %s index %u was not found (%u total)", tag,
          n, size);
    }
  }
  gst_ogg_mux_add_fisbone_message_header (mux, bw, header, s->str);
  g_string_free (s, TRUE);
}

/* This is a basic placeholder to generate roles for the tracks.
   For tracks with more than one video, both video tracks will get
   tagged with a "video/main" role, but we have no way of knowing
   which one is the main one, if any. We could just pick one. For
   audio, it's more complicated as we don't know which is music,
   which is dubbing, etc. For kate, we could take a pretty good
   guess based on the category, as role essentially is category.
   For now, leave this as is. */
static const char *
gst_ogg_mux_get_default_role (GstOggPadData * pad)
{
  const char *type = gst_ogg_stream_get_media_type (&pad->map);
  if (type) {
    if (!strncmp (type, "video/", strlen ("video/")))
      return "video/main";
    if (!strncmp (type, "audio/", strlen ("audio/")))
      return "audio/main";
    if (!strcmp (type + strlen (type) - strlen ("kate"), "kate"))
      return "text/caption";
  }
  return NULL;
}

static void
gst_ogg_mux_make_fisbone (GstOggMux * mux, ogg_stream_state * os,
    GstOggPadData * pad)
{
  GstByteWriter bw;
  gboolean handled = TRUE;

  GST_DEBUG_OBJECT (mux,
      "Creating %s fisbone for serial %08x",
      gst_ogg_stream_get_media_type (&pad->map), pad->map.serialno);

  gst_byte_writer_init (&bw);
  handled &= gst_byte_writer_put_string_utf8 (&bw, "fisbone");
  handled &= gst_byte_writer_put_int32_le (&bw, 44);    /* offset to message headers */
  handled &= gst_byte_writer_put_uint32_le (&bw, pad->map.serialno);
  handled &= gst_byte_writer_put_uint32_le (&bw, pad->map.n_header_packets);
  handled &= gst_byte_writer_put_uint64_le (&bw, pad->map.granulerate_n);
  handled &= gst_byte_writer_put_uint64_le (&bw, pad->map.granulerate_d);
  handled &= gst_byte_writer_put_uint64_le (&bw, 0);    /* base granule */
  handled &= gst_byte_writer_put_uint32_le (&bw, pad->map.preroll);
  handled &= gst_byte_writer_put_uint8 (&bw, pad->map.granuleshift);
  handled &= gst_byte_writer_fill (&bw, 0, 3);  /* padding */
  /* message header fields - MIME type for now */
  gst_ogg_mux_add_fisbone_message_header (mux, &bw, "Content-Type",
      gst_ogg_stream_get_media_type (&pad->map));
  gst_ogg_mux_add_fisbone_message_header (mux, &bw, "Role",
      gst_ogg_mux_get_default_role (pad));
  gst_ogg_mux_add_fisbone_message_header_from_tags (mux, &bw, "Language",
      GST_TAG_LANGUAGE_CODE, pad->tags);
  gst_ogg_mux_add_fisbone_message_header_from_tags (mux, &bw, "Title",
      GST_TAG_TITLE, pad->tags);

  if (G_UNLIKELY (!handled))
    GST_WARNING_OBJECT (mux, "Error writing fishbon");

  gst_ogg_mux_submit_skeleton_header_packet (mux, os,
      gst_byte_writer_reset_and_get_buffer (&bw), 0, 0);
}

static void
gst_ogg_mux_make_fistail (GstOggMux * mux, ogg_stream_state * os)
{
  GST_DEBUG_OBJECT (mux, "Creating fistail");

  gst_ogg_mux_submit_skeleton_header_packet (mux, os,
      gst_buffer_new_and_alloc (0), 0, 1);
}

/*
 * For each pad we need to write out one (small) header in one
 * page that allows decoders to identify the type of the stream.
 * After that we need to write out all extra info for the decoders.
 * In the case of a codec that also needs data as configuration, we can
 * find that info in the streamcaps. 
 * After writing the headers we must start a new page for the data.
 */
static GstFlowReturn
gst_ogg_mux_send_headers (GstOggMux * mux)
{
  GSList *walk;
  GList *hbufs, *hwalk;
  GstCaps *caps;
  GstFlowReturn ret;
  ogg_page page;
  ogg_stream_state skeleton_stream;

  hbufs = NULL;
  ret = GST_FLOW_OK;

  GST_LOG_OBJECT (mux, "collecting headers");

  walk = mux->collect->data;
  while (walk) {
    GstOggPadData *pad;
    GstPad *thepad;

    pad = (GstOggPadData *) walk->data;
    thepad = pad->collect.pad;

    walk = g_slist_next (walk);

    GST_LOG_OBJECT (mux, "looking at pad %s:%s", GST_DEBUG_PAD_NAME (thepad));

    /* if the pad has no buffer and is not sparse, we don't care */
    if (pad->buffer == NULL && !pad->map.is_sparse)
      continue;

    /* now figure out the headers */
    pad->map.headers = gst_ogg_mux_get_headers (pad);
  }

  GST_LOG_OBJECT (mux, "creating BOS pages");
  walk = mux->collect->data;
  while (walk) {
    GstOggPadData *pad;
    GstBuffer *buf;
    ogg_packet packet;
    GstPad *thepad;
    GstBuffer *hbuf;
    GstMapInfo map;
    GstCaps *caps;
    const gchar *mime_type = "";

    pad = (GstOggPadData *) walk->data;
    thepad = pad->collect.pad;
    walk = walk->next;

    pad->packetno = 0;

    GST_LOG_OBJECT (thepad, "looping over headers");

    if (pad->map.headers) {
      buf = GST_BUFFER (pad->map.headers->data);
      pad->map.headers = g_list_remove (pad->map.headers, buf);
    } else if (pad->buffer) {
      buf = pad->buffer;
      gst_buffer_ref (buf);
    } else {
      /* fixme -- should be caught in the previous list traversal. */
      GST_OBJECT_LOCK (thepad);
      g_critical ("No headers or buffers on pad %s:%s",
          GST_DEBUG_PAD_NAME (thepad));
      GST_OBJECT_UNLOCK (thepad);
      continue;
    }

    if ((caps = gst_pad_get_current_caps (thepad))) {
      GstStructure *structure = gst_caps_get_structure (caps, 0);
      mime_type = gst_structure_get_name (structure);
    } else {
      GST_INFO_OBJECT (thepad, "got empty caps as negotiated format");
    }

    /* create a packet from the buffer */
    gst_buffer_map (buf, &map, GST_MAP_READ);
    packet.packet = map.data;
    packet.bytes = map.size;

    gst_ogg_mux_create_header_packet (&packet, pad);

    /* swap the packet in */
    ogg_stream_packetin (&pad->map.stream, &packet);

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

    GST_LOG_OBJECT (thepad, "flushing out BOS page");
    if (!ogg_stream_flush (&pad->map.stream, &page))
      g_critical ("Could not flush BOS page");

    hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);

    GST_LOG_OBJECT (mux, "swapped out page with mime type '%s'", mime_type);

    /* quick hack: put video pages at the front.
     * Ideally, we would have a settable enum for which Ogg
     * profile we work with, and order based on that.
     * (FIXME: if there is more than one video stream, shouldn't we only put
     * one's BOS into the first page, followed by an audio stream's BOS, and
     * only then followed by the remaining video and audio streams?) */
    if (pad->map.is_video) {
      GST_DEBUG_OBJECT (thepad, "putting %s page at the front", mime_type);
      hbufs = g_list_prepend (hbufs, hbuf);
    } else {
      hbufs = g_list_append (hbufs, hbuf);
    }

    if (caps) {
      gst_caps_unref (caps);
    }
  }

  /* The Skeleton BOS goes first - even before the video that went first before */
  if (mux->use_skeleton) {
    ogg_stream_init (&skeleton_stream, gst_ogg_mux_generate_serialno (mux));
    gst_ogg_mux_make_fishead (mux, &skeleton_stream);
    while (ogg_stream_flush (&skeleton_stream, &page) > 0) {
      GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);
      hbufs = g_list_append (hbufs, hbuf);
    }
  }

  GST_LOG_OBJECT (mux, "creating next headers");
  walk = mux->collect->data;
  while (walk) {
    GstOggPadData *pad;
    GstPad *thepad;

    pad = (GstOggPadData *) walk->data;
    thepad = pad->collect.pad;

    walk = walk->next;

    if (mux->use_skeleton)
      gst_ogg_mux_make_fisbone (mux, &skeleton_stream, pad);

    GST_LOG_OBJECT (mux, "looping over headers for pad %s:%s",
        GST_DEBUG_PAD_NAME (thepad));

    hwalk = pad->map.headers;
    while (hwalk) {
      GstBuffer *buf = GST_BUFFER (hwalk->data);
      ogg_packet packet;
      ogg_page page;
      GstMapInfo map;

      hwalk = hwalk->next;

      /* create a packet from the buffer */
      gst_buffer_map (buf, &map, GST_MAP_READ);
      packet.packet = map.data;
      packet.bytes = map.size;

      gst_ogg_mux_create_header_packet (&packet, pad);

      /* swap the packet in */
      ogg_stream_packetin (&pad->map.stream, &packet);
      gst_buffer_unmap (buf, &map);
      gst_buffer_unref (buf);

      /* if last header, flush page */
      if (hwalk == NULL) {
        GST_LOG_OBJECT (mux,
            "flushing page as packet %" G_GUINT64_FORMAT " is first or "
            "last packet", (guint64) packet.packetno);
        while (ogg_stream_flush (&pad->map.stream, &page)) {
          GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);

          GST_LOG_OBJECT (mux, "swapped out page");
          hbufs = g_list_append (hbufs, hbuf);
        }
      } else {
        GST_LOG_OBJECT (mux, "try to swap out page");
        /* just try to swap out a page then */
        while (ogg_stream_pageout (&pad->map.stream, &page) > 0) {
          GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);

          GST_LOG_OBJECT (mux, "swapped out page");
          hbufs = g_list_append (hbufs, hbuf);
        }
      }
    }
    g_list_free (pad->map.headers);
    pad->map.headers = NULL;
  }

  if (mux->use_skeleton) {
    /* flush accumulated fisbones, the fistail must be on a separate page */
    while (ogg_stream_flush (&skeleton_stream, &page) > 0) {
      GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);
      hbufs = g_list_append (hbufs, hbuf);
    }
    gst_ogg_mux_make_fistail (mux, &skeleton_stream);
    while (ogg_stream_flush (&skeleton_stream, &page) > 0) {
      GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE);
      hbufs = g_list_append (hbufs, hbuf);
    }
    ogg_stream_clear (&skeleton_stream);
  }

  /* hbufs holds all buffers for the headers now */

  /* create caps with the buffers */
  /* FIXME: should prefer media type audio/ogg, video/ogg, etc. depending on
   * what we create, if acceptable downstream (instead of defaulting to
   * application/ogg because that's the first in the template caps) */
  caps = gst_pad_get_allowed_caps (mux->srcpad);
  if (caps) {
    if (!gst_caps_is_fixed (caps))
      caps = gst_caps_fixate (caps);
  }
  if (!caps)
    caps = gst_caps_new_empty_simple ("application/ogg");

  caps = gst_ogg_mux_set_header_on_caps (caps, hbufs);
  gst_pad_set_caps (mux->srcpad, caps);
  gst_caps_unref (caps);

  /* Send segment event */
  {
    GstSegment segment;
    gst_segment_init (&segment, GST_FORMAT_TIME);
    gst_pad_push_event (mux->srcpad, gst_event_new_segment (&segment));
  }

  /* and send the buffers */
  while (hbufs != NULL) {
    GstBuffer *buf = GST_BUFFER (hbufs->data);

    hbufs = g_list_delete_link (hbufs, hbufs);

    if ((ret = gst_ogg_mux_push_buffer (mux, buf, NULL)) != GST_FLOW_OK)
      break;
  }
  /* free any remaining nodes/buffers in case we couldn't push them */
  g_list_foreach (hbufs, (GFunc) gst_mini_object_unref, NULL);
  g_list_free (hbufs);

  return ret;
}

/* this function is called to process data on the best pending pad.
 *
 * basic idea:
 *
 * 1) store the selected pad and keep on pulling until we fill a
 *    complete ogg page or the ogg page is filled above the max-delay
 *    threshold. This is needed because the ogg spec says that
 *    you should fill a complete page with data from the same logical
 *    stream. When the page is filled, go back to 1).
 * 2) before filling a page, read ahead one more buffer to see if this
 *    packet is the last of the stream. We need to do this because the ogg
 *    spec mandates that the last packet should have the EOS flag set before
 *    sending it to ogg. if pad->buffer is NULL we need to wait to find out
 *    whether there are any more buffers.
 * 3) pages get queued on a per-pad queue. Every time a page is queued, a
 *    dequeue is called, which will dequeue the oldest page on any pad, provided
 *    that ALL pads have at least one marked page in the queue (or remaining
 *    pads are at EOS)
 */
static GstFlowReturn
gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
{
  GstFlowReturn ret = GST_FLOW_OK;
  gboolean delta_unit;
  gint64 granulepos = 0;
  GstClockTime timestamp, gp_time;
  GstBuffer *next_buf;

  GST_LOG_OBJECT (ogg_mux, "best pad %" GST_PTR_FORMAT
      ", currently pulling from %" GST_PTR_FORMAT, best->collect.pad,
      ogg_mux->pulling ? ogg_mux->pulling->collect.pad : NULL);

  if (ogg_mux->pulling) {
    next_buf = gst_collect_pads_peek (ogg_mux->collect,
        &ogg_mux->pulling->collect);
    if (next_buf) {
      ogg_mux->pulling->eos = FALSE;
      gst_buffer_unref (next_buf);
    } else if (!ogg_mux->pulling->map.is_sparse) {
      GST_DEBUG_OBJECT (ogg_mux->pulling->collect.pad, "setting eos to true");
      ogg_mux->pulling->eos = TRUE;
    }
  }

  /* We could end up pushing from the best pad instead, so check that
   * as well */
  if (best && best != ogg_mux->pulling) {
    next_buf = gst_collect_pads_peek (ogg_mux->collect, &best->collect);
    if (next_buf) {
      best->eos = FALSE;
      gst_buffer_unref (next_buf);
    } else if (!best->map.is_sparse) {
      GST_DEBUG_OBJECT (best->collect.pad, "setting eos to true");
      best->eos = TRUE;
    }
  }

  /* if we were already pulling from one pad, but the new "best" buffer is
   * from another pad, we need to check if we have reason to flush a page
   * for the pad we were pulling from before */
  if (ogg_mux->pulling && best &&
      ogg_mux->pulling != best && ogg_mux->pulling->buffer) {
    GstOggPadData *pad = ogg_mux->pulling;
    GstClockTime last_ts = GST_BUFFER_END_TIME (pad->buffer);

    /* if the next packet in the current page is going to make the page
     * too long, we need to flush */
    if (last_ts > ogg_mux->next_ts + ogg_mux->max_delay) {
      ogg_page page;

      GST_LOG_OBJECT (pad->collect.pad,
          GST_GP_FORMAT " stored packet %" G_GINT64_FORMAT
          " will make page too long, flushing",
          GST_BUFFER_OFFSET_END (pad->buffer),
          (gint64) pad->map.stream.packetno);

      while (ogg_stream_flush (&pad->map.stream, &page)) {
        /* end time of this page is the timestamp of the next buffer */
        ogg_mux->pulling->timestamp_end = GST_BUFFER_TIMESTAMP (pad->buffer);
        /* Place page into the per-pad queue */
        ret = gst_ogg_mux_pad_queue_page (ogg_mux, pad, &page,
            pad->first_delta);
        /* increment the page number counter */
        pad->pageno++;
        /* mark other pages as delta */
        pad->first_delta = TRUE;
      }
      pad->new_page = TRUE;
      ogg_mux->pulling = NULL;
    }
  }

  /* if we don't know which pad to pull on, use the best one */
  if (ogg_mux->pulling == NULL) {
    ogg_mux->pulling = best;
    GST_LOG_OBJECT (ogg_mux->pulling->collect.pad, "pulling from best pad");

    /* remember timestamp and gp time of first buffer for this new pad */
    if (ogg_mux->pulling != NULL) {
      ogg_mux->next_ts = GST_BUFFER_TIMESTAMP (ogg_mux->pulling->buffer);
      GST_LOG_OBJECT (ogg_mux->pulling->collect.pad, "updated times, next ts %"
          GST_TIME_FORMAT, GST_TIME_ARGS (ogg_mux->next_ts));
    } else {
      GST_LOG_OBJECT (ogg_mux->srcpad, "sending EOS");
      /* no pad to pull on, send EOS */
      gst_pad_push_event (ogg_mux->srcpad, gst_event_new_eos ());
      return GST_FLOW_FLUSHING;
    }
  }

  if (ogg_mux->need_headers) {
    ret = gst_ogg_mux_send_headers (ogg_mux);
    ogg_mux->need_headers = FALSE;
  }

  /* we are pulling from a pad, continue to do so until a page
   * has been filled and queued */
  if (ogg_mux->pulling != NULL) {
    ogg_packet packet;
    ogg_page page;
    GstBuffer *buf, *tmpbuf;
    GstOggPadData *pad = ogg_mux->pulling;
    gint64 duration;
    gboolean force_flush;
    GstMapInfo map;

    GST_LOG_OBJECT (ogg_mux->pulling->collect.pad, "pulling from pad");

    /* now see if we have a buffer */
    buf = pad->buffer;
    if (buf == NULL) {
      GST_DEBUG_OBJECT (ogg_mux, "pad was EOS");
      ogg_mux->pulling = NULL;
      return GST_FLOW_OK;
    }

    delta_unit = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
    duration = GST_BUFFER_DURATION (buf);

    /* if the current "next timestamp" on the pad is unset, then this is the
     * first packet on the new page.  Update our pad's page timestamp */
    if (ogg_mux->pulling->timestamp == GST_CLOCK_TIME_NONE) {
      ogg_mux->pulling->timestamp = GST_BUFFER_TIMESTAMP (buf);
      GST_LOG_OBJECT (ogg_mux->pulling->collect.pad,
          "updated pad timestamp to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
    }
    /* create a packet from the buffer */
    gst_buffer_map (buf, &map, GST_MAP_READ);
    packet.packet = map.data;
    packet.bytes = map.size;
    packet.granulepos = GST_BUFFER_OFFSET_END (buf);
    if (packet.granulepos == -1)
      packet.granulepos = 0;
    /* mark BOS and packet number */
    packet.b_o_s = (pad->packetno == 0);
    packet.packetno = pad->packetno++;
    GST_LOG_OBJECT (pad->collect.pad, GST_GP_FORMAT
        " packet %" G_GINT64_FORMAT " (%ld bytes) created from buffer",
        GST_GP_CAST (packet.granulepos), (gint64) packet.packetno,
        packet.bytes);

    packet.e_o_s = ogg_mux->pulling->eos ? 1 : 0;
    tmpbuf = NULL;

    /* we flush when we see a new keyframe */
    force_flush = (pad->prev_delta && !delta_unit)
        || pad->map.always_flush_page;
    if (duration != -1) {
      pad->duration += duration;
      /* if page duration exceeds max, flush page */
      if (pad->duration > ogg_mux->max_page_delay) {
        force_flush = TRUE;
        pad->duration = 0;
      }
    }

    if (GST_BUFFER_IS_DISCONT (buf)) {
      if (pad->data_pushed) {
        GST_LOG_OBJECT (pad->collect.pad, "got discont");
        packet.packetno++;
        /* No public API for this; hack things in */
        pad->map.stream.pageno++;
        force_flush = TRUE;
      } else {
        GST_LOG_OBJECT (pad->collect.pad, "discont at stream start");
      }
    }

    /* flush the currently built page if necessary */
    if (force_flush) {
      GST_LOG_OBJECT (pad->collect.pad,
          GST_GP_FORMAT " forced flush of page before this packet",
          GST_BUFFER_OFFSET_END (pad->buffer));
      while (ogg_stream_flush (&pad->map.stream, &page)) {
        /* end time of this page is the timestamp of the next buffer */
        ogg_mux->pulling->timestamp_end = GST_BUFFER_TIMESTAMP (pad->buffer);
        ret = gst_ogg_mux_pad_queue_page (ogg_mux, pad, &page,
            pad->first_delta);

        /* increment the page number counter */
        pad->pageno++;
        /* mark other pages as delta */
        pad->first_delta = TRUE;
      }
      pad->new_page = TRUE;
    }

    /* if this is the first packet of a new page figure out the delta flag */
    if (pad->new_page) {
      if (delta_unit) {
        /* mark the page as delta */
        pad->first_delta = TRUE;
      } else {
        /* got a keyframe */
        if (ogg_mux->delta_pad == pad) {
          /* if we get it on the pad with deltaunits,
           * we mark the page as non delta */
          pad->first_delta = FALSE;
        } else if (ogg_mux->delta_pad != NULL) {
          /* if there are pads with delta frames, we
           * must mark this one as delta */
          pad->first_delta = TRUE;
        } else {
          pad->first_delta = FALSE;
        }
      }
      pad->new_page = FALSE;
    }

    /* save key unit to track delta->key unit transitions */
    pad->prev_delta = delta_unit;

    /* swap the packet in */
    if (packet.e_o_s == 1)
      GST_DEBUG_OBJECT (pad->collect.pad, "swapping in EOS packet");
    if (packet.b_o_s == 1)
      GST_DEBUG_OBJECT (pad->collect.pad, "swapping in BOS packet");

    ogg_stream_packetin (&pad->map.stream, &packet);
    gst_buffer_unmap (buf, &map);
    pad->data_pushed = TRUE;

    gp_time = GST_BUFFER_OFFSET (pad->buffer);
    granulepos = GST_BUFFER_OFFSET_END (pad->buffer);
    timestamp = GST_BUFFER_TIMESTAMP (pad->buffer);

    GST_LOG_OBJECT (pad->collect.pad,
        GST_GP_FORMAT " packet %" G_GINT64_FORMAT ", gp time %"
        GST_TIME_FORMAT ", timestamp %" GST_TIME_FORMAT " packetin'd",
        granulepos, (gint64) packet.packetno, GST_TIME_ARGS (gp_time),
        GST_TIME_ARGS (timestamp));
    /* don't need the old buffer anymore */
    gst_buffer_unref (pad->buffer);
    /* store new readahead buffer */
    pad->buffer = tmpbuf;

    /* let ogg write out the pages now. The packet we got could end
     * up in more than one page so we need to write them all */
    if (ogg_stream_pageout (&pad->map.stream, &page) > 0) {
      /* we have a new page, so we need to timestamp it correctly.
       * if this fresh packet ends on this page, then the page's granulepos
       * comes from that packet, and we should set this buffer's timestamp */

      GST_LOG_OBJECT (pad->collect.pad,
          GST_GP_FORMAT " packet %" G_GINT64_FORMAT ", time %"
          GST_TIME_FORMAT ") caused new page",
          granulepos, (gint64) packet.packetno, GST_TIME_ARGS (timestamp));
      GST_LOG_OBJECT (pad->collect.pad,
          GST_GP_FORMAT " new page %ld",
          GST_GP_CAST (ogg_page_granulepos (&page)), pad->map.stream.pageno);

      if (ogg_page_granulepos (&page) == granulepos) {
        /* the packet we streamed in finishes on the current page,
         * because the page's granulepos is the granulepos of the last
         * packet completed on that page,
         * so update the timestamp that we will give to the page */
        GST_LOG_OBJECT (pad->collect.pad,
            GST_GP_FORMAT
            " packet finishes on current page, updating gp time to %"
            GST_TIME_FORMAT, granulepos, GST_TIME_ARGS (gp_time));
        pad->gp_time = gp_time;
      } else {
        GST_LOG_OBJECT (pad->collect.pad,
            GST_GP_FORMAT
            " packet spans beyond current page, keeping old gp time %"
            GST_TIME_FORMAT, granulepos, GST_TIME_ARGS (pad->gp_time));
      }

      /* push the page */
      /* end time of this page is the timestamp of the next buffer */
      pad->timestamp_end = timestamp;
      ret = gst_ogg_mux_pad_queue_page (ogg_mux, pad, &page, pad->first_delta);
      pad->pageno++;
      /* mark next pages as delta */
      pad->first_delta = TRUE;

      /* use an inner loop here to flush the remaining pages and
       * mark them as delta frames as well */
      while (ogg_stream_pageout (&pad->map.stream, &page) > 0) {
        if (ogg_page_granulepos (&page) == granulepos) {
          /* the page has taken up the new packet completely, which means
           * the packet ends the page and we can update the gp time
           * before pushing out */
          pad->gp_time = gp_time;
        }

        /* we have a complete page now, we can push the page
         * and make sure to pull on a new pad the next time around */
        ret = gst_ogg_mux_pad_queue_page (ogg_mux, pad, &page,
            pad->first_delta);
        /* increment the page number counter */
        pad->pageno++;
      }
      /* need a new page as well */
      pad->new_page = TRUE;
      pad->duration = 0;
      /* we're done pulling on this pad, make sure to choose a new
       * pad for pulling in the next iteration */
      ogg_mux->pulling = NULL;
    }

    /* Update the gp time, if necessary, since any future page will have at
     * least this gp time.
     */
    if (pad->gp_time < gp_time) {
      pad->gp_time = gp_time;
      GST_LOG_OBJECT (pad->collect.pad,
          "Updated running gp time of pad %" GST_PTR_FORMAT
          " to %" GST_TIME_FORMAT, pad->collect.pad, GST_TIME_ARGS (gp_time));
    }
  }

  return ret;
}

/* all_pads_eos:
 *
 * Checks if all pads are EOS'd by peeking.
 *
 * Returns TRUE if all pads are EOS.
 */
static gboolean
all_pads_eos (GstCollectPads * pads)
{
  GSList *walk;

  walk = pads->data;
  while (walk) {
    GstOggPadData *oggpad = (GstOggPadData *) walk->data;

    GST_DEBUG_OBJECT (oggpad->collect.pad,
        "oggpad %p eos %d", oggpad, oggpad->eos);

    if (!oggpad->eos)
      return FALSE;

    walk = g_slist_next (walk);
  }

  return TRUE;
}

static void
gst_ogg_mux_send_start_events (GstOggMux * ogg_mux, GstCollectPads * pads)
{
  gchar s_id[32];

  /* stream-start (FIXME: create id based on input ids) and
   * also do something with the group id */
  g_snprintf (s_id, sizeof (s_id), "oggmux-%08x", g_random_int ());
  gst_pad_push_event (ogg_mux->srcpad, gst_event_new_stream_start (s_id));

  /* we'll send caps later, need to collect all headers first */
}

/* This function is called when there is data on all pads.
 * 
 * It finds a pad to pull on, this is done by looking at the buffers
 * to decide which one to use, and using the 'oldest' one first. It then calls
 * gst_ogg_mux_process_best_pad() to process as much data as possible.
 * 
 * If all the pads have received EOS, it flushes out all data by continually
 * getting the best pad and calling gst_ogg_mux_process_best_pad() until they
 * are all empty, and then sends EOS.
 */
static GstFlowReturn
gst_ogg_mux_collected (GstCollectPads * pads, GstOggMux * ogg_mux)
{
  GstOggPadData *best;
  GstFlowReturn ret;
  gboolean popped;

  GST_LOG_OBJECT (ogg_mux, "collected");

  if (ogg_mux->need_start_events) {
    gst_ogg_mux_send_start_events (ogg_mux, pads);
    ogg_mux->need_start_events = FALSE;
  }

  /* queue buffers on all pads; find a buffer with the lowest timestamp */
  best = gst_ogg_mux_queue_pads (ogg_mux, &popped);

  if (popped)
    return GST_FLOW_OK;

  if (best == NULL) {
    /* No data, assume EOS */
    goto eos;
  }

  /* This is not supposed to happen */
  g_return_val_if_fail (best->buffer != NULL, GST_FLOW_ERROR);

  ret = gst_ogg_mux_process_best_pad (ogg_mux, best);

  if (best->eos && all_pads_eos (pads))
    goto eos;

  /* We might have used up a cached pad->buffer. If all streams
   * have a buffer ready in collectpads, collectpads will block at
   * next chain, and will never call collected again. So we make a
   * last call to _queue_pads now, to ensure that collectpads can
   * push to at least one pad (mostly for streams with a single
   * logical stream). */
  gst_ogg_mux_queue_pads (ogg_mux, &popped);

  return ret;

eos:
  {
    GST_DEBUG_OBJECT (ogg_mux, "no data available, must be EOS");
    gst_pad_push_event (ogg_mux->srcpad, gst_event_new_eos ());
    return GST_FLOW_EOS;
  }
}

static void
gst_ogg_mux_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstOggMux *ogg_mux;

  ogg_mux = GST_OGG_MUX (object);

  switch (prop_id) {
    case ARG_MAX_DELAY:
      g_value_set_uint64 (value, ogg_mux->max_delay);
      break;
    case ARG_MAX_PAGE_DELAY:
      g_value_set_uint64 (value, ogg_mux->max_page_delay);
      break;
    case ARG_MAX_TOLERANCE:
      g_value_set_uint64 (value, ogg_mux->max_tolerance);
      break;
    case ARG_SKELETON:
      g_value_set_boolean (value, ogg_mux->use_skeleton);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_ogg_mux_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstOggMux *ogg_mux;

  ogg_mux = GST_OGG_MUX (object);

  switch (prop_id) {
    case ARG_MAX_DELAY:
      ogg_mux->max_delay = g_value_get_uint64 (value);
      break;
    case ARG_MAX_PAGE_DELAY:
      ogg_mux->max_page_delay = g_value_get_uint64 (value);
      break;
    case ARG_MAX_TOLERANCE:
      ogg_mux->max_tolerance = g_value_get_uint64 (value);
      break;
    case ARG_SKELETON:
      ogg_mux->use_skeleton = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* reset all variables in the ogg pads. */
static void
gst_ogg_mux_init_collectpads (GstCollectPads * collect)
{
  GSList *walk;

  walk = collect->data;
  while (walk) {
    GstOggPadData *oggpad = (GstOggPadData *) walk->data;

    ogg_stream_clear (&oggpad->map.stream);
    ogg_stream_init (&oggpad->map.stream, oggpad->map.serialno);
    oggpad->packetno = 0;
    oggpad->pageno = 0;
    oggpad->eos = FALSE;
    /* we assume there will be some control data first for this pad */
    oggpad->state = GST_OGG_PAD_STATE_CONTROL;
    oggpad->new_page = TRUE;
    oggpad->first_delta = FALSE;
    oggpad->prev_delta = FALSE;
    oggpad->data_pushed = FALSE;
    oggpad->pagebuffers = g_queue_new ();

    gst_segment_init (&oggpad->segment, GST_FORMAT_TIME);

    walk = g_slist_next (walk);
  }
}

/* Clear all buffers from the collectpads object */
static void
gst_ogg_mux_clear_collectpads (GstCollectPads * collect)
{
  GSList *walk;

  for (walk = collect->data; walk; walk = g_slist_next (walk)) {
    GstOggPadData *oggpad = (GstOggPadData *) walk->data;
    GstBuffer *buf;

    ogg_stream_clear (&oggpad->map.stream);

    while ((buf = g_queue_pop_head (oggpad->pagebuffers)) != NULL) {
      GST_LOG ("flushing buffer : %p", buf);
      gst_buffer_unref (buf);
    }
    g_queue_free (oggpad->pagebuffers);
    oggpad->pagebuffers = NULL;

    if (oggpad->buffer) {
      gst_buffer_unref (oggpad->buffer);
      oggpad->buffer = NULL;
    }

    if (oggpad->tags) {
      gst_tag_list_unref (oggpad->tags);
      oggpad->tags = NULL;
    }

    gst_segment_init (&oggpad->segment, GST_FORMAT_TIME);
  }
}

static GstStateChangeReturn
gst_ogg_mux_change_state (GstElement * element, GstStateChange transition)
{
  GstOggMux *ogg_mux;
  GstStateChangeReturn ret;

  ogg_mux = GST_OGG_MUX (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_ogg_mux_clear (ogg_mux);
      gst_ogg_mux_init_collectpads (ogg_mux->collect);
      gst_collect_pads_start (ogg_mux->collect);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_collect_pads_stop (ogg_mux->collect);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_ogg_mux_clear_collectpads (ogg_mux->collect);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

gboolean
gst_ogg_mux_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_ogg_mux_debug, "oggmux", 0, "ogg muxer");

  return gst_element_register (plugin, "oggmux", GST_RANK_PRIMARY,
      GST_TYPE_OGG_MUX);
}
