/* GStreamer Matroska muxer/demuxer
 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * (c) 2005 Michal Benes <michal.benes@xeris.cz>
 * (c) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * (c) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
 *
 * matroska-mux.c: matroska file/stream muxer
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/* TODO: - check everywhere that we don't write invalid values
 *       - make sure timestamps are correctly scaled everywhere
 */

/**
 * SECTION:element-matroskamux
 *
 * matroskamux muxes different input streams into a Matroska file.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v filesrc location=/path/to/mp3 ! mp3parse ! matroskamux name=mux ! filesink location=test.mkv  filesrc location=/path/to/theora.ogg ! oggdemux ! theoraparse ! mux.
 * ]| This pipeline muxes an MP3 file and a Ogg Theora video into a Matroska file.
 * |[
 * gst-launch-1.0 -v audiotestsrc num-buffers=100 ! audioconvert ! vorbisenc ! matroskamux ! filesink location=test.mka
 * ]| This pipeline muxes a 440Hz sine wave encoded with the Vorbis codec into a Matroska file.
 * </refsect2>
 */

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

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

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

#include "matroska-mux.h"
#include "matroska-ids.h"

#define GST_MATROSKA_MUX_CHAPLANG "und"

GST_DEBUG_CATEGORY_STATIC (matroskamux_debug);
#define GST_CAT_DEFAULT matroskamux_debug

enum
{
  ARG_0,
  ARG_WRITING_APP,
  ARG_DOCTYPE_VERSION,
  ARG_MIN_INDEX_INTERVAL,
  ARG_STREAMABLE
};

#define  DEFAULT_DOCTYPE_VERSION         2
#define  DEFAULT_WRITING_APP             "GStreamer Matroska muxer"
#define  DEFAULT_MIN_INDEX_INTERVAL      0
#define  DEFAULT_STREAMABLE              FALSE

/* WAVEFORMATEX is gst_riff_strf_auds + an extra guint16 extension size */
#define WAVEFORMATEX_SIZE  (2 + sizeof (gst_riff_strf_auds))

static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-matroska; video/x-matroska-3d; audio/x-matroska")
    );

#define COMMON_VIDEO_CAPS \
  "width = (int) [ 16, 4096 ], " \
  "height = (int) [ 16, 4096 ], " \
  "framerate = (fraction) [ 0, MAX ]"

#define COMMON_VIDEO_CAPS_NO_FRAMERATE \
  "width = (int) [ 16, 4096 ], " \
  "height = (int) [ 16, 4096 ] "

/* FIXME:
 * * require codec data, etc as needed
 */

static GstStaticPadTemplate videosink_templ =
    GST_STATIC_PAD_TEMPLATE ("video_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("video/mpeg, "
        "mpegversion = (int) { 1, 2, 4 }, "
        "systemstream = (boolean) false, "
        COMMON_VIDEO_CAPS "; "
        "video/x-h264, stream-format=avc, alignment=au, "
        COMMON_VIDEO_CAPS "; "
        "video/x-divx, "
        COMMON_VIDEO_CAPS "; "
        "video/x-huffyuv, "
        COMMON_VIDEO_CAPS "; "
        "video/x-dv, "
        COMMON_VIDEO_CAPS "; "
        "video/x-h263, "
        COMMON_VIDEO_CAPS "; "
        "video/x-msmpeg, "
        COMMON_VIDEO_CAPS "; "
        "image/jpeg, "
        COMMON_VIDEO_CAPS_NO_FRAMERATE "; "
        "video/x-theora; "
        "video/x-dirac, "
        COMMON_VIDEO_CAPS "; "
        "video/x-pn-realvideo, "
        "rmversion = (int) [1, 4], "
        COMMON_VIDEO_CAPS "; "
        "video/x-vp8, "
        COMMON_VIDEO_CAPS "; "
        "video/x-raw, "
        "format = (string) { YUY2, I420, YV12, UYVY, AYUV }, "
        COMMON_VIDEO_CAPS "; "
        "video/x-wmv, " "wmvversion = (int) [ 1, 3 ], " COMMON_VIDEO_CAPS)
    );

#define COMMON_AUDIO_CAPS \
  "channels = (int) [ 1, MAX ], " \
  "rate = (int) [ 1, MAX ]"

/* FIXME:
 * * require codec data, etc as needed
 */
static GstStaticPadTemplate audiosink_templ =
    GST_STATIC_PAD_TEMPLATE ("audio_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("audio/mpeg, "
        "mpegversion = (int) 1, "
        "layer = (int) [ 1, 3 ], "
        COMMON_AUDIO_CAPS "; "
        "audio/mpeg, "
        "mpegversion = (int) { 2, 4 }, "
        "stream-format = (string) raw, "
        COMMON_AUDIO_CAPS "; "
        "audio/x-ac3, "
        COMMON_AUDIO_CAPS "; "
        "audio/x-eac3, "
        COMMON_AUDIO_CAPS "; "
        "audio/x-dts, "
        COMMON_AUDIO_CAPS "; "
        "audio/x-vorbis, "
        COMMON_AUDIO_CAPS "; "
        "audio/x-flac, "
        COMMON_AUDIO_CAPS "; "
        "audio/x-speex, "
        COMMON_AUDIO_CAPS "; "
        "audio/x-raw, "
        "format = (string) { U8, S16BE, S16LE, S24BE, S24LE, S32BE, S32LE, F32LE, F64LE }, "
        "layout = (string) interleaved, "
        COMMON_AUDIO_CAPS ";"
        "audio/x-tta, "
        "width = (int) { 8, 16, 24 }, "
        "channels = (int) { 1, 2 }, " "rate = (int) [ 8000, 96000 ]; "
        "audio/x-pn-realaudio, "
        "raversion = (int) { 1, 2, 8 }, " COMMON_AUDIO_CAPS "; "
        "audio/x-wma, " "wmaversion = (int) [ 1, 3 ], "
        "block_align = (int) [ 0, 65535 ], bitrate = (int) [ 0, 524288 ], "
        COMMON_AUDIO_CAPS ";"
        "audio/x-alaw, "
        "channels = (int) {1, 2}, " "rate = (int) [ 8000, 192000 ]; "
        "audio/x-mulaw, "
        "channels = (int) {1, 2}, " "rate = (int) [ 8000, 192000 ]")
    );

static GstStaticPadTemplate subtitlesink_templ =
    GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("subtitle/x-kate; "
        "text/x-raw, format=utf8; application/x-ssa; application/x-ass; "
        "application/x-usf; subpicture/x-dvd; "
        "application/x-subtitle-unknown")
    );

static GArray *used_uids;
G_LOCK_DEFINE_STATIC (used_uids);

#define parent_class gst_matroska_mux_parent_class
G_DEFINE_TYPE_WITH_CODE (GstMatroskaMux, gst_matroska_mux, GST_TYPE_ELEMENT,
    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL)
    G_IMPLEMENT_INTERFACE (GST_TYPE_TOC_SETTER, NULL)
    );

/* Matroska muxer destructor */
static void gst_matroska_mux_finalize (GObject * object);

/* Pads collected callback */
static GstFlowReturn gst_matroska_mux_handle_buffer (GstCollectPads * pads,
    GstCollectData * data, GstBuffer * buf, gpointer user_data);
static gboolean gst_matroska_mux_handle_sink_event (GstCollectPads * pads,
    GstCollectData * data, GstEvent * event, gpointer user_data);

/* pad functions */
static gboolean gst_matroska_mux_handle_src_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static GstPad *gst_matroska_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gst_matroska_mux_release_pad (GstElement * element, GstPad * pad);

/* gst internal change state handler */
static GstStateChangeReturn
gst_matroska_mux_change_state (GstElement * element, GstStateChange transition);

/* gobject bla bla */
static void gst_matroska_mux_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_matroska_mux_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

/* reset muxer */
static void gst_matroska_mux_reset (GstElement * element);

/* uid generation */
static guint64 gst_matroska_mux_create_uid ();

static gboolean theora_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context);
static gboolean vorbis_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context);
static gboolean speex_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context);
static gboolean kate_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context);
static gboolean flac_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context);
static void
gst_matroska_mux_write_simple_tag (const GstTagList * list, const gchar * tag,
    gpointer data);

static void
gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&videosink_templ));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&audiosink_templ));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&subtitlesink_templ));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_templ));
  gst_element_class_set_static_metadata (gstelement_class, "Matroska muxer",
      "Codec/Muxer",
      "Muxes video/audio/subtitle streams into a matroska stream",
      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");

  GST_DEBUG_CATEGORY_INIT (matroskamux_debug, "matroskamux", 0,
      "Matroska muxer");

  gobject_class->finalize = gst_matroska_mux_finalize;

  gobject_class->get_property = gst_matroska_mux_get_property;
  gobject_class->set_property = gst_matroska_mux_set_property;

  g_object_class_install_property (gobject_class, ARG_WRITING_APP,
      g_param_spec_string ("writing-app", "Writing application.",
          "The name the application that creates the matroska file.",
          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_DOCTYPE_VERSION,
      g_param_spec_int ("version", "DocType version",
          "This parameter determines what Matroska features can be used.",
          1, 2, DEFAULT_DOCTYPE_VERSION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_MIN_INDEX_INTERVAL,
      g_param_spec_int64 ("min-index-interval", "Minimum time between index "
          "entries", "An index entry is created every so many nanoseconds.",
          0, G_MAXINT64, DEFAULT_MIN_INDEX_INTERVAL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, ARG_STREAMABLE,
      g_param_spec_boolean ("streamable", "Determines whether output should "
          "be streamable", "If set to true, the output should be as if it is "
          "to be streamed and hence no indexes written or duration written.",
          DEFAULT_STREAMABLE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_matroska_mux_change_state);
  gstelement_class->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_matroska_mux_request_new_pad);
  gstelement_class->release_pad =
      GST_DEBUG_FUNCPTR (gst_matroska_mux_release_pad);
}

/**
 * Start of pad option handler code
 */
#define DEFAULT_PAD_FRAME_DURATION TRUE
#define DEFAULT_PAD_FRAME_DURATION_VP8 FALSE

enum
{
  PROP_PAD_0,
  PROP_PAD_FRAME_DURATION
};

typedef struct
{
  GstPad parent;
  gboolean frame_duration;
  gboolean frame_duration_user;
} GstMatroskamuxPad;

static void gst_matroskamux_pad_class_init (GstPadClass * klass);

static GType
gst_matroskamux_pad_get_type (void)
{
  static GType type = 0;

  if (G_UNLIKELY (type == 0)) {
    type = g_type_register_static_simple (GST_TYPE_PAD,
        g_intern_static_string ("GstMatroskamuxPad"), sizeof (GstPadClass),
        (GClassInitFunc) gst_matroskamux_pad_class_init,
        sizeof (GstMatroskamuxPad), NULL, 0);
  }
  return type;
}

#define GST_TYPE_MATROSKAMUX_PAD (gst_matroskamux_pad_get_type())
#define GST_MATROSKAMUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_CAST((pad),GST_TYPE_MATROSKAMUX_PAD,GstMatroskamuxPad))
#define GST_MATROSKAMUX_PAD_CAST(pad) ((GstMatroskamuxPad *) pad)
#define GST_IS_MATROSKAMUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_TYPE((pad),GST_TYPE_MATROSKAMUX_PAD))

static void
gst_matroskamux_pad_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstMatroskamuxPad *pad = GST_MATROSKAMUX_PAD (object);

  switch (prop_id) {
    case PROP_PAD_FRAME_DURATION:
      g_value_set_boolean (value, pad->frame_duration);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_matroskamux_pad_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstMatroskamuxPad *pad = GST_MATROSKAMUX_PAD (object);

  switch (prop_id) {
    case PROP_PAD_FRAME_DURATION:
      pad->frame_duration = g_value_get_boolean (value);
      pad->frame_duration_user = TRUE;
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_matroskamux_pad_class_init (GstPadClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  gobject_class->set_property = gst_matroskamux_pad_set_property;
  gobject_class->get_property = gst_matroskamux_pad_get_property;

  g_object_class_install_property (gobject_class, PROP_PAD_FRAME_DURATION,
      g_param_spec_boolean ("frame-duration", "Frame duration",
          "Default frame duration", DEFAULT_PAD_FRAME_DURATION,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
}

static void
gst_matroskamux_pad_init (GstMatroskamuxPad * pad)
{
  pad->frame_duration = DEFAULT_PAD_FRAME_DURATION;
  pad->frame_duration_user = FALSE;
}

/*
 * End of pad option handler code
 **/

/**
 * gst_matroska_mux_init:
 * @mux: #GstMatroskaMux that should be initialized.
 * @g_class: Class of the muxer.
 *
 * Matroska muxer constructor.
 */
static void
gst_matroska_mux_init (GstMatroskaMux * mux)
{
  GstPadTemplate *templ;

  templ =
      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mux), "src");
  mux->srcpad = gst_pad_new_from_template (templ, "src");

  gst_pad_set_event_function (mux->srcpad, gst_matroska_mux_handle_src_event);
  gst_element_add_pad (GST_ELEMENT (mux), mux->srcpad);
  gst_pad_use_fixed_caps (mux->srcpad);

  mux->collect = gst_collect_pads_new ();
  gst_collect_pads_set_clip_function (mux->collect,
      GST_DEBUG_FUNCPTR (gst_collect_pads_clip_running_time), mux);
  gst_collect_pads_set_buffer_function (mux->collect,
      GST_DEBUG_FUNCPTR (gst_matroska_mux_handle_buffer), mux);
  gst_collect_pads_set_event_function (mux->collect,
      GST_DEBUG_FUNCPTR (gst_matroska_mux_handle_sink_event), mux);

  mux->ebml_write = gst_ebml_write_new (mux->srcpad);
  mux->doctype = GST_MATROSKA_DOCTYPE_MATROSKA;

  /* property defaults */
  mux->doctype_version = DEFAULT_DOCTYPE_VERSION;
  mux->writing_app = g_strdup (DEFAULT_WRITING_APP);
  mux->min_index_interval = DEFAULT_MIN_INDEX_INTERVAL;
  mux->streamable = DEFAULT_STREAMABLE;

  /* initialize internal variables */
  mux->index = NULL;
  mux->num_streams = 0;
  mux->num_a_streams = 0;
  mux->num_t_streams = 0;
  mux->num_v_streams = 0;

  /* initialize remaining variables */
  gst_matroska_mux_reset (GST_ELEMENT (mux));
}


/**
 * gst_matroska_mux_finalize:
 * @object: #GstMatroskaMux that should be finalized.
 *
 * Finalize matroska muxer.
 */
static void
gst_matroska_mux_finalize (GObject * object)
{
  GstMatroskaMux *mux = GST_MATROSKA_MUX (object);

  gst_event_replace (&mux->force_key_unit_event, NULL);

  gst_object_unref (mux->collect);
  gst_object_unref (mux->ebml_write);
  if (mux->writing_app)
    g_free (mux->writing_app);

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


/**
 * gst_matroska_mux_create_uid:
 *
 * Generate new unused track UID.
 *
 * Returns: New track UID.
 */
static guint64
gst_matroska_mux_create_uid (void)
{
  guint64 uid = 0;

  G_LOCK (used_uids);

  if (!used_uids)
    used_uids = g_array_sized_new (FALSE, FALSE, sizeof (guint64), 10);

  while (!uid) {
    guint i;

    uid = (((guint64) g_random_int ()) << 32) | g_random_int ();
    for (i = 0; i < used_uids->len; i++) {
      if (g_array_index (used_uids, guint64, i) == uid) {
        uid = 0;
        break;
      }
    }
    g_array_append_val (used_uids, uid);
  }

  G_UNLOCK (used_uids);
  return uid;
}


/**
 * gst_matroska_pad_reset:
 * @collect_pad: the #GstMatroskaPad
 *
 * Reset and/or release resources of a matroska collect pad.
 */
static void
gst_matroska_pad_reset (GstMatroskaPad * collect_pad, gboolean full)
{
  gchar *name = NULL;
  GstMatroskaTrackType type = 0;

  /* free track information */
  if (collect_pad->track != NULL) {
    /* retrieve for optional later use */
    name = collect_pad->track->name;
    type = collect_pad->track->type;
    /* extra for video */
    if (type == GST_MATROSKA_TRACK_TYPE_VIDEO) {
      GstMatroskaTrackVideoContext *ctx =
          (GstMatroskaTrackVideoContext *) collect_pad->track;

      if (ctx->dirac_unit) {
        gst_buffer_unref (ctx->dirac_unit);
        ctx->dirac_unit = NULL;
      }
    }
    g_free (collect_pad->track->codec_id);
    g_free (collect_pad->track->codec_name);
    if (full)
      g_free (collect_pad->track->name);
    g_free (collect_pad->track->language);
    g_free (collect_pad->track->codec_priv);
    g_free (collect_pad->track);
    collect_pad->track = NULL;
  }

  if (!full && type != 0) {
    GstMatroskaTrackContext *context;

    /* create a fresh context */
    switch (type) {
      case GST_MATROSKA_TRACK_TYPE_VIDEO:
        context = (GstMatroskaTrackContext *)
            g_new0 (GstMatroskaTrackVideoContext, 1);
        break;
      case GST_MATROSKA_TRACK_TYPE_AUDIO:
        context = (GstMatroskaTrackContext *)
            g_new0 (GstMatroskaTrackAudioContext, 1);
        break;
      case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
        context = (GstMatroskaTrackContext *)
            g_new0 (GstMatroskaTrackSubtitleContext, 1);
        break;
      default:
        g_assert_not_reached ();
        return;
    }

    context->type = type;
    context->name = name;
    /* TODO: check default values for the context */
    context->flags = GST_MATROSKA_TRACK_ENABLED | GST_MATROSKA_TRACK_DEFAULT;
    collect_pad->track = context;
    collect_pad->duration = 0;
    collect_pad->start_ts = GST_CLOCK_TIME_NONE;
    collect_pad->end_ts = GST_CLOCK_TIME_NONE;
  }
}

/**
 * gst_matroska_pad_free:
 * @collect_pad: the #GstMatroskaPad
 *
 * Release resources of a matroska collect pad.
 */
static void
gst_matroska_pad_free (GstPad * collect_pad)
{
  gst_matroska_pad_reset ((GstMatroskaPad *) collect_pad, TRUE);
}


/**
 * gst_matroska_mux_reset:
 * @element: #GstMatroskaMux that should be reseted.
 *
 * Reset matroska muxer back to initial state.
 */
static void
gst_matroska_mux_reset (GstElement * element)
{
  GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
  GSList *walk;

  /* reset EBML write */
  gst_ebml_write_reset (mux->ebml_write);

  /* reset input */
  mux->state = GST_MATROSKA_MUX_STATE_START;

  /* clean up existing streams */

  for (walk = mux->collect->data; walk; walk = g_slist_next (walk)) {
    GstMatroskaPad *collect_pad;

    collect_pad = (GstMatroskaPad *) walk->data;

    /* reset collect pad to pristine state */
    gst_matroska_pad_reset (collect_pad, FALSE);
  }

  /* reset indexes */
  mux->num_indexes = 0;
  g_free (mux->index);
  mux->index = NULL;

  /* reset timers */
  mux->time_scale = GST_MSECOND;
  mux->max_cluster_duration = G_MAXINT16 * mux->time_scale;
  mux->duration = 0;

  /* reset cluster */
  mux->cluster = 0;
  mux->cluster_time = 0;
  mux->cluster_pos = 0;
  mux->prev_cluster_size = 0;

  /* reset tags */
  gst_tag_setter_reset_tags (GST_TAG_SETTER (mux));

  mux->tags_pos = 0;

  /* reset chapters */
  gst_toc_setter_reset (GST_TOC_SETTER (mux));

  mux->chapters_pos = 0;
}

/**
 * gst_matroska_mux_handle_src_event:
 * @pad: Pad which received the event.
 * @event: Received event.
 *
 * handle events - copied from oggmux without understanding
 *
 * Returns: #TRUE on success.
 */
static gboolean
gst_matroska_mux_handle_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstEventType type;

  type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;

  switch (type) {
    case GST_EVENT_SEEK:
      /* disable seeking for now */
      return FALSE;
    default:
      break;
  }

  return gst_pad_event_default (pad, parent, event);
}


static void
gst_matroska_mux_free_codec_priv (GstMatroskaTrackContext * context)
{
  if (context->codec_priv != NULL) {
    g_free (context->codec_priv);
    context->codec_priv = NULL;
    context->codec_priv_size = 0;
  }
}

static void
gst_matroska_mux_build_vobsub_private (GstMatroskaTrackContext * context,
    const guint * clut)
{
  gchar *clutv[17];
  gchar *sclut;
  gint i;
  guint32 col;
  gdouble y, u, v;
  guint8 r, g, b;

  /* produce comma-separated list in hex format */
  for (i = 0; i < 16; ++i) {
    col = clut[i];
    /* replicate vobsub's slightly off RGB conversion calculation */
    y = (((col >> 16) & 0xff) - 16) * 255 / 219;
    u = ((col >> 8) & 0xff) - 128;
    v = (col & 0xff) - 128;
    r = CLAMP (1.0 * y + 1.4022 * u, 0, 255);
    g = CLAMP (1.0 * y - 0.3456 * u - 0.7145 * v, 0, 255);
    b = CLAMP (1.0 * y + 1.7710 * v, 0, 255);
    clutv[i] = g_strdup_printf ("%02x%02x%02x", r, g, b);
  }
  clutv[i] = NULL;
  sclut = g_strjoinv (",", clutv);

  /* build codec private; only palette for now */
  gst_matroska_mux_free_codec_priv (context);
  context->codec_priv = (guint8 *) g_strdup_printf ("palette: %s", sclut);
  /* include terminating 0 */
  context->codec_priv_size = strlen ((gchar *) context->codec_priv) + 1;
  g_free (sclut);
  for (i = 0; i < 16; ++i) {
    g_free (clutv[i]);
  }
}


/**
 * gst_matroska_mux_handle_sink_event:
 * @pad: Pad which received the event.
 * @event: Received event.
 *
 * handle events - informational ones like tags
 *
 * Returns: #TRUE on success.
 */
static gboolean
gst_matroska_mux_handle_sink_event (GstCollectPads * pads,
    GstCollectData * data, GstEvent * event, gpointer user_data)
{
  GstMatroskaPad *collect_pad;
  GstMatroskaTrackContext *context;
  GstMatroskaMux *mux;
  GstPad *pad;
  GstTagList *list;
  gboolean ret = TRUE;

  mux = GST_MATROSKA_MUX (user_data);
  collect_pad = (GstMatroskaPad *) data;
  pad = data->pad;
  context = collect_pad->track;
  g_assert (context);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:{
      GstCaps *caps;

      collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
      gst_event_parse_caps (event, &caps);

      ret = collect_pad->capsfunc (pad, caps);
      gst_event_unref (event);
      event = NULL;
      break;
    }
    case GST_EVENT_TAG:{
      gchar *lang = NULL;

      GST_DEBUG_OBJECT (mux, "received tag event");
      gst_event_parse_tag (event, &list);

      /* Matroska wants ISO 639-2B code, taglist most likely contains 639-1 */
      if (gst_tag_list_get_string (list, GST_TAG_LANGUAGE_CODE, &lang)) {
        const gchar *lang_code;

        lang_code = gst_tag_get_language_code_iso_639_2B (lang);
        if (lang_code) {
          GST_INFO_OBJECT (pad, "Setting language to '%s'", lang_code);
          context->language = g_strdup (lang_code);
        } else {
          GST_WARNING_OBJECT (pad, "Did not get language code for '%s'", lang);
        }
        g_free (lang);
      }

      /* FIXME: what about stream-specific tags? */
      gst_tag_setter_merge_tags (GST_TAG_SETTER (mux), list,
          gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (mux)));

      gst_event_unref (event);
      /* handled this, don't want collectpads to forward it downstream */
      event = NULL;
      ret = TRUE;
      break;
    }
    case GST_EVENT_TOC:{
      GstToc *toc, *old_toc;

      if (mux->chapters_pos > 0)
        break;

      GST_DEBUG_OBJECT (mux, "received toc event");
      gst_event_parse_toc (event, &toc, NULL);

      if (toc != NULL) {
        old_toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux));
        if (old_toc != NULL) {
          if (old_toc != toc)
            GST_INFO_OBJECT (pad, "Replacing TOC with a new one");
          gst_toc_unref (old_toc);
        }

        gst_toc_setter_set_toc (GST_TOC_SETTER (mux), toc);
        gst_toc_unref (toc);
      }

      gst_event_unref (event);
      /* handled this, don't want collectpads to forward it downstream */
      event = NULL;
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:{
      const GstStructure *structure;

      structure = gst_event_get_structure (event);
      if (gst_structure_has_name (structure, "GstForceKeyUnit")) {
        gst_event_replace (&mux->force_key_unit_event, NULL);
        mux->force_key_unit_event = event;
        event = NULL;
      } else if (gst_structure_has_name (structure, "application/x-gst-dvd") &&
          !strcmp ("dvd-spu-clut-change",
              gst_structure_get_string (structure, "event"))) {
        gchar name[16];
        gint i, value;
        guint clut[16];

        GST_DEBUG_OBJECT (pad, "New DVD colour table received");
        if (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE) {
          GST_DEBUG_OBJECT (pad, "... discarding");
          break;
        }
        /* first transform event data into table form */
        for (i = 0; i < 16; i++) {
          g_snprintf (name, sizeof (name), "clut%02d", i);
          if (!gst_structure_get_int (structure, name, &value)) {
            GST_ERROR_OBJECT (mux, "dvd-spu-clut-change event did not "
                "contain %s field", name);
            break;
          }
          clut[i] = value;
        }

        /* transform into private data for stream; text form */
        gst_matroska_mux_build_vobsub_private (context, clut);
      }
    }
      /* fall through */
    default:
      break;
  }

  if (event != NULL)
    return gst_collect_pads_event_default (pads, data, event, FALSE);

  return ret;
}

static void
gst_matroska_mux_set_codec_id (GstMatroskaTrackContext * context,
    const char *id)
{
  g_assert (context && id);
  if (context->codec_id)
    g_free (context->codec_id);
  context->codec_id = g_strdup (id);
}

/**
 * gst_matroska_mux_video_pad_setcaps:
 * @pad: Pad which got the caps.
 * @caps: New caps.
 *
 * Setcaps function for video sink pad.
 *
 * Returns: #TRUE on success.
 */
static gboolean
gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
{
  GstMatroskaTrackContext *context = NULL;
  GstMatroskaTrackVideoContext *videocontext;
  GstMatroskaMux *mux;
  GstMatroskaPad *collect_pad;
  GstStructure *structure;
  const gchar *mimetype;
  const gchar *interlace_mode;
  const GValue *value = NULL;
  GstBuffer *codec_buf = NULL;
  gint width, height, pixel_width, pixel_height;
  gint fps_d, fps_n;

  mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));

  /* find context */
  collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
  g_assert (collect_pad);
  context = collect_pad->track;
  g_assert (context);
  g_assert (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO);
  videocontext = (GstMatroskaTrackVideoContext *) context;

  /* gst -> matroska ID'ing */
  structure = gst_caps_get_structure (caps, 0);

  mimetype = gst_structure_get_name (structure);

  interlace_mode = gst_structure_get_string (structure, "interlace-mode");
  if (interlace_mode != NULL && strcmp (interlace_mode, "progressive") != 0)
    context->flags |= GST_MATROSKA_VIDEOTRACK_INTERLACED;

  if (!strcmp (mimetype, "video/x-theora")) {
    /* we'll extract the details later from the theora identification header */
    goto skip_details;
  }

  /* get general properties */
  /* spec says it is mandatory */
  if (!gst_structure_get_int (structure, "width", &width) ||
      !gst_structure_get_int (structure, "height", &height))
    goto refuse_caps;

  videocontext->pixel_width = width;
  videocontext->pixel_height = height;

  /* set vp8 defaults or let user override it */
  if (GST_MATROSKAMUX_PAD_CAST (pad)->frame_duration_user == FALSE
      && (!strcmp (mimetype, "video/x-vp8")))
    GST_MATROSKAMUX_PAD_CAST (pad)->frame_duration =
        DEFAULT_PAD_FRAME_DURATION_VP8;

  if (GST_MATROSKAMUX_PAD_CAST (pad)->frame_duration
      && gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)
      && fps_n > 0) {
    context->default_duration =
        gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
    GST_LOG_OBJECT (pad, "default duration = %" GST_TIME_FORMAT,
        GST_TIME_ARGS (context->default_duration));
  } else {
    context->default_duration = 0;
  }
  if (gst_structure_get_fraction (structure, "pixel-aspect-ratio",
          &pixel_width, &pixel_height)) {
    if (pixel_width > pixel_height) {
      videocontext->display_width = width * pixel_width / pixel_height;
      videocontext->display_height = height;
    } else if (pixel_width < pixel_height) {
      videocontext->display_width = width;
      videocontext->display_height = height * pixel_height / pixel_width;
    } else {
      videocontext->display_width = 0;
      videocontext->display_height = 0;
    }
  } else {
    videocontext->display_width = 0;
    videocontext->display_height = 0;
  }

skip_details:

  videocontext->asr_mode = GST_MATROSKA_ASPECT_RATIO_MODE_FREE;
  videocontext->fourcc = 0;

  /* TODO: - check if we handle all codecs by the spec, i.e. codec private
   *         data and other settings
   *       - add new formats
   */

  /* extract codec_data, may turn out needed */
  value = gst_structure_get_value (structure, "codec_data");
  if (value)
    codec_buf = (GstBuffer *) gst_value_get_buffer (value);

  /* find type */
  if (!strcmp (mimetype, "video/x-raw")) {
    const gchar *fstr;
    gst_matroska_mux_set_codec_id (context,
        GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED);
    fstr = gst_structure_get_string (structure, "format");
    if (fstr && strlen (fstr) == 4)
      videocontext->fourcc = GST_STR_FOURCC (fstr);
  } else if (!strcmp (mimetype, "video/x-huffyuv")      /* MS/VfW compatibility cases */
      ||!strcmp (mimetype, "video/x-divx")
      || !strcmp (mimetype, "video/x-dv")
      || !strcmp (mimetype, "video/x-h263")
      || !strcmp (mimetype, "video/x-msmpeg")
      || !strcmp (mimetype, "video/x-wmv")
      || !strcmp (mimetype, "image/jpeg")) {
    gst_riff_strf_vids *bih;
    gint size = sizeof (gst_riff_strf_vids);
    guint32 fourcc = 0;

    if (!strcmp (mimetype, "video/x-huffyuv"))
      fourcc = GST_MAKE_FOURCC ('H', 'F', 'Y', 'U');
    else if (!strcmp (mimetype, "video/x-dv"))
      fourcc = GST_MAKE_FOURCC ('D', 'V', 'S', 'D');
    else if (!strcmp (mimetype, "video/x-h263"))
      fourcc = GST_MAKE_FOURCC ('H', '2', '6', '3');
    else if (!strcmp (mimetype, "video/x-divx")) {
      gint divxversion;

      gst_structure_get_int (structure, "divxversion", &divxversion);
      switch (divxversion) {
        case 3:
          fourcc = GST_MAKE_FOURCC ('D', 'I', 'V', '3');
          break;
        case 4:
          fourcc = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
          break;
        case 5:
          fourcc = GST_MAKE_FOURCC ('D', 'X', '5', '0');
          break;
      }
    } else if (!strcmp (mimetype, "video/x-msmpeg")) {
      gint msmpegversion;

      gst_structure_get_int (structure, "msmpegversion", &msmpegversion);
      switch (msmpegversion) {
        case 41:
          fourcc = GST_MAKE_FOURCC ('M', 'P', 'G', '4');
          break;
        case 42:
          fourcc = GST_MAKE_FOURCC ('M', 'P', '4', '2');
          break;
        case 43:
          goto msmpeg43;
          break;
      }
    } else if (!strcmp (mimetype, "video/x-wmv")) {
      gint wmvversion;
      const gchar *fstr;

      fstr = gst_structure_get_string (structure, "format");
      if (fstr && strlen (fstr) == 4) {
        fourcc = GST_STR_FOURCC (fstr);
      } else if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
        if (wmvversion == 2) {
          fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '2');
        } else if (wmvversion == 1) {
          fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '1');
        } else if (wmvversion == 3) {
          fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '3');
        }
      }
    } else if (!strcmp (mimetype, "image/jpeg")) {
      fourcc = GST_MAKE_FOURCC ('M', 'J', 'P', 'G');
    }

    if (!fourcc)
      goto refuse_caps;

    bih = g_new0 (gst_riff_strf_vids, 1);
    GST_WRITE_UINT32_LE (&bih->size, size);
    GST_WRITE_UINT32_LE (&bih->width, videocontext->pixel_width);
    GST_WRITE_UINT32_LE (&bih->height, videocontext->pixel_height);
    GST_WRITE_UINT32_LE (&bih->compression, fourcc);
    GST_WRITE_UINT16_LE (&bih->planes, (guint16) 1);
    GST_WRITE_UINT16_LE (&bih->bit_cnt, (guint16) 24);
    GST_WRITE_UINT32_LE (&bih->image_size, videocontext->pixel_width *
        videocontext->pixel_height * 3);

    /* process codec private/initialization data, if any */
    if (codec_buf) {
      size += gst_buffer_get_size (codec_buf);
      bih = g_realloc (bih, size);
      GST_WRITE_UINT32_LE (&bih->size, size);
      gst_buffer_extract (codec_buf, 0,
          (guint8 *) bih + sizeof (gst_riff_strf_vids), -1);
    }

    gst_matroska_mux_set_codec_id (context,
        GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC);
    gst_matroska_mux_free_codec_priv (context);
    context->codec_priv = (gpointer) bih;
    context->codec_priv_size = size;
  } else if (!strcmp (mimetype, "video/x-h264")) {
    gst_matroska_mux_set_codec_id (context,
        GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC);
    gst_matroska_mux_free_codec_priv (context);
    /* Create avcC header */
    if (codec_buf != NULL) {
      context->codec_priv_size = gst_buffer_get_size (codec_buf);
      context->codec_priv = g_malloc0 (context->codec_priv_size);
      gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
    }
  } else if (!strcmp (mimetype, "video/x-theora")) {
    const GValue *streamheader;

    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_THEORA);

    gst_matroska_mux_free_codec_priv (context);

    streamheader = gst_structure_get_value (structure, "streamheader");
    if (!theora_streamheader_to_codecdata (streamheader, context)) {
      GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
          ("theora stream headers missing or malformed"));
      goto refuse_caps;
    }
  } else if (!strcmp (mimetype, "video/x-dirac")) {
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC);
  } else if (!strcmp (mimetype, "video/x-vp8")) {
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_VP8);
  } else if (!strcmp (mimetype, "video/mpeg")) {
    gint mpegversion;

    gst_structure_get_int (structure, "mpegversion", &mpegversion);
    switch (mpegversion) {
      case 1:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_VIDEO_MPEG1);
        break;
      case 2:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_VIDEO_MPEG2);
        break;
      case 4:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_ASP);
        break;
      default:
        goto refuse_caps;
    }

    /* global headers may be in codec data */
    if (codec_buf != NULL) {
      gst_matroska_mux_free_codec_priv (context);
      context->codec_priv_size = gst_buffer_get_size (codec_buf);
      context->codec_priv = g_malloc0 (context->codec_priv_size);
      gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
    }
  } else if (!strcmp (mimetype, "video/x-msmpeg")) {
  msmpeg43:
    /* can only make it here if preceding case verified it was version 3 */
    context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MSMPEG4V3);
  } else if (!strcmp (mimetype, "video/x-pn-realvideo")) {
    gint rmversion;
    const GValue *mdpr_data;

    gst_structure_get_int (structure, "rmversion", &rmversion);
    switch (rmversion) {
      case 1:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO1);
        break;
      case 2:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO2);
        break;
      case 3:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO3);
        break;
      case 4:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_VIDEO_REALVIDEO4);
        break;
      default:
        goto refuse_caps;
    }

    mdpr_data = gst_structure_get_value (structure, "mdpr_data");
    if (mdpr_data != NULL) {
      guint8 *priv_data = NULL;
      guint priv_data_size = 0;

      GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);

      priv_data_size = gst_buffer_get_size (codec_data_buf);
      priv_data = g_malloc0 (priv_data_size);

      gst_buffer_extract (codec_data_buf, 0, priv_data, -1);

      gst_matroska_mux_free_codec_priv (context);
      context->codec_priv = priv_data;
      context->codec_priv_size = priv_data_size;
    }
  }

  return TRUE;

  /* ERRORS */
refuse_caps:
  {
    GST_WARNING_OBJECT (mux, "pad %s refused caps %" GST_PTR_FORMAT,
        GST_PAD_NAME (pad), caps);
    return FALSE;
  }
}

/* N > 0 to expect a particular number of headers, negative if the
   number of headers is variable */
static gboolean
xiphN_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context, GstBuffer ** p_buf0, int N)
{
  GstBuffer **buf = NULL;
  GArray *bufarr;
  guint8 *priv_data;
  guint bufi, i, offset, priv_data_size;

  if (streamheader == NULL)
    goto no_stream_headers;

  if (G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY)
    goto wrong_type;

  bufarr = g_value_peek_pointer (streamheader);
  if (bufarr->len <= 0 || bufarr->len > 255)    /* at least one header, and count stored in a byte */
    goto wrong_count;
  if (N > 0 && bufarr->len != N)
    goto wrong_count;

  context->xiph_headers_to_skip = bufarr->len;

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

    if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
      g_free (buf);
      goto wrong_content_type;
    }

    buf[i] = g_value_peek_pointer (bufval);
  }

  priv_data_size = 1;
  if (bufarr->len > 0) {
    for (i = 0; i < bufarr->len - 1; i++) {
      priv_data_size += gst_buffer_get_size (buf[i]) / 0xff + 1;
    }
  }

  for (i = 0; i < bufarr->len; ++i) {
    priv_data_size += gst_buffer_get_size (buf[i]);
  }

  priv_data = g_malloc0 (priv_data_size);

  priv_data[0] = bufarr->len - 1;
  offset = 1;

  if (bufarr->len > 0) {
    for (bufi = 0; bufi < bufarr->len - 1; bufi++) {
      for (i = 0; i < gst_buffer_get_size (buf[bufi]) / 0xff; ++i) {
        priv_data[offset++] = 0xff;
      }
      priv_data[offset++] = gst_buffer_get_size (buf[bufi]) % 0xff;
    }
  }

  for (i = 0; i < bufarr->len; ++i) {
    gst_buffer_extract (buf[i], 0, priv_data + offset, -1);
    offset += gst_buffer_get_size (buf[i]);
  }

  gst_matroska_mux_free_codec_priv (context);
  context->codec_priv = priv_data;
  context->codec_priv_size = priv_data_size;

  if (p_buf0)
    *p_buf0 = gst_buffer_ref (buf[0]);

  g_free (buf);

  return TRUE;

/* ERRORS */
no_stream_headers:
  {
    GST_WARNING ("required streamheaders missing in sink caps!");
    return FALSE;
  }
wrong_type:
  {
    GST_WARNING ("streamheaders are not a GST_TYPE_ARRAY, but a %s",
        G_VALUE_TYPE_NAME (streamheader));
    return FALSE;
  }
wrong_count:
  {
    GST_WARNING ("got %u streamheaders, not %d as expected", bufarr->len, N);
    return FALSE;
  }
wrong_content_type:
  {
    GST_WARNING ("streamheaders array does not contain GstBuffers");
    return FALSE;
  }
}

static gboolean
vorbis_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context)
{
  GstBuffer *buf0 = NULL;

  if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, 3))
    return FALSE;

  if (buf0 == NULL || gst_buffer_get_size (buf0) < 1 + 6 + 4) {
    GST_WARNING ("First vorbis header too small, ignoring");
  } else {
    if (gst_buffer_memcmp (buf0, 1, "vorbis", 6) == 0) {
      GstMatroskaTrackAudioContext *audiocontext;
      GstMapInfo map;
      guint8 *hdr;

      gst_buffer_map (buf0, &map, GST_MAP_READ);
      hdr = map.data + 1 + 6 + 4;
      audiocontext = (GstMatroskaTrackAudioContext *) context;
      audiocontext->channels = GST_READ_UINT8 (hdr);
      audiocontext->samplerate = GST_READ_UINT32_LE (hdr + 1);
      gst_buffer_unmap (buf0, &map);
    }
  }

  if (buf0)
    gst_buffer_unref (buf0);

  return TRUE;
}

static gboolean
theora_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context)
{
  GstBuffer *buf0 = NULL;

  if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, 3))
    return FALSE;

  if (buf0 == NULL || gst_buffer_get_size (buf0) < 1 + 6 + 26) {
    GST_WARNING ("First theora header too small, ignoring");
  } else if (gst_buffer_memcmp (buf0, 0, "\200theora\003\002", 9) != 0) {
    GST_WARNING ("First header not a theora identification header, ignoring");
  } else {
    GstMatroskaTrackVideoContext *videocontext;
    guint fps_num, fps_denom, par_num, par_denom;
    GstMapInfo map;
    guint8 *hdr;

    gst_buffer_map (buf0, &map, GST_MAP_READ);
    hdr = map.data + 1 + 6 + 3 + 2 + 2;

    videocontext = (GstMatroskaTrackVideoContext *) context;
    videocontext->pixel_width = GST_READ_UINT32_BE (hdr) >> 8;
    videocontext->pixel_height = GST_READ_UINT32_BE (hdr + 3) >> 8;
    hdr += 3 + 3 + 1 + 1;
    fps_num = GST_READ_UINT32_BE (hdr);
    fps_denom = GST_READ_UINT32_BE (hdr + 4);
    context->default_duration = gst_util_uint64_scale_int (GST_SECOND,
        fps_denom, fps_num);
    hdr += 4 + 4;
    par_num = GST_READ_UINT32_BE (hdr) >> 8;
    par_denom = GST_READ_UINT32_BE (hdr + 3) >> 8;
    if (par_num > 0 && par_num > 0) {
      if (par_num > par_denom) {
        videocontext->display_width =
            videocontext->pixel_width * par_num / par_denom;
        videocontext->display_height = videocontext->pixel_height;
      } else if (par_num < par_denom) {
        videocontext->display_width = videocontext->pixel_width;
        videocontext->display_height =
            videocontext->pixel_height * par_denom / par_num;
      } else {
        videocontext->display_width = 0;
        videocontext->display_height = 0;
      }
    } else {
      videocontext->display_width = 0;
      videocontext->display_height = 0;
    }
    hdr += 3 + 3;

    gst_buffer_unmap (buf0, &map);
  }

  if (buf0)
    gst_buffer_unref (buf0);

  return TRUE;
}

static gboolean
kate_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context)
{
  GstBuffer *buf0 = NULL;

  if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, -1))
    return FALSE;

  if (buf0 == NULL || gst_buffer_get_size (buf0) < 64) {        /* Kate ID header is 64 bytes */
    GST_WARNING ("First kate header too small, ignoring");
  } else if (gst_buffer_memcmp (buf0, 0, "\200kate\0\0\0", 8) != 0) {
    GST_WARNING ("First header not a kate identification header, ignoring");
  }

  if (buf0)
    gst_buffer_unref (buf0);

  return TRUE;
}

static gboolean
flac_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context)
{
  GArray *bufarr;
  gint i;
  GValue *bufval;
  GstBuffer *buffer;

  if (streamheader == NULL || G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY) {
    GST_WARNING ("No or invalid streamheader field in the caps");
    return FALSE;
  }

  bufarr = g_value_peek_pointer (streamheader);
  if (bufarr->len < 2) {
    GST_WARNING ("Too few headers in streamheader field");
    return FALSE;
  }

  context->xiph_headers_to_skip = bufarr->len + 1;

  bufval = &g_array_index (bufarr, GValue, 0);
  if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
    GST_WARNING ("streamheaders array does not contain GstBuffers");
    return FALSE;
  }

  buffer = g_value_peek_pointer (bufval);

  /* Need at least OggFLAC mapping header, fLaC marker and STREAMINFO block */
  if (gst_buffer_get_size (buffer) < 9 + 4 + 4 + 34
      || gst_buffer_memcmp (buffer, 1, "FLAC", 4) != 0
      || gst_buffer_memcmp (buffer, 9, "fLaC", 4) != 0) {
    GST_WARNING ("Invalid streamheader for FLAC");
    return FALSE;
  }

  gst_matroska_mux_free_codec_priv (context);
  context->codec_priv_size = gst_buffer_get_size (buffer) - 9;
  context->codec_priv = g_malloc (context->codec_priv_size);
  gst_buffer_extract (buffer, 9, context->codec_priv, -1);

  for (i = 1; i < bufarr->len; i++) {
    guint old_size;
    bufval = &g_array_index (bufarr, GValue, i);

    if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
      gst_matroska_mux_free_codec_priv (context);
      GST_WARNING ("streamheaders array does not contain GstBuffers");
      return FALSE;
    }

    buffer = g_value_peek_pointer (bufval);

    old_size = context->codec_priv_size;
    context->codec_priv_size += gst_buffer_get_size (buffer);

    context->codec_priv = g_realloc (context->codec_priv,
        context->codec_priv_size);
    gst_buffer_extract (buffer, 0,
        (guint8 *) context->codec_priv + old_size, -1);
  }

  return TRUE;
}

static gboolean
speex_streamheader_to_codecdata (const GValue * streamheader,
    GstMatroskaTrackContext * context)
{
  GArray *bufarr;
  GValue *bufval;
  GstBuffer *buffer;
  guint old_size;

  if (streamheader == NULL || G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY) {
    GST_WARNING ("No or invalid streamheader field in the caps");
    return FALSE;
  }

  bufarr = g_value_peek_pointer (streamheader);
  if (bufarr->len != 2) {
    GST_WARNING ("Too few headers in streamheader field");
    return FALSE;
  }

  context->xiph_headers_to_skip = bufarr->len + 1;

  bufval = &g_array_index (bufarr, GValue, 0);
  if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
    GST_WARNING ("streamheaders array does not contain GstBuffers");
    return FALSE;
  }

  buffer = g_value_peek_pointer (bufval);

  if (gst_buffer_get_size (buffer) < 80
      || gst_buffer_memcmp (buffer, 0, "Speex   ", 8) != 0) {
    GST_WARNING ("Invalid streamheader for Speex");
    return FALSE;
  }

  gst_matroska_mux_free_codec_priv (context);
  context->codec_priv_size = gst_buffer_get_size (buffer);
  context->codec_priv = g_malloc (context->codec_priv_size);
  gst_buffer_extract (buffer, 0, context->codec_priv, -1);

  bufval = &g_array_index (bufarr, GValue, 1);

  if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
    gst_matroska_mux_free_codec_priv (context);
    GST_WARNING ("streamheaders array does not contain GstBuffers");
    return FALSE;
  }

  buffer = g_value_peek_pointer (bufval);

  old_size = context->codec_priv_size;
  context->codec_priv_size += gst_buffer_get_size (buffer);
  context->codec_priv = g_realloc (context->codec_priv,
      context->codec_priv_size);
  gst_buffer_extract (buffer, 0, (guint8 *) context->codec_priv + old_size, -1);

  return TRUE;
}

static const gchar *
aac_codec_data_to_codec_id (GstBuffer * buf)
{
  const gchar *result;
  guint8 profile;

  /* default to MAIN */
  profile = 1;

  if (gst_buffer_get_size (buf) >= 2) {
    gst_buffer_extract (buf, 0, &profile, 1);
    profile >>= 3;
  }

  switch (profile) {
    case 1:
      result = "MAIN";
      break;
    case 2:
      result = "LC";
      break;
    case 3:
      result = "SSR";
      break;
    case 4:
      result = "LTP";
      break;
    default:
      GST_WARNING ("unknown AAC profile, defaulting to MAIN");
      result = "MAIN";
      break;
  }

  return result;
}

/**
 * gst_matroska_mux_audio_pad_setcaps:
 * @pad: Pad which got the caps.
 * @caps: New caps.
 *
 * Setcaps function for audio sink pad.
 *
 * Returns: #TRUE on success.
 */
static gboolean
gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
{
  GstMatroskaTrackContext *context = NULL;
  GstMatroskaTrackAudioContext *audiocontext;
  GstMatroskaMux *mux;
  GstMatroskaPad *collect_pad;
  const gchar *mimetype;
  gint samplerate = 0, channels = 0;
  GstStructure *structure;
  const GValue *codec_data = NULL;
  GstBuffer *buf = NULL;
  const gchar *stream_format = NULL;

  mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));

  /* find context */
  collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
  g_assert (collect_pad);
  context = collect_pad->track;
  g_assert (context);
  g_assert (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO);
  audiocontext = (GstMatroskaTrackAudioContext *) context;

  structure = gst_caps_get_structure (caps, 0);
  mimetype = gst_structure_get_name (structure);

  /* general setup */
  gst_structure_get_int (structure, "rate", &samplerate);
  gst_structure_get_int (structure, "channels", &channels);

  audiocontext->samplerate = samplerate;
  audiocontext->channels = channels;
  audiocontext->bitdepth = 0;
  context->default_duration = 0;

  codec_data = gst_structure_get_value (structure, "codec_data");
  if (codec_data)
    buf = gst_value_get_buffer (codec_data);

  /* TODO: - check if we handle all codecs by the spec, i.e. codec private
   *         data and other settings
   *       - add new formats
   */

  if (!strcmp (mimetype, "audio/mpeg")) {
    gint mpegversion = 0;

    gst_structure_get_int (structure, "mpegversion", &mpegversion);
    switch (mpegversion) {
      case 1:{
        gint layer;
        gint version = 1;
        gint spf;

        gst_structure_get_int (structure, "layer", &layer);

        if (!gst_structure_get_int (structure, "mpegaudioversion", &version)) {
          GST_WARNING_OBJECT (mux,
              "Unable to determine MPEG audio version, assuming 1");
          version = 1;
        }

        if (layer == 1)
          spf = 384;
        else if (layer == 2)
          spf = 1152;
        else if (version == 2)
          spf = 576;
        else
          spf = 1152;

        context->default_duration =
            gst_util_uint64_scale (GST_SECOND, spf, audiocontext->samplerate);

        switch (layer) {
          case 1:
            gst_matroska_mux_set_codec_id (context,
                GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1);
            break;
          case 2:
            gst_matroska_mux_set_codec_id (context,
                GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2);
            break;
          case 3:
            gst_matroska_mux_set_codec_id (context,
                GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L3);
            break;
          default:
            goto refuse_caps;
        }
        break;
      }
      case 2:
      case 4:
        stream_format = gst_structure_get_string (structure, "stream-format");
        /* check this is raw aac */
        if (stream_format) {
          if (strcmp (stream_format, "raw") != 0) {
            GST_WARNING_OBJECT (mux, "AAC stream-format must be 'raw', not %s",
                stream_format);
          }
        } else {
          GST_WARNING_OBJECT (mux, "AAC stream-format not specified, "
              "assuming 'raw'");
        }

        if (buf) {
          if (mpegversion == 2)
            context->codec_id =
                g_strdup_printf (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2 "%s",
                aac_codec_data_to_codec_id (buf));
          else if (mpegversion == 4)
            context->codec_id =
                g_strdup_printf (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4 "%s",
                aac_codec_data_to_codec_id (buf));
          else
            g_assert_not_reached ();
        } else {
          GST_DEBUG_OBJECT (mux, "no AAC codec_data; not packetized");
          goto refuse_caps;
        }
        break;
      default:
        goto refuse_caps;
    }
  } else if (!strcmp (mimetype, "audio/x-raw")) {
    GstAudioInfo info;

    gst_audio_info_init (&info);
    if (!gst_audio_info_from_caps (&info, caps)) {
      GST_DEBUG_OBJECT (mux,
          "broken caps, rejected by gst_audio_info_from_caps");
      goto refuse_caps;
    }

    switch (GST_AUDIO_INFO_FORMAT (&info)) {
      case GST_AUDIO_FORMAT_U8:
      case GST_AUDIO_FORMAT_S16BE:
      case GST_AUDIO_FORMAT_S16LE:
      case GST_AUDIO_FORMAT_S24BE:
      case GST_AUDIO_FORMAT_S24LE:
      case GST_AUDIO_FORMAT_S32BE:
      case GST_AUDIO_FORMAT_S32LE:
        if (GST_AUDIO_INFO_WIDTH (&info) != GST_AUDIO_INFO_DEPTH (&info)) {
          GST_DEBUG_OBJECT (mux, "width must be same as depth!");
          goto refuse_caps;
        }
        if (GST_AUDIO_INFO_IS_BIG_ENDIAN (&info))
          gst_matroska_mux_set_codec_id (context,
              GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE);
        else
          gst_matroska_mux_set_codec_id (context,
              GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE);
        break;
      case GST_AUDIO_FORMAT_F32LE:
      case GST_AUDIO_FORMAT_F64LE:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT);
        break;

      default:
        GST_DEBUG_OBJECT (mux, "wrong format in raw audio caps");
        goto refuse_caps;
    }

    audiocontext->bitdepth = GST_AUDIO_INFO_WIDTH (&info);
  } else if (!strcmp (mimetype, "audio/x-vorbis")) {
    const GValue *streamheader;

    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS);

    gst_matroska_mux_free_codec_priv (context);

    streamheader = gst_structure_get_value (structure, "streamheader");
    if (!vorbis_streamheader_to_codecdata (streamheader, context)) {
      GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
          ("vorbis stream headers missing or malformed"));
      goto refuse_caps;
    }
  } else if (!strcmp (mimetype, "audio/x-flac")) {
    const GValue *streamheader;

    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_FLAC);

    gst_matroska_mux_free_codec_priv (context);

    streamheader = gst_structure_get_value (structure, "streamheader");
    if (!flac_streamheader_to_codecdata (streamheader, context)) {
      GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
          ("flac stream headers missing or malformed"));
      goto refuse_caps;
    }
  } else if (!strcmp (mimetype, "audio/x-speex")) {
    const GValue *streamheader;

    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX);
    gst_matroska_mux_free_codec_priv (context);

    streamheader = gst_structure_get_value (structure, "streamheader");
    if (!speex_streamheader_to_codecdata (streamheader, context)) {
      GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
          ("speex stream headers missing or malformed"));
      goto refuse_caps;
    }
  } else if (!strcmp (mimetype, "audio/x-ac3")) {
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_AC3);
  } else if (!strcmp (mimetype, "audio/x-eac3")) {
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_EAC3);
  } else if (!strcmp (mimetype, "audio/x-dts")) {
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_DTS);
  } else if (!strcmp (mimetype, "audio/x-tta")) {
    gint width;

    /* TTA frame duration */
    context->default_duration = 1.04489795918367346939 * GST_SECOND;

    gst_structure_get_int (structure, "width", &width);
    audiocontext->bitdepth = width;
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_TTA);

  } else if (!strcmp (mimetype, "audio/x-pn-realaudio")) {
    gint raversion;
    const GValue *mdpr_data;

    gst_structure_get_int (structure, "raversion", &raversion);
    switch (raversion) {
      case 1:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4);
        break;
      case 2:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_AUDIO_REAL_28_8);
        break;
      case 8:
        gst_matroska_mux_set_codec_id (context,
            GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK);
        break;
      default:
        goto refuse_caps;
    }

    mdpr_data = gst_structure_get_value (structure, "mdpr_data");
    if (mdpr_data != NULL) {
      guint8 *priv_data = NULL;
      guint priv_data_size = 0;

      GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);

      priv_data_size = gst_buffer_get_size (codec_data_buf);
      priv_data = g_malloc0 (priv_data_size);

      gst_buffer_extract (codec_data_buf, 0, priv_data, -1);

      gst_matroska_mux_free_codec_priv (context);

      context->codec_priv = priv_data;
      context->codec_priv_size = priv_data_size;
    }

  } else if (!strcmp (mimetype, "audio/x-wma")
      || !strcmp (mimetype, "audio/x-alaw")
      || !strcmp (mimetype, "audio/x-mulaw")) {
    guint8 *codec_priv;
    guint codec_priv_size;
    guint16 format = 0;
    gint block_align;
    gint bitrate;

    if (samplerate == 0 || channels == 0) {
      GST_WARNING_OBJECT (mux, "Missing channels/samplerate on caps");
      goto refuse_caps;
    }

    if (!strcmp (mimetype, "audio/x-wma")) {
      gint wmaversion;
      gint depth;

      if (!gst_structure_get_int (structure, "wmaversion", &wmaversion)
          || !gst_structure_get_int (structure, "block_align", &block_align)
          || !gst_structure_get_int (structure, "bitrate", &bitrate)) {
        GST_WARNING_OBJECT (mux, "Missing wmaversion/block_align/bitrate"
            " on WMA caps");
        goto refuse_caps;
      }

      switch (wmaversion) {
        case 1:
          format = GST_RIFF_WAVE_FORMAT_WMAV1;
          break;
        case 2:
          format = GST_RIFF_WAVE_FORMAT_WMAV2;
          break;
        case 3:
          format = GST_RIFF_WAVE_FORMAT_WMAV3;
          break;
        default:
          GST_WARNING_OBJECT (mux, "Unexpected WMA version: %d", wmaversion);
          goto refuse_caps;
      }

      if (gst_structure_get_int (structure, "depth", &depth))
        audiocontext->bitdepth = depth;
    } else if (!strcmp (mimetype, "audio/x-alaw")
        || !strcmp (mimetype, "audio/x-mulaw")) {
      audiocontext->bitdepth = 8;
      if (!strcmp (mimetype, "audio/x-alaw"))
        format = GST_RIFF_WAVE_FORMAT_ALAW;
      else
        format = GST_RIFF_WAVE_FORMAT_MULAW;

      block_align = channels;
      bitrate = block_align * samplerate;
    }
    g_assert (format != 0);

    codec_priv_size = WAVEFORMATEX_SIZE;
    if (buf)
      codec_priv_size += gst_buffer_get_size (buf);

    /* serialize waveformatex structure */
    codec_priv = g_malloc0 (codec_priv_size);
    GST_WRITE_UINT16_LE (codec_priv, format);
    GST_WRITE_UINT16_LE (codec_priv + 2, channels);
    GST_WRITE_UINT32_LE (codec_priv + 4, samplerate);
    GST_WRITE_UINT32_LE (codec_priv + 8, bitrate / 8);
    GST_WRITE_UINT16_LE (codec_priv + 12, block_align);
    GST_WRITE_UINT16_LE (codec_priv + 14, 0);
    if (buf)
      GST_WRITE_UINT16_LE (codec_priv + 16, gst_buffer_get_size (buf));
    else
      GST_WRITE_UINT16_LE (codec_priv + 16, 0);

    /* process codec private/initialization data, if any */
    if (buf) {
      gst_buffer_extract (buf, 0,
          (guint8 *) codec_priv + WAVEFORMATEX_SIZE, -1);
    }

    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_ACM);
    gst_matroska_mux_free_codec_priv (context);
    context->codec_priv = (gpointer) codec_priv;
    context->codec_priv_size = codec_priv_size;
  }

  return TRUE;

  /* ERRORS */
refuse_caps:
  {
    GST_WARNING_OBJECT (mux, "pad %s refused caps %" GST_PTR_FORMAT,
        GST_PAD_NAME (pad), caps);
    return FALSE;
  }
}

/* we probably don't have the data at start,
 * so have to reserve (a maximum) space to write this at the end.
 * bit spacy, but some formats can hold quite some */
#define SUBTITLE_MAX_CODEC_PRIVATE   2048       /* must be > 128 */

/**
 * gst_matroska_mux_subtitle_pad_setcaps:
 * @pad: Pad which got the caps.
 * @caps: New caps.
 *
 * Setcaps function for subtitle sink pad.
 *
 * Returns: #TRUE on success.
 */
static gboolean
gst_matroska_mux_subtitle_pad_setcaps (GstPad * pad, GstCaps * caps)
{
  /* There is now (at least) one such alement (kateenc), and I'm going
     to handle it here and claim it works when it can be piped back
     through GStreamer and VLC */

  GstMatroskaTrackContext *context = NULL;
  GstMatroskaTrackSubtitleContext *scontext;
  GstMatroskaMux *mux;
  GstMatroskaPad *collect_pad;
  const gchar *mimetype;
  GstStructure *structure;
  const GValue *value = NULL;
  GstBuffer *buf = NULL;
  gboolean ret = TRUE;

  mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));

  /* find context */
  collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
  g_assert (collect_pad);
  context = collect_pad->track;
  g_assert (context);
  g_assert (context->type == GST_MATROSKA_TRACK_TYPE_SUBTITLE);
  scontext = (GstMatroskaTrackSubtitleContext *) context;

  structure = gst_caps_get_structure (caps, 0);
  mimetype = gst_structure_get_name (structure);

  /* general setup */
  scontext->check_utf8 = 1;
  scontext->invalid_utf8 = 0;
  context->default_duration = 0;

  if (!strcmp (mimetype, "subtitle/x-kate")) {
    const GValue *streamheader;

    gst_matroska_mux_set_codec_id (context,
        GST_MATROSKA_CODEC_ID_SUBTITLE_KATE);

    gst_matroska_mux_free_codec_priv (context);

    streamheader = gst_structure_get_value (structure, "streamheader");
    if (!kate_streamheader_to_codecdata (streamheader, context)) {
      GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
          ("kate stream headers missing or malformed"));
      ret = FALSE;
      goto exit;
    }
  } else if (!strcmp (mimetype, "text/x-raw")) {
    gst_matroska_mux_set_codec_id (context,
        GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8);
  } else if (!strcmp (mimetype, "application/x-ssa")) {
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA);
  } else if (!strcmp (mimetype, "application/x-ass")) {
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS);
  } else if (!strcmp (mimetype, "application/x-usf")) {
    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_SUBTITLE_USF);
  } else if (!strcmp (mimetype, "subpicture/x-dvd")) {
    gst_matroska_mux_set_codec_id (context,
        GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB);
  } else {
    ret = FALSE;
    goto exit;
  }

  /* maybe some private data, e.g. vobsub */
  value = gst_structure_get_value (structure, "codec_data");
  if (value)
    buf = gst_value_get_buffer (value);
  if (buf != NULL) {
    GstMapInfo map;
    guint8 *priv_data = NULL;

    gst_buffer_map (buf, &map, GST_MAP_READ);

    if (map.size > SUBTITLE_MAX_CODEC_PRIVATE) {
      GST_WARNING_OBJECT (mux, "pad %" GST_PTR_FORMAT " subtitle private data"
          " exceeded maximum (%d); discarding", pad,
          SUBTITLE_MAX_CODEC_PRIVATE);
      gst_buffer_unmap (buf, &map);
      return TRUE;
    }

    gst_matroska_mux_free_codec_priv (context);

    priv_data = g_malloc0 (map.size);
    memcpy (priv_data, map.data, map.size);
    context->codec_priv = priv_data;
    context->codec_priv_size = map.size;
    gst_buffer_unmap (buf, &map);
  }

  GST_DEBUG_OBJECT (pad, "codec_id %s, codec data size %" G_GSIZE_FORMAT,
      GST_STR_NULL (context->codec_id), context->codec_priv_size);

exit:

  return ret;
}


/**
 * gst_matroska_mux_request_new_pad:
 * @element: #GstMatroskaMux.
 * @templ: #GstPadTemplate.
 * @pad_name: New pad name.
 *
 * Request pad function for sink templates.
 *
 * Returns: New #GstPad.
 */
static GstPad *
gst_matroska_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
  GstMatroskaPad *collect_pad;
  GstMatroskamuxPad *newpad;
  gchar *name = NULL;
  const gchar *pad_name = NULL;
  GstMatroskaCapsFunc capsfunc = NULL;
  GstMatroskaTrackContext *context = NULL;
  gint pad_id;
  gboolean locked = TRUE;
  gchar *id = NULL;

  if (templ == gst_element_class_get_pad_template (klass, "audio_%u")) {
    /* don't mix named and unnamed pads, if the pad already exists we fail when
     * trying to add it */
    if (req_name != NULL && sscanf (req_name, "audio_%u", &pad_id) == 1) {
      pad_name = req_name;
    } else {
      name = g_strdup_printf ("audio_%u", mux->num_a_streams++);
      pad_name = name;
    }
    capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_audio_pad_setcaps);
    context = (GstMatroskaTrackContext *)
        g_new0 (GstMatroskaTrackAudioContext, 1);
    context->type = GST_MATROSKA_TRACK_TYPE_AUDIO;
    context->name = g_strdup ("Audio");
  } else if (templ == gst_element_class_get_pad_template (klass, "video_%u")) {
    /* don't mix named and unnamed pads, if the pad already exists we fail when
     * trying to add it */
    if (req_name != NULL && sscanf (req_name, "video_%u", &pad_id) == 1) {
      pad_name = req_name;
    } else {
      name = g_strdup_printf ("video_%u", mux->num_v_streams++);
      pad_name = name;
    }
    capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_video_pad_setcaps);
    context = (GstMatroskaTrackContext *)
        g_new0 (GstMatroskaTrackVideoContext, 1);
    context->type = GST_MATROSKA_TRACK_TYPE_VIDEO;
    context->name = g_strdup ("Video");
  } else if (templ == gst_element_class_get_pad_template (klass, "subtitle_%u")) {
    /* don't mix named and unnamed pads, if the pad already exists we fail when
     * trying to add it */
    if (req_name != NULL && sscanf (req_name, "subtitle_%u", &pad_id) == 1) {
      pad_name = req_name;
    } else {
      name = g_strdup_printf ("subtitle_%u", mux->num_t_streams++);
      pad_name = name;
    }
    capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_subtitle_pad_setcaps);
    context = (GstMatroskaTrackContext *)
        g_new0 (GstMatroskaTrackSubtitleContext, 1);
    context->type = GST_MATROSKA_TRACK_TYPE_SUBTITLE;
    context->name = g_strdup ("Subtitle");
    /* setcaps may only provide proper one a lot later */
    id = g_strdup ("S_SUB_UNKNOWN");
    locked = FALSE;
  } else {
    GST_WARNING_OBJECT (mux, "This is not our template!");
    return NULL;
  }

  newpad = g_object_new (GST_TYPE_MATROSKAMUX_PAD,
      "name", pad_name, "direction", templ->direction, "template", templ, NULL);
  g_free (name);

  gst_matroskamux_pad_init (newpad);
  collect_pad = (GstMatroskaPad *)
      gst_collect_pads_add_pad (mux->collect, GST_PAD (newpad),
      sizeof (GstMatroskamuxPad),
      (GstCollectDataDestroyNotify) gst_matroska_pad_free, locked);

  collect_pad->track = context;
  gst_matroska_pad_reset (collect_pad, FALSE);
  collect_pad->track->codec_id = id;

  collect_pad->capsfunc = capsfunc;
  gst_pad_set_active (GST_PAD (newpad), TRUE);
  if (!gst_element_add_pad (element, GST_PAD (newpad)))
    goto pad_add_failed;

  mux->num_streams++;

  GST_DEBUG_OBJECT (newpad, "Added new request pad");

  return GST_PAD (newpad);

  /* ERROR cases */
pad_add_failed:
  {
    GST_WARNING_OBJECT (mux, "Adding the new pad '%s' failed", pad_name);
    gst_object_unref (newpad);
    return NULL;
  }
}

/**
 * gst_matroska_mux_release_pad:
 * @element: #GstMatroskaMux.
 * @pad: Pad to release.
 *
 * Release a previously requested pad.
*/
static void
gst_matroska_mux_release_pad (GstElement * element, GstPad * pad)
{
  GstMatroskaMux *mux;
  GSList *walk;

  mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));

  for (walk = mux->collect->data; walk; walk = g_slist_next (walk)) {
    GstCollectData *cdata = (GstCollectData *) walk->data;
    GstMatroskaPad *collect_pad = (GstMatroskaPad *) cdata;

    if (cdata->pad == pad) {
      GstClockTime min_dur;     /* observed minimum duration */

      if (GST_CLOCK_TIME_IS_VALID (collect_pad->start_ts) &&
          GST_CLOCK_TIME_IS_VALID (collect_pad->end_ts)) {
        min_dur = GST_CLOCK_DIFF (collect_pad->start_ts, collect_pad->end_ts);
        if (collect_pad->duration < min_dur)
          collect_pad->duration = min_dur;
      }

      if (GST_CLOCK_TIME_IS_VALID (collect_pad->duration) &&
          mux->duration < collect_pad->duration)
        mux->duration = collect_pad->duration;

      break;
    }
  }

  gst_collect_pads_remove_pad (mux->collect, pad);
  if (gst_element_remove_pad (element, pad))
    mux->num_streams--;
}


/**
 * gst_matroska_mux_track_header:
 * @mux: #GstMatroskaMux
 * @context: Tack context.
 *
 * Write a track header.
 */
static void
gst_matroska_mux_track_header (GstMatroskaMux * mux,
    GstMatroskaTrackContext * context)
{
  GstEbmlWrite *ebml = mux->ebml_write;
  guint64 master;

  /* TODO: check if everything necessary is written and check default values */

  /* track type goes before the type-specific stuff */
  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKNUMBER, context->num);
  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKTYPE, context->type);

  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKUID,
      gst_matroska_mux_create_uid ());
  if (context->default_duration) {
    gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TRACKDEFAULTDURATION,
        context->default_duration);
  }
  if (context->language) {
    gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_TRACKLANGUAGE,
        context->language);
  }

  /* FIXME: until we have a nice way of getting the codecname
   * out of the caps, I'm not going to enable this. Too much
   * (useless, double, boring) work... */
  /* TODO: Use value from tags if any */
  /*gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_CODECNAME,
     context->codec_name); */
  gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_TRACKNAME, context->name);

  /* type-specific stuff */
  switch (context->type) {
    case GST_MATROSKA_TRACK_TYPE_VIDEO:{
      GstMatroskaTrackVideoContext *videocontext =
          (GstMatroskaTrackVideoContext *) context;

      master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKVIDEO);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOPIXELWIDTH,
          videocontext->pixel_width);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOPIXELHEIGHT,
          videocontext->pixel_height);
      if (videocontext->display_width && videocontext->display_height) {
        gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEODISPLAYWIDTH,
            videocontext->display_width);
        gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEODISPLAYHEIGHT,
            videocontext->display_height);
      }
      if (context->flags & GST_MATROSKA_VIDEOTRACK_INTERLACED)
        gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOFLAGINTERLACED, 1);
      if (videocontext->fourcc) {
        guint32 fcc_le = GUINT32_TO_LE (videocontext->fourcc);

        gst_ebml_write_binary (ebml, GST_MATROSKA_ID_VIDEOCOLOURSPACE,
            (gpointer) & fcc_le, 4);
      }
      gst_ebml_write_master_finish (ebml, master);

      break;
    }

    case GST_MATROSKA_TRACK_TYPE_AUDIO:{
      GstMatroskaTrackAudioContext *audiocontext =
          (GstMatroskaTrackAudioContext *) context;

      master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKAUDIO);
      if (audiocontext->samplerate != 8000)
        gst_ebml_write_float (ebml, GST_MATROSKA_ID_AUDIOSAMPLINGFREQ,
            audiocontext->samplerate);
      if (audiocontext->channels != 1)
        gst_ebml_write_uint (ebml, GST_MATROSKA_ID_AUDIOCHANNELS,
            audiocontext->channels);
      if (audiocontext->bitdepth) {
        gst_ebml_write_uint (ebml, GST_MATROSKA_ID_AUDIOBITDEPTH,
            audiocontext->bitdepth);
      }
      gst_ebml_write_master_finish (ebml, master);

      break;
    }

      /* this is what we write for now and must be filled
       * and remainder void'ed later on */
#define SUBTITLE_DUMMY_SIZE   (1 + 1 + 14 + 1 + 2 + SUBTITLE_MAX_CODEC_PRIVATE)

    case GST_MATROSKA_TRACK_TYPE_SUBTITLE:{
      gpointer buf;

      context->pos = ebml->pos;
      /* CodecID is mandatory ... */
      gst_ebml_write_ascii (ebml, GST_MATROSKA_ID_CODECID, "S_SUB_UNKNOWN");
      /* reserve space */
      buf = g_malloc0 (SUBTITLE_MAX_CODEC_PRIVATE);
      gst_ebml_write_binary (ebml, GST_EBML_ID_VOID, buf,
          SUBTITLE_MAX_CODEC_PRIVATE);
      g_free (buf);
      /* real data has to be written at finish */
      return;
    }
    default:
      /* doesn't need type-specific data */
      break;
  }

  gst_ebml_write_ascii (ebml, GST_MATROSKA_ID_CODECID, context->codec_id);
  if (context->codec_priv)
    gst_ebml_write_binary (ebml, GST_MATROSKA_ID_CODECPRIVATE,
        context->codec_priv, context->codec_priv_size);
}

#if 0
static void
gst_matroska_mux_write_chapter_title (const gchar * title, GstEbmlWrite * ebml)
{
  guint64 title_master;

  title_master =
      gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CHAPTERDISPLAY);

  gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_CHAPSTRING, title);
  gst_ebml_write_ascii (ebml, GST_MATROSKA_ID_CHAPLANGUAGE,
      GST_MATROSKA_MUX_CHAPLANG);

  gst_ebml_write_master_finish (ebml, title_master);
}

static void
gst_matroska_mux_write_chapter (GstMatroskaMux * mux, GstTocEntry * edition,
    GstTocEntry * entry, GstEbmlWrite * ebml, guint64 * master_chapters,
    guint64 * master_edition)
{
  guint64 uid, master_chapteratom;
  GList *cur;
  GstTocEntry *cur_entry;
  guint count, i;
  gchar *title;
  gint64 start, stop;

  if (G_UNLIKELY (master_chapters != NULL && *master_chapters == 0))
    *master_chapters =
        gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CHAPTERS);

  if (G_UNLIKELY (master_edition != NULL && *master_edition == 0)) {
    /* create uid for the parent */
    uid = gst_matroska_mux_create_uid ();
    g_free (edition->uid);
    edition->uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);

    *master_edition =
        gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_EDITIONENTRY);

    gst_ebml_write_uint (ebml, GST_MATROSKA_ID_EDITIONUID, uid);
    gst_ebml_write_uint (ebml, GST_MATROSKA_ID_EDITIONFLAGHIDDEN, 0);
    gst_ebml_write_uint (ebml, GST_MATROSKA_ID_EDITIONFLAGDEFAULT, 0);
    gst_ebml_write_uint (ebml, GST_MATROSKA_ID_EDITIONFLAGORDERED, 0);
  }

  uid = gst_matroska_mux_create_uid ();
  gst_toc_entry_get_start_stop_times (entry, &start, &stop);

  master_chapteratom =
      gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CHAPTERATOM);
  g_free (entry->uid);
  entry->uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uid);
  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERUID, uid);
  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERTIMESTART, start);
  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERTIMESTOP, stop);
  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERFLAGHIDDEN, 0);
  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CHAPTERFLAGENABLED, 1);

  cur = entry->subentries;
  while (cur != NULL) {
    cur_entry = cur->data;
    gst_matroska_mux_write_chapter (mux, NULL, cur_entry, ebml, NULL, NULL);

    cur = cur->next;
  }

  if (G_LIKELY (entry->tags != NULL)) {
    count = gst_tag_list_get_tag_size (entry->tags, GST_TAG_TITLE);

    for (i = 0; i < count; ++i) {
      gst_tag_list_get_string_index (entry->tags, GST_TAG_TITLE, i, &title);
      gst_matroska_mux_write_chapter_title (title, ebml);
      g_free (title);
    }

    /* remove title tag */
    if (G_LIKELY (count > 0))
      gst_tag_list_remove_tag (entry->tags, GST_TAG_TITLE);
  }

  gst_ebml_write_master_finish (ebml, master_chapteratom);
}

static void
gst_matroska_mux_write_chapter_edition (GstMatroskaMux * mux,
    GstTocEntry * entry, GstEbmlWrite * ebml, guint64 * master_chapters)
{
  guint64 master_edition = 0;
  GList *cur;
  GstTocEntry *subentry;

  cur = gst_toc_entry_get_sub_entries (entry);
  while (cur != NULL) {
    subentry = cur->data;
    gst_matroska_mux_write_chapter (mux, entry, subentry, ebml, master_chapters,
        &master_edition);

    cur = cur->next;
  }

  if (G_LIKELY (master_edition != 0))
    gst_ebml_write_master_finish (ebml, master_edition);
}
#endif

/**
 * gst_matroska_mux_start:
 * @mux: #GstMatroskaMux
 *
 * Start a new matroska file (write headers etc...)
 */
static void
gst_matroska_mux_start (GstMatroskaMux * mux)
{
  GstEbmlWrite *ebml = mux->ebml_write;
  const gchar *doctype;
  guint32 seekhead_id[] = { GST_MATROSKA_ID_SEGMENTINFO,
    GST_MATROSKA_ID_TRACKS,
    GST_MATROSKA_ID_CHAPTERS,
    GST_MATROSKA_ID_CUES,
    GST_MATROSKA_ID_TAGS,
    0
  };
  const gchar *media_type;
  gboolean audio_only;
  guint64 master, child;
  GSList *collected;
  int i;
  guint tracknum = 1;
  GstClockTime duration = 0;
  guint32 segment_uid[4];
  GTimeVal time = { 0, 0 };
  gchar s_id[32];
#if 0
  GstToc *toc;
#endif

  /* if not streaming, check if downstream is seekable */
  if (!mux->streamable) {
    gboolean seekable;
    GstQuery *query;

    query = gst_query_new_seeking (GST_FORMAT_BYTES);
    if (gst_pad_peer_query (mux->srcpad, query)) {
      gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
      GST_INFO_OBJECT (mux, "downstream is %sseekable", seekable ? "" : "not ");
    } else {
      /* have to assume seeking is supported if query not handled downstream */
      GST_WARNING_OBJECT (mux, "downstream did not handle seeking query");
      seekable = FALSE;
    }
    if (!seekable) {
      mux->streamable = TRUE;
      g_object_notify (G_OBJECT (mux), "streamable");
      GST_WARNING_OBJECT (mux, "downstream is not seekable, but "
          "streamable=false. Will ignore that and create streamable output "
          "instead");
    }
    gst_query_unref (query);
  }

  /* stream-start (FIXME: create id based on input ids) */
  g_snprintf (s_id, sizeof (s_id), "matroskamux-%08x", g_random_int ());
  gst_pad_push_event (mux->srcpad, gst_event_new_stream_start (s_id));

  /* output caps */
  audio_only = mux->num_v_streams == 0 && mux->num_a_streams > 0;
  if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) {
    media_type = (audio_only) ? "audio/webm" : "video/webm";
  } else {
    media_type = (audio_only) ? "audio/x-matroska" : "video/x-matroska";
  }
  ebml->caps = gst_caps_new_empty_simple (media_type);
  gst_pad_set_caps (mux->srcpad, ebml->caps);
  /* we start with a EBML header */
  doctype = mux->doctype;
  GST_INFO_OBJECT (ebml, "DocType: %s, Version: %d",
      doctype, mux->doctype_version);
  gst_ebml_write_header (ebml, doctype, mux->doctype_version);

  /* the rest of the header is cached */
  gst_ebml_write_set_cache (ebml, 0x1000);

  /* start a segment */
  mux->segment_pos =
      gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEGMENT);
  mux->segment_master = ebml->pos;

  if (!mux->streamable) {
    /* seekhead (table of contents) - we set the positions later */
    mux->seekhead_pos = ebml->pos;
    master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKHEAD);
    for (i = 0; seekhead_id[i] != 0; i++) {
      child = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKENTRY);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKID, seekhead_id[i]);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKPOSITION, -1);
      gst_ebml_write_master_finish (ebml, child);
    }
    gst_ebml_write_master_finish (ebml, master);
  }

  if (mux->streamable) {
    const GstTagList *tags;

    /* tags */
    tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (mux));

    if (tags != NULL && !gst_tag_list_is_empty (tags)) {
      guint64 master_tags, master_tag;

      GST_DEBUG_OBJECT (mux, "Writing tags");

      /* TODO: maybe limit via the TARGETS id by looking at the source pad */
      mux->tags_pos = ebml->pos;
      master_tags = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAGS);
      master_tag = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAG);
      gst_tag_list_foreach (tags, gst_matroska_mux_write_simple_tag, ebml);
      gst_ebml_write_master_finish (ebml, master_tag);
      gst_ebml_write_master_finish (ebml, master_tags);
    }
  }

  /* segment info */
  mux->info_pos = ebml->pos;
  master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEGMENTINFO);
  for (i = 0; i < 4; i++) {
    segment_uid[i] = g_random_int ();
  }
  gst_ebml_write_binary (ebml, GST_MATROSKA_ID_SEGMENTUID,
      (guint8 *) segment_uid, 16);
  gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TIMECODESCALE, mux->time_scale);
  mux->duration_pos = ebml->pos;
  /* get duration */
  if (!mux->streamable) {
    for (collected = mux->collect->data; collected;
        collected = g_slist_next (collected)) {
      GstMatroskaPad *collect_pad;
      GstPad *thepad;
      gint64 trackduration;

      collect_pad = (GstMatroskaPad *) collected->data;
      thepad = collect_pad->collect.pad;

      /* Query the total length of the track. */
      GST_DEBUG_OBJECT (thepad, "querying peer duration");
      if (gst_pad_peer_query_duration (thepad, GST_FORMAT_TIME, &trackduration)) {
        GST_DEBUG_OBJECT (thepad, "duration: %" GST_TIME_FORMAT,
            GST_TIME_ARGS (trackduration));
        if (trackduration != GST_CLOCK_TIME_NONE && trackduration > duration) {
          duration = (GstClockTime) trackduration;
        }
      }
    }
    gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
        gst_guint64_to_gdouble (duration) /
        gst_guint64_to_gdouble (mux->time_scale));
  }
  gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_MUXINGAPP,
      "GStreamer plugin version " PACKAGE_VERSION);
  if (mux->writing_app && mux->writing_app[0]) {
    gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_WRITINGAPP, mux->writing_app);
  }
  g_get_current_time (&time);
  gst_ebml_write_date (ebml, GST_MATROSKA_ID_DATEUTC, time.tv_sec);
  gst_ebml_write_master_finish (ebml, master);

  /* tracks */
  mux->tracks_pos = ebml->pos;
  master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKS);

  for (collected = mux->collect->data; collected;
      collected = g_slist_next (collected)) {
    GstMatroskaPad *collect_pad;
    GstPad *thepad;

    collect_pad = (GstMatroskaPad *) collected->data;
    thepad = collect_pad->collect.pad;

    if (gst_pad_is_linked (thepad) && gst_pad_is_active (thepad) &&
        collect_pad->track->codec_id != 0) {
      collect_pad->track->num = tracknum++;
      child = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKENTRY);
      gst_matroska_mux_track_header (mux, collect_pad->track);
      gst_ebml_write_master_finish (ebml, child);
      /* some remaining pad/track setup */
      collect_pad->default_duration_scaled =
          gst_util_uint64_scale (collect_pad->track->default_duration,
          1, mux->time_scale);
    }
  }
  gst_ebml_write_master_finish (ebml, master);

  /* FIXME: Check if we get a TOC that is supported by Matroska
   * and clean up the code below */
#if 0
  /* chapters */
  toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux));
  if (toc != NULL && !mux->streamable) {
    guint64 master_chapters = 0;
    GstTocEntry *toc_entry;
    GList *cur, *to_write = NULL;
    gint64 start, stop;

    GST_DEBUG ("Writing chapters");

    /* check whether we have editions or chapters at the root level */
    toc_entry = toc->entries->data;

    if (toc_entry->type != GST_TOC_ENTRY_TYPE_EDITION) {
      toc_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, "");
      gst_toc_entry_set_start_stop_times (toc_entry, -1, -1);

      /* aggregate all chapters without root edition */
      cur = gst_toc_get_entries (toc);
      while (cur != NULL) {
        toc_entry->subentries =
            g_list_prepend (toc_entry->subentries, cur->data);
        cur = cur->next;
      }

      gst_toc_entry_get_start_stop_times (((GstTocEntry *)
              toc_entry->subentries->data), &start, NULL);
      toc_entry->subentries = g_list_reverse (toc_entry->subentries);
      gst_toc_entry_get_start_stop_times (((GstTocEntry *)
              toc_entry->subentries->data), NULL, &stop);
      gst_toc_entry_set_start_stop_times (toc_entry, start, stop);

      to_write = g_list_append (to_write, toc_entry);
    } else {
      toc_entry = NULL;
      to_write = toc->entries;
    }

    /* finally write chapters */
    mux->chapters_pos = ebml->pos;

    cur = to_write;
    while (cur != NULL) {
      gst_matroska_mux_write_chapter_edition (mux, cur->data, ebml,
          &master_chapters);
      cur = cur->next;
    }

    /* close master element if any edition was written */
    if (G_LIKELY (master_chapters != 0))
      gst_ebml_write_master_finish (ebml, master_chapters);

    if (toc_entry != NULL) {
      g_list_free (toc_entry->subentries);
      toc_entry->subentries = NULL;
      gst_toc_entry_unref (toc_entry);
      g_list_free (to_write);
    }
  }
#endif

  /* lastly, flush the cache */
  gst_ebml_write_flush_cache (ebml, FALSE, 0);

#if 0
  if (toc != NULL)
    gst_toc_unref (toc);
#endif
}

static void
gst_matroska_mux_write_simple_tag (const GstTagList * list, const gchar * tag,
    gpointer data)
{
  /* TODO: more sensible tag mappings */
  static const struct
  {
    const gchar *matroska_tagname;
    const gchar *gstreamer_tagname;
  }
  tag_conv[] = {
    {
    GST_MATROSKA_TAG_ID_TITLE, GST_TAG_TITLE}, {
    GST_MATROSKA_TAG_ID_ARTIST, GST_TAG_ARTIST}, {
    GST_MATROSKA_TAG_ID_ALBUM, GST_TAG_ALBUM}, {
    GST_MATROSKA_TAG_ID_COMMENTS, GST_TAG_COMMENT}, {
    GST_MATROSKA_TAG_ID_BITSPS, GST_TAG_BITRATE}, {
    GST_MATROSKA_TAG_ID_BPS, GST_TAG_BITRATE}, {
    GST_MATROSKA_TAG_ID_ENCODER, GST_TAG_ENCODER}, {
    GST_MATROSKA_TAG_ID_DATE, GST_TAG_DATE}, {
    GST_MATROSKA_TAG_ID_ISRC, GST_TAG_ISRC}, {
    GST_MATROSKA_TAG_ID_COPYRIGHT, GST_TAG_COPYRIGHT}, {
    GST_MATROSKA_TAG_ID_BPM, GST_TAG_BEATS_PER_MINUTE}, {
    GST_MATROSKA_TAG_ID_TERMS_OF_USE, GST_TAG_LICENSE}, {
    GST_MATROSKA_TAG_ID_COMPOSER, GST_TAG_COMPOSER}, {
    GST_MATROSKA_TAG_ID_LEAD_PERFORMER, GST_TAG_PERFORMER}, {
    GST_MATROSKA_TAG_ID_GENRE, GST_TAG_GENRE}
  };
  GstEbmlWrite *ebml = (GstEbmlWrite *) data;
  guint i;
  guint64 simpletag_master;

  for (i = 0; i < G_N_ELEMENTS (tag_conv); i++) {
    const gchar *tagname_gst = tag_conv[i].gstreamer_tagname;
    const gchar *tagname_mkv = tag_conv[i].matroska_tagname;

    if (strcmp (tagname_gst, tag) == 0) {
      GValue src = { 0, };
      gchar *dest;

      if (!gst_tag_list_copy_value (&src, list, tag))
        break;
      if ((dest = gst_value_serialize (&src))) {

        simpletag_master = gst_ebml_write_master_start (ebml,
            GST_MATROSKA_ID_SIMPLETAG);
        gst_ebml_write_ascii (ebml, GST_MATROSKA_ID_TAGNAME, tagname_mkv);
        gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_TAGSTRING, dest);
        gst_ebml_write_master_finish (ebml, simpletag_master);
        g_free (dest);
      } else {
        GST_WARNING ("Can't transform tag '%s' to string", tagname_mkv);
      }
      g_value_unset (&src);
      break;
    }
  }
}

#if 0
static void
gst_matroska_mux_write_toc_entry_tags (GstMatroskaMux * mux,
    const GstTocEntry * entry, guint64 * master_tags)
{
  guint64 master_tag, master_targets;
  GstEbmlWrite *ebml;
  GList *cur;

  ebml = mux->ebml_write;

  if (G_UNLIKELY (entry->tags != NULL && !gst_tag_list_is_empty (entry->tags))) {
    if (*master_tags == 0) {
      mux->tags_pos = ebml->pos;
      *master_tags = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAGS);
    }

    master_tag = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAG);
    master_targets =
        gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TARGETS);

    if (entry->type == GST_TOC_ENTRY_TYPE_EDITION)
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TARGETEDITIONUID,
          g_ascii_strtoull (entry->uid, NULL, 10));
    else
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TARGETCHAPTERUID,
          g_ascii_strtoull (entry->uid, NULL, 10));

    gst_ebml_write_master_finish (ebml, master_targets);
    gst_tag_list_foreach (entry->tags, gst_matroska_mux_write_simple_tag, ebml);
    gst_ebml_write_master_finish (ebml, master_tag);
  }

  cur = entry->subentries;
  while (cur != NULL) {
    gst_matroska_mux_write_toc_entry_tags (mux, cur->data, master_tags);
    cur = cur->next;
  }
}
#endif

/**
 * gst_matroska_mux_finish:
 * @mux: #GstMatroskaMux
 *
 * Finish a new matroska file (write index etc...)
 */
static void
gst_matroska_mux_finish (GstMatroskaMux * mux)
{
  GstEbmlWrite *ebml = mux->ebml_write;
  guint64 pos;
  guint64 duration = 0;
  GSList *collected;
  const GstTagList *tags;

  /* finish last cluster */
  if (mux->cluster) {
    gst_ebml_write_master_finish (ebml, mux->cluster);
  }

  /* cues */
  if (mux->index != NULL) {
    guint n;
    guint64 master, pointentry_master, trackpos_master;

    mux->cues_pos = ebml->pos;
    gst_ebml_write_set_cache (ebml, 12 + 41 * mux->num_indexes);
    master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CUES);

    for (n = 0; n < mux->num_indexes; n++) {
      GstMatroskaIndex *idx = &mux->index[n];

      pointentry_master = gst_ebml_write_master_start (ebml,
          GST_MATROSKA_ID_POINTENTRY);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CUETIME,
          idx->time / mux->time_scale);
      trackpos_master = gst_ebml_write_master_start (ebml,
          GST_MATROSKA_ID_CUETRACKPOSITIONS);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CUETRACK, idx->track);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CUECLUSTERPOSITION,
          idx->pos - mux->segment_master);
      gst_ebml_write_master_finish (ebml, trackpos_master);
      gst_ebml_write_master_finish (ebml, pointentry_master);
    }

    gst_ebml_write_master_finish (ebml, master);
    gst_ebml_write_flush_cache (ebml, FALSE, GST_CLOCK_TIME_NONE);
  }

  /* tags */
  tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (mux));

  if ((tags != NULL && !gst_tag_list_is_empty (tags))
      || gst_toc_setter_get_toc (GST_TOC_SETTER (mux)) != NULL) {
    guint64 master_tags = 0, master_tag;
#if 0
    const GstToc *toc;
#endif

    GST_DEBUG_OBJECT (mux, "Writing tags");

#if 0
    toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux));
#endif

    if (tags != NULL) {
      /* TODO: maybe limit via the TARGETS id by looking at the source pad */
      mux->tags_pos = ebml->pos;
      master_tags = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAGS);
      master_tag = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TAG);

      if (tags != NULL)
        gst_tag_list_foreach (tags, gst_matroska_mux_write_simple_tag, ebml);
#if 0
      if (toc != NULL)
        gst_tag_list_foreach (toc->tags, gst_matroska_mux_write_simple_tag,
            ebml);
#endif

      gst_ebml_write_master_finish (ebml, master_tag);
    }
#if 0
    if (toc != NULL) {
      cur = toc->entries;
      while (cur != NULL) {
        gst_matroska_mux_write_toc_entry_tags (mux, cur->data, &master_tags);
        cur = cur->next;
      }
    }
#endif

    if (master_tags != 0)
      gst_ebml_write_master_finish (ebml, master_tags);
  }

  /* update seekhead. We know that:
   * - a seekhead contains 5 entries.
   * - order of entries is as above.
   * - a seekhead has a 4-byte header + 8-byte length
   * - each entry is 2-byte master, 2-byte ID pointer,
   *     2-byte length pointer, all 8/1-byte length, 4-
   *     byte ID and 8-byte length pointer, where the
   *     length pointer starts at 20.
   * - all entries are local to the segment (so pos - segment_master).
   * - so each entry is at 12 + 20 + num * 28. */
  gst_ebml_replace_uint (ebml, mux->seekhead_pos + 32,
      mux->info_pos - mux->segment_master);
  gst_ebml_replace_uint (ebml, mux->seekhead_pos + 60,
      mux->tracks_pos - mux->segment_master);
  if (gst_toc_setter_get_toc (GST_TOC_SETTER (mux)) != NULL
      && mux->chapters_pos > 0) {
    gst_ebml_replace_uint (ebml, mux->seekhead_pos + 88,
        mux->chapters_pos - mux->segment_master);
  } else {
    /* void'ify */
    guint64 my_pos = ebml->pos;

    gst_ebml_write_seek (ebml, mux->seekhead_pos + 68);
    gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
    gst_ebml_write_seek (ebml, my_pos);
  }
  if (mux->index != NULL) {
    gst_ebml_replace_uint (ebml, mux->seekhead_pos + 116,
        mux->cues_pos - mux->segment_master);
  } else {
    /* void'ify */
    guint64 my_pos = ebml->pos;

    gst_ebml_write_seek (ebml, mux->seekhead_pos + 96);
    gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
    gst_ebml_write_seek (ebml, my_pos);
  }

  if (tags != NULL) {
    gst_ebml_replace_uint (ebml, mux->seekhead_pos + 144,
        mux->tags_pos - mux->segment_master);
  } else {
    /* void'ify */
    guint64 my_pos = ebml->pos;

    gst_ebml_write_seek (ebml, mux->seekhead_pos + 124);
    gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
    gst_ebml_write_seek (ebml, my_pos);
  }

  /* loop tracks:
   * - first get the overall duration
   *   (a released track may have left a duration in here)
   * - write some track header data for subtitles
   */
  duration = mux->duration;
  pos = ebml->pos;
  for (collected = mux->collect->data; collected;
      collected = g_slist_next (collected)) {
    GstMatroskaPad *collect_pad;
    GstClockTime min_duration;  /* observed minimum duration */
    GstMatroskaTrackContext *context;
    gint voidleft = 0, fill = 0;
    gpointer codec_id;

    collect_pad = (GstMatroskaPad *) collected->data;
    context = collect_pad->track;

    GST_DEBUG_OBJECT (mux,
        "Pad %" GST_PTR_FORMAT " start ts %" GST_TIME_FORMAT
        " end ts %" GST_TIME_FORMAT, collect_pad,
        GST_TIME_ARGS (collect_pad->start_ts),
        GST_TIME_ARGS (collect_pad->end_ts));

    if (GST_CLOCK_TIME_IS_VALID (collect_pad->start_ts) &&
        GST_CLOCK_TIME_IS_VALID (collect_pad->end_ts)) {
      min_duration =
          GST_CLOCK_DIFF (collect_pad->start_ts, collect_pad->end_ts);
      if (collect_pad->duration < min_duration)
        collect_pad->duration = min_duration;
      GST_DEBUG_OBJECT (collect_pad,
          "final track duration: %" GST_TIME_FORMAT,
          GST_TIME_ARGS (collect_pad->duration));
    }

    if (GST_CLOCK_TIME_IS_VALID (collect_pad->duration) &&
        duration < collect_pad->duration)
      duration = collect_pad->duration;

    if (context->type != GST_MATROSKA_TRACK_TYPE_SUBTITLE || !context->pos)
      continue;

  again:
    /* write subtitle type and possible private data */
    gst_ebml_write_seek (ebml, context->pos);
    /* complex way to write ascii to account for extra filling */
    codec_id = g_malloc0 (strlen (context->codec_id) + 1 + fill);
    strcpy (codec_id, context->codec_id);
    gst_ebml_write_binary (ebml, GST_MATROSKA_ID_CODECID,
        codec_id, strlen (context->codec_id) + 1 + fill);
    g_free (codec_id);
    if (context->codec_priv)
      gst_ebml_write_binary (ebml, GST_MATROSKA_ID_CODECPRIVATE,
          context->codec_priv, context->codec_priv_size);
    voidleft = SUBTITLE_DUMMY_SIZE - (ebml->pos - context->pos);
    /* void'ify; sigh, variable sized length field */
    if (voidleft == 1) {
      fill = 1;
      goto again;
    } else if (voidleft && voidleft <= 128)
      gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, voidleft - 2);
    else if (voidleft >= 130)
      gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, voidleft - 3);
    else if (voidleft == 129) {
      gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 64);
      gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 63);
    }
  }

  /* seek back (optional, but do anyway) */
  gst_ebml_write_seek (ebml, pos);

  /* update duration */
  if (duration != 0) {
    GST_DEBUG_OBJECT (mux, "final total duration: %" GST_TIME_FORMAT,
        GST_TIME_ARGS (duration));
    pos = mux->ebml_write->pos;
    gst_ebml_write_seek (ebml, mux->duration_pos);
    gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
        gst_guint64_to_gdouble (duration) /
        gst_guint64_to_gdouble (mux->time_scale));
    gst_ebml_write_seek (ebml, pos);
  } else {
    /* void'ify */
    guint64 my_pos = ebml->pos;

    gst_ebml_write_seek (ebml, mux->duration_pos);
    gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 8);
    gst_ebml_write_seek (ebml, my_pos);
  }
  GST_DEBUG_OBJECT (mux, "finishing segment");
  /* finish segment - this also writes element length */
  gst_ebml_write_master_finish (ebml, mux->segment_pos);
}

/**
 * gst_matroska_mux_buffer_header:
 * @track: Track context.
 * @relative_timestamp: relative timestamp of the buffer
 * @flags: Buffer flags.
 *
 * Create a buffer containing buffer header.
 *
 * Returns: New buffer.
 */
static GstBuffer *
gst_matroska_mux_create_buffer_header (GstMatroskaTrackContext * track,
    gint16 relative_timestamp, int flags)
{
  GstBuffer *hdr;
  guint8 *data = g_malloc (4);

  hdr = gst_buffer_new_wrapped (data, 4);
  /* track num - FIXME: what if num >= 0x80 (unlikely)? */
  data[0] = track->num | 0x80;
  /* time relative to clustertime */
  GST_WRITE_UINT16_BE (data + 1, relative_timestamp);

  /* flags */
  data[3] = flags;

  return hdr;
}

#define DIRAC_PARSE_CODE_SEQUENCE_HEADER 0x00
#define DIRAC_PARSE_CODE_END_OF_SEQUENCE 0x10
#define DIRAC_PARSE_CODE_IS_PICTURE(x) ((x & 0x08) != 0)

static GstBuffer *
gst_matroska_mux_handle_dirac_packet (GstMatroskaMux * mux,
    GstMatroskaPad * collect_pad, GstBuffer * buf)
{
  GstMatroskaTrackVideoContext *ctx =
      (GstMatroskaTrackVideoContext *) collect_pad->track;
  GstMapInfo map;
  guint8 *data;
  gsize size;
  guint8 parse_code;
  guint32 next_parse_offset;
  GstBuffer *ret = NULL;
  gboolean is_muxing_unit = FALSE;

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

  if (size < 13) {
    gst_buffer_unmap (buf, &map);
    gst_buffer_unref (buf);
    return ret;
  }

  /* Check if this buffer contains a picture or end-of-sequence packet */
  while (size >= 13) {
    if (GST_READ_UINT32_BE (data) != 0x42424344 /* 'BBCD' */ ) {
      gst_buffer_unmap (buf, &map);
      gst_buffer_unref (buf);
      return ret;
    }

    parse_code = GST_READ_UINT8 (data + 4);
    if (parse_code == DIRAC_PARSE_CODE_SEQUENCE_HEADER) {
      if (ctx->dirac_unit) {
        gst_buffer_unref (ctx->dirac_unit);
        ctx->dirac_unit = NULL;
      }
    } else if (DIRAC_PARSE_CODE_IS_PICTURE (parse_code) ||
        parse_code == DIRAC_PARSE_CODE_END_OF_SEQUENCE) {
      is_muxing_unit = TRUE;
      break;
    }

    next_parse_offset = GST_READ_UINT32_BE (data + 5);

    if (G_UNLIKELY (next_parse_offset == 0 || next_parse_offset > size))
      break;

    data += next_parse_offset;
    size -= next_parse_offset;
  }

  if (ctx->dirac_unit)
    ctx->dirac_unit = gst_buffer_append (ctx->dirac_unit, gst_buffer_ref (buf));
  else
    ctx->dirac_unit = gst_buffer_ref (buf);

  gst_buffer_unmap (buf, &map);

  if (is_muxing_unit) {
    ret = gst_buffer_make_writable (ctx->dirac_unit);
    ctx->dirac_unit = NULL;
    gst_buffer_copy_into (ret, buf,
        GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
    gst_buffer_unref (buf);
  } else {
    gst_buffer_unref (buf);
    ret = NULL;
  }

  return ret;
}

static void
gst_matroska_mux_stop_streamheader (GstMatroskaMux * mux)
{
  GstCaps *caps;
  GstStructure *s;
  GValue streamheader = { 0 };
  GValue bufval = { 0 };
  GstBuffer *streamheader_buffer;
  GstEbmlWrite *ebml = mux->ebml_write;

  streamheader_buffer = gst_ebml_stop_streamheader (ebml);
  caps = gst_caps_copy (mux->ebml_write->caps);
  s = gst_caps_get_structure (caps, 0);
  g_value_init (&streamheader, GST_TYPE_ARRAY);
  g_value_init (&bufval, GST_TYPE_BUFFER);
  GST_BUFFER_FLAG_SET (streamheader_buffer, GST_BUFFER_FLAG_HEADER);
  gst_value_set_buffer (&bufval, streamheader_buffer);
  gst_value_array_append_value (&streamheader, &bufval);
  g_value_unset (&bufval);
  gst_structure_set_value (s, "streamheader", &streamheader);
  g_value_unset (&streamheader);
  gst_caps_replace (&ebml->caps, caps);
  gst_buffer_unref (streamheader_buffer);
  gst_pad_set_caps (mux->srcpad, caps);
  gst_caps_unref (caps);
}

/**
 * gst_matroska_mux_write_data:
 * @mux: #GstMatroskaMux
 * @collect_pad: #GstMatroskaPad with the data
 *
 * Write collected data (called from gst_matroska_mux_collected).
 *
 * Returns: Result of the gst_pad_push issued to write the data.
 */
static GstFlowReturn
gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad,
    GstBuffer * buf)
{
  GstEbmlWrite *ebml = mux->ebml_write;
  GstBuffer *hdr;
  guint64 blockgroup;
  gboolean write_duration;
  gint16 relative_timestamp;
  gint64 relative_timestamp64;
  guint64 block_duration;
  gboolean is_video_keyframe = FALSE;
  GstMatroskamuxPad *pad;

  /* write data */
  pad = GST_MATROSKAMUX_PAD_CAST (collect_pad->collect.pad);

  /* vorbis/theora headers are retrieved from caps and put in CodecPrivate */
  if (collect_pad->track->xiph_headers_to_skip > 0) {
    GST_LOG_OBJECT (collect_pad->collect.pad, "dropping streamheader buffer");
    gst_buffer_unref (buf);
    --collect_pad->track->xiph_headers_to_skip;
    return GST_FLOW_OK;
  }

  /* for dirac we have to queue up everything up to a picture unit */
  if (collect_pad->track->codec_id != NULL &&
      strcmp (collect_pad->track->codec_id,
          GST_MATROSKA_CODEC_ID_VIDEO_DIRAC) == 0) {
    buf = gst_matroska_mux_handle_dirac_packet (mux, collect_pad, buf);
    if (!buf)
      return GST_FLOW_OK;
  }

  /* hm, invalid timestamp (due to --to be fixed--- element upstream);
   * this would wreak havoc with time stored in matroska file */
  /* TODO: maybe calculate a timestamp by using the previous timestamp
   * and default duration */
  if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
    GST_WARNING_OBJECT (collect_pad->collect.pad,
        "Invalid buffer timestamp; dropping buffer");
    gst_buffer_unref (buf);
    return GST_FLOW_OK;
  }

  /* set the timestamp for outgoing buffers */
  ebml->timestamp = GST_BUFFER_TIMESTAMP (buf);

  if (collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_VIDEO &&
      !GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
    GST_LOG_OBJECT (mux, "have video keyframe, ts=%" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
    is_video_keyframe = TRUE;
  }

  if (mux->cluster) {
    /* start a new cluster at every keyframe, at every GstForceKeyUnit event,
     * or when we may be reaching the limit of the relative timestamp */
    if (mux->cluster_time +
        mux->max_cluster_duration < GST_BUFFER_TIMESTAMP (buf)
        || is_video_keyframe || mux->force_key_unit_event) {
      if (!mux->streamable)
        gst_ebml_write_master_finish (ebml, mux->cluster);

      /* Forward the GstForceKeyUnit event after finishing the cluster */
      if (mux->force_key_unit_event) {
        gst_pad_push_event (mux->srcpad, mux->force_key_unit_event);
        mux->force_key_unit_event = NULL;
      }

      mux->prev_cluster_size = ebml->pos - mux->cluster_pos;
      mux->cluster_pos = ebml->pos;
      gst_ebml_write_set_cache (ebml, 0x20);
      mux->cluster =
          gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
          gst_util_uint64_scale (GST_BUFFER_TIMESTAMP (buf), 1,
              mux->time_scale));
      GST_LOG_OBJECT (mux, "cluster timestamp %" G_GUINT64_FORMAT,
          gst_util_uint64_scale (GST_BUFFER_TIMESTAMP (buf), 1,
              mux->time_scale));
      gst_ebml_write_flush_cache (ebml, TRUE, GST_BUFFER_TIMESTAMP (buf));
      mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_PREVSIZE,
          mux->prev_cluster_size);
    }
  } else {
    /* first cluster */

    mux->cluster_pos = ebml->pos;
    gst_ebml_write_set_cache (ebml, 0x20);
    mux->cluster = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
    gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
        gst_util_uint64_scale (GST_BUFFER_TIMESTAMP (buf), 1, mux->time_scale));
    gst_ebml_write_flush_cache (ebml, TRUE, GST_BUFFER_TIMESTAMP (buf));
    mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
  }

  /* update duration of this track */
  if (GST_BUFFER_DURATION_IS_VALID (buf))
    collect_pad->duration += GST_BUFFER_DURATION (buf);

  /* We currently write index entries for all video tracks or for the audio
   * track in a single-track audio file.  This could be improved by keeping the
   * index only for the *first* video track. */

  /* TODO: index is useful for every track, should contain the number of
   * the block in the cluster which contains the timestamp, should also work
   * for files with multiple audio tracks.
   */
  if (!mux->streamable &&
      (is_video_keyframe ||
          ((collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) &&
              (mux->num_streams == 1)))) {
    gint last_idx = -1;

    if (mux->min_index_interval != 0) {
      for (last_idx = mux->num_indexes - 1; last_idx >= 0; last_idx--) {
        if (mux->index[last_idx].track == collect_pad->track->num)
          break;
      }
    }

    if (last_idx < 0 || mux->min_index_interval == 0 ||
        (GST_CLOCK_DIFF (mux->index[last_idx].time, GST_BUFFER_TIMESTAMP (buf))
            >= mux->min_index_interval)) {
      GstMatroskaIndex *idx;

      if (mux->num_indexes % 32 == 0) {
        mux->index = g_renew (GstMatroskaIndex, mux->index,
            mux->num_indexes + 32);
      }
      idx = &mux->index[mux->num_indexes++];

      idx->pos = mux->cluster_pos;
      idx->time = GST_BUFFER_TIMESTAMP (buf);
      idx->track = collect_pad->track->num;
    }
  }

  /* Check if the duration differs from the default duration. */
  write_duration = FALSE;
  block_duration = 0;
  if (pad->frame_duration && GST_BUFFER_DURATION_IS_VALID (buf)) {
    block_duration = gst_util_uint64_scale (GST_BUFFER_DURATION (buf),
        1, mux->time_scale);

    /* small difference should be ok. */
    if (block_duration > collect_pad->default_duration_scaled + 1 ||
        block_duration < collect_pad->default_duration_scaled - 1) {
      write_duration = TRUE;
    }
  }

  /* write the block, for doctype v2 use SimpleBlock if possible
   * one slice (*breath*).
   * FIXME: Need to do correct lacing! */
  relative_timestamp64 = GST_BUFFER_TIMESTAMP (buf) - mux->cluster_time;
  if (relative_timestamp64 >= 0) {
    /* round the timestamp */
    relative_timestamp64 += gst_util_uint64_scale (mux->time_scale, 1, 2);
  } else {
    /* round the timestamp */
    relative_timestamp64 -= gst_util_uint64_scale (mux->time_scale, 1, 2);
  }
  relative_timestamp = gst_util_uint64_scale (relative_timestamp64, 1,
      mux->time_scale);
  if (mux->doctype_version > 1 && !write_duration) {
    int flags =
        GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT) ? 0 : 0x80;

    hdr =
        gst_matroska_mux_create_buffer_header (collect_pad->track,
        relative_timestamp, flags);
    gst_ebml_write_set_cache (ebml, 0x40);
    gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_SIMPLEBLOCK,
        gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
    gst_ebml_write_buffer (ebml, hdr);
    gst_ebml_write_flush_cache (ebml, FALSE, GST_BUFFER_TIMESTAMP (buf));
    gst_ebml_write_buffer (ebml, buf);

    return gst_ebml_last_write_result (ebml);
  } else {
    gst_ebml_write_set_cache (ebml, gst_buffer_get_size (buf) * 2);
    /* write and call order slightly unnatural,
     * but avoids seek and minizes pushing */
    blockgroup = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_BLOCKGROUP);
    hdr =
        gst_matroska_mux_create_buffer_header (collect_pad->track,
        relative_timestamp, 0);
    if (write_duration)
      gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION, block_duration);
    gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_BLOCK,
        gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
    gst_ebml_write_buffer (ebml, hdr);
    gst_ebml_write_master_finish_full (ebml, blockgroup,
        gst_buffer_get_size (buf));
    gst_ebml_write_flush_cache (ebml, FALSE, GST_BUFFER_TIMESTAMP (buf));
    gst_ebml_write_buffer (ebml, buf);

    return gst_ebml_last_write_result (ebml);
  }
}

/**
 * gst_matroska_mux_handle_buffer:
 * @pads: #GstCollectPads
 * @uuser_data: #GstMatroskaMux
 *
 * Collectpads callback.
 *
 * Returns: #GstFlowReturn
 */
static GstFlowReturn
gst_matroska_mux_handle_buffer (GstCollectPads * pads, GstCollectData * data,
    GstBuffer * buf, gpointer user_data)
{
  GstMatroskaMux *mux = GST_MATROSKA_MUX (user_data);
  GstEbmlWrite *ebml = mux->ebml_write;
  GstMatroskaPad *best;
  GstFlowReturn ret = GST_FLOW_OK;

  GST_DEBUG_OBJECT (mux, "Collected pads");

  /* start with a header */
  if (mux->state == GST_MATROSKA_MUX_STATE_START) {
    if (mux->collect->data == NULL) {
      GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
          ("No input streams configured"));
      return GST_FLOW_ERROR;
    }
    mux->state = GST_MATROSKA_MUX_STATE_HEADER;
    gst_ebml_start_streamheader (ebml);
    gst_matroska_mux_start (mux);
    gst_matroska_mux_stop_streamheader (mux);
    mux->state = GST_MATROSKA_MUX_STATE_DATA;
  }

  /* provided with stream to write from */
  best = (GstMatroskaPad *) data;

  /* if there is no best pad, we have reached EOS */
  if (best == NULL) {
    GST_DEBUG_OBJECT (mux, "No best pad finishing...");
    if (!mux->streamable) {
      gst_matroska_mux_finish (mux);
    } else {
      GST_DEBUG_OBJECT (mux, "... but streamable, nothing to finish");
    }
    gst_pad_push_event (mux->srcpad, gst_event_new_eos ());
    ret = GST_FLOW_EOS;
    goto exit;
  }

  /* if we have a best stream, should also have a buffer */
  g_assert (buf);

  GST_DEBUG_OBJECT (best->collect.pad, "best pad - buffer ts %"
      GST_TIME_FORMAT " dur %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));

  /* make note of first and last encountered timestamps, so we can calculate
   * the actual duration later when we send an updated header on eos */
  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
    GstClockTime start_ts = GST_BUFFER_TIMESTAMP (buf);
    GstClockTime end_ts = start_ts;

    if (GST_BUFFER_DURATION_IS_VALID (buf))
      end_ts += GST_BUFFER_DURATION (buf);
    else if (best->track->default_duration)
      end_ts += best->track->default_duration;

    if (!GST_CLOCK_TIME_IS_VALID (best->end_ts) || end_ts > best->end_ts)
      best->end_ts = end_ts;

    if (G_UNLIKELY (best->start_ts == GST_CLOCK_TIME_NONE ||
            start_ts < best->start_ts))
      best->start_ts = start_ts;
  }

  /* write one buffer */
  ret = gst_matroska_mux_write_data (mux, best, buf);

exit:
  return ret;
}


/**
 * gst_matroska_mux_change_state:
 * @element: #GstMatroskaMux
 * @transition: State change transition.
 *
 * Change the muxer state.
 *
 * Returns: #GstStateChangeReturn
 */
static GstStateChangeReturn
gst_matroska_mux_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstMatroskaMux *mux = GST_MATROSKA_MUX (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_collect_pads_start (mux->collect);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_collect_pads_stop (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_matroska_mux_reset (GST_ELEMENT (mux));
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

static void
gst_matroska_mux_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstMatroskaMux *mux;

  g_return_if_fail (GST_IS_MATROSKA_MUX (object));
  mux = GST_MATROSKA_MUX (object);

  switch (prop_id) {
    case ARG_WRITING_APP:
      if (!g_value_get_string (value)) {
        GST_WARNING_OBJECT (mux, "writing-app property can not be NULL");
        break;
      }
      g_free (mux->writing_app);
      mux->writing_app = g_value_dup_string (value);
      break;
    case ARG_DOCTYPE_VERSION:
      mux->doctype_version = g_value_get_int (value);
      break;
    case ARG_MIN_INDEX_INTERVAL:
      mux->min_index_interval = g_value_get_int64 (value);
      break;
    case ARG_STREAMABLE:
      mux->streamable = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_matroska_mux_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstMatroskaMux *mux;

  g_return_if_fail (GST_IS_MATROSKA_MUX (object));
  mux = GST_MATROSKA_MUX (object);

  switch (prop_id) {
    case ARG_WRITING_APP:
      g_value_set_string (value, mux->writing_app);
      break;
    case ARG_DOCTYPE_VERSION:
      g_value_set_int (value, mux->doctype_version);
      break;
    case ARG_MIN_INDEX_INTERVAL:
      g_value_set_int64 (value, mux->min_index_interval);
      break;
    case ARG_STREAMABLE:
      g_value_set_boolean (value, mux->streamable);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
