/* ASF muxer plugin for GStreamer
 * Copyright (C) 2009 Thiago Santos <thiagoss@embedded.ufcg.edu.br>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/* based on:
 * - avimux (by Ronald Bultje and Mark Nauwelaerts)
 * - qtmux (by Thiago Santos and Mark Nauwelaerts)
 */

/**
 * SECTION:element-asfmux
 *
 * Muxes media into an ASF file/stream.
 *
 * Pad names are either video_xx or audio_xx, where 'xx' is the
 * stream number of the stream that goes through that pad. Stream numbers
 * are assigned sequentially, starting from 1.
 *
 * <refsect2>
 * <title>Example launch lines</title>
 * <para>(write everything in one line, without the backslash characters)</para>
 * |[
 * gst-launch videotestsrc num-buffers=250 \
 * ! "video/x-raw,format=(string)I420,framerate=(fraction)25/1" ! ffenc_wmv2 \
 * ! asfmux name=mux ! filesink location=test.asf \
 * audiotestsrc num-buffers=440 ! audioconvert \
 * ! "audio/x-raw,rate=44100" ! ffenc_wmav2 ! mux.
 * ]| This creates an ASF file containing an WMV video stream
 * with a test picture and WMA audio stream of a test sound.
 *
 * <title>Live streaming</title>
 * asfmux and rtpasfpay are capable of generating a live asf stream.
 * asfmux has to set its 'streamable' property to true, because in this 
 * mode it won't try to seek back to the start of the file to replace
 * some fields that couldn't be known at the file start. In this mode,
 * it won't also send indexes at the end of the data packets (the actual
 * media content)
 * the following pipelines are an example of this usage.
 * <para>(write everything in one line, without the backslash characters)</para>
 * Server (sender)
 * |[
 * gst-launch -ve videotestsrc ! ffenc_wmv2 ! asfmux name=mux streamable=true \
 * ! rtpasfpay ! udpsink host=127.0.0.1 port=3333 \
 * audiotestsrc ! ffenc_wmav2 ! mux.
 * ]|
 * Client (receiver)
 * |[
 * gst-launch udpsrc port=3333 ! "caps_from_rtpasfpay_at_sender" \
 * ! rtpasfdepay ! decodebin2 name=d ! queue \
 * ! videoconvert ! autovideosink \
 * d. ! queue ! audioconvert ! autoaudiosink
 * ]|
 * </refsect2>
 */

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

#include <string.h>
#include <stdio.h>
#include <gst/gst-i18n-plugin.h>
#include "gstasfmux.h"

#define DEFAULT_SIMPLE_INDEX_TIME_INTERVAL G_GUINT64_CONSTANT (10000000)
#define MAX_PAYLOADS_IN_A_PACKET 63

GST_DEBUG_CATEGORY_STATIC (asfmux_debug);
#define GST_CAT_DEFAULT asfmux_debug

enum
{
  PROP_0,
  PROP_PACKET_SIZE,
  PROP_PREROLL,
  PROP_MERGE_STREAM_TAGS,
  PROP_PADDING,
  PROP_STREAMABLE
};

/* Stores a tag list for the available/known tags
 * in an ASF file
 * Also stores the sizes those entries would use in a
 * content description object and extended content
 * description object
 */
typedef struct
{
  GstTagList *tags;
  guint64 cont_desc_size;
  guint64 ext_cont_desc_size;
} GstAsfTags;

/* Helper struct to be used as user data
 * in gst_tag_foreach function for writing
 * each tag for the metadata objects
 *
 * stream_num is used only for stream dependent tags
 */
typedef struct
{
  GstAsfMux *asfmux;
  guint8 *buf;
  guint16 count;
  guint64 size;
  guint16 stream_num;
} GstAsfExtContDescData;

typedef GstAsfExtContDescData GstAsfMetadataObjData;

#define DEFAULT_PACKET_SIZE 4800
#define DEFAULT_PREROLL 5000
#define DEFAULT_MERGE_STREAM_TAGS TRUE
#define DEFAULT_PADDING 0
#define DEFAULT_STREAMABLE FALSE

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-ms-asf, " "parsed = (boolean) true")
    );

static GstStaticPadTemplate video_sink_factory =
GST_STATIC_PAD_TEMPLATE ("video_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("video/x-wmv, wmvversion = (int) [1,3]"));

static GstStaticPadTemplate audio_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("audio_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("audio/x-wma, wmaversion = (int) [1,3]; "
        "audio/mpeg, layer = (int) 3, mpegversion = (int) 1, "
        "channels = (int) [1,2], rate = (int) [8000,96000]"));

static gboolean gst_asf_mux_audio_set_caps (GstPad * pad, GstCaps * caps);
static gboolean gst_asf_mux_video_set_caps (GstPad * pad, GstCaps * caps);

static GstPad *gst_asf_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gst_asf_mux_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_asf_mux_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_asf_mux_change_state (GstElement * element,
    GstStateChange transition);

static gboolean gst_asf_mux_sink_event (GstCollectPads * pads,
    GstCollectData * cdata, GstEvent * event, GstAsfMux * asfmux);

static void gst_asf_mux_pad_reset (GstAsfPad * data);
static GstFlowReturn gst_asf_mux_collected (GstCollectPads * collect,
    gpointer data);

static GstElementClass *parent_class = NULL;

G_DEFINE_TYPE_WITH_CODE (GstAsfMux, gst_asf_mux, GST_TYPE_ELEMENT,
    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));

static void
gst_asf_mux_reset (GstAsfMux * asfmux)
{
  asfmux->state = GST_ASF_MUX_STATE_NONE;
  asfmux->stream_number = 0;
  asfmux->data_object_size = 0;
  asfmux->data_object_position = 0;
  asfmux->file_properties_object_position = 0;
  asfmux->total_data_packets = 0;
  asfmux->file_size = 0;
  asfmux->packet_size = 0;
  asfmux->first_ts = GST_CLOCK_TIME_NONE;

  if (asfmux->payloads) {
    GSList *walk;
    for (walk = asfmux->payloads; walk; walk = g_slist_next (walk)) {
      gst_asf_payload_free ((AsfPayload *) walk->data);
      walk->data = NULL;
    }
    g_slist_free (asfmux->payloads);
  }
  asfmux->payloads = NULL;
  asfmux->payload_data_size = 0;

  asfmux->file_id.v1 = 0;
  asfmux->file_id.v2 = 0;
  asfmux->file_id.v3 = 0;
  asfmux->file_id.v4 = 0;

  gst_tag_setter_reset_tags (GST_TAG_SETTER (asfmux));
}

static void
gst_asf_mux_finalize (GObject * object)
{
  GstAsfMux *asfmux;

  asfmux = GST_ASF_MUX (object);

  gst_asf_mux_reset (asfmux);
  gst_object_unref (asfmux->collect);

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

static void
gst_asf_mux_class_init (GstAsfMuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->get_property = gst_asf_mux_get_property;
  gobject_class->set_property = gst_asf_mux_set_property;
  gobject_class->finalize = gst_asf_mux_finalize;

  g_object_class_install_property (gobject_class, PROP_PACKET_SIZE,
      g_param_spec_uint ("packet-size", "Packet size",
          "The ASF packets size (bytes)",
          ASF_MULTIPLE_PAYLOAD_HEADER_SIZE + 1, G_MAXUINT32,
          DEFAULT_PACKET_SIZE,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PREROLL,
      g_param_spec_uint64 ("preroll", "Preroll",
          "The preroll time (milisecs)",
          0, G_MAXUINT64,
          DEFAULT_PREROLL,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MERGE_STREAM_TAGS,
      g_param_spec_boolean ("merge-stream-tags", "Merge Stream Tags",
          "If the stream metadata (received as events in the sink) should be "
          "merged to the main file metadata.",
          DEFAULT_MERGE_STREAM_TAGS,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PADDING,
      g_param_spec_uint64 ("padding", "Padding",
          "Size of the padding object to be added to the end of the header. "
          "If this less than 24 (the smaller size of an ASF object), "
          "no padding is added.",
          0, G_MAXUINT64,
          DEFAULT_PADDING,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_STREAMABLE,
      g_param_spec_boolean ("streamable", "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_CONSTRUCT | G_PARAM_STATIC_STRINGS));

  gstelement_class->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_asf_mux_request_new_pad);
  gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_asf_mux_change_state);

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&audio_sink_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&video_sink_factory));

  gst_element_class_set_static_metadata (gstelement_class, "ASF muxer",
      "Codec/Muxer",
      "Muxes audio and video into an ASF stream",
      "Thiago Santos <thiagoss@embedded.ufcg.edu.br>");

  GST_DEBUG_CATEGORY_INIT (asfmux_debug, "asfmux", 0, "Muxer for ASF streams");
}

static void
gst_asf_mux_init (GstAsfMux * asfmux)
{
  asfmux->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
  gst_pad_use_fixed_caps (asfmux->srcpad);
  gst_element_add_pad (GST_ELEMENT (asfmux), asfmux->srcpad);

  asfmux->collect = gst_collect_pads_new ();
  gst_collect_pads_set_function (asfmux->collect,
      (GstCollectPadsFunction) GST_DEBUG_FUNCPTR (gst_asf_mux_collected),
      asfmux);
  gst_collect_pads_set_event_function (asfmux->collect,
      (GstCollectPadsEventFunction) GST_DEBUG_FUNCPTR (gst_asf_mux_sink_event),
      asfmux);

  asfmux->payloads = NULL;
  asfmux->prop_packet_size = DEFAULT_PACKET_SIZE;
  asfmux->prop_preroll = DEFAULT_PREROLL;
  asfmux->prop_merge_stream_tags = DEFAULT_MERGE_STREAM_TAGS;
  asfmux->prop_padding = DEFAULT_PADDING;
  asfmux->prop_streamable = DEFAULT_STREAMABLE;
  gst_asf_mux_reset (asfmux);
}

static gboolean
gst_asf_mux_sink_event (GstCollectPads * pads, GstCollectData * cdata,
    GstEvent * event, GstAsfMux * asfmux)
{
  GstAsfPad *asfpad = (GstAsfPad *) cdata;
  gboolean ret = TRUE;

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

      gst_event_parse_caps (event, &caps);
      if (asfpad->is_audio)
        ret = gst_asf_mux_audio_set_caps (cdata->pad, caps);
      else
        ret = gst_asf_mux_video_set_caps (cdata->pad, caps);
      gst_event_unref (event);
      event = NULL;
      break;
    }
    case GST_EVENT_TAG:{
      GST_DEBUG_OBJECT (asfmux, "received tag event");
      /* we discard tag events that come after we started
       * writing the headers, because tags are to be in
       * the headers
       */
      if (asfmux->state == GST_ASF_MUX_STATE_NONE) {
        GstTagList *list = NULL;
        gst_event_parse_tag (event, &list);
        if (asfmux->merge_stream_tags) {
          GstTagSetter *setter = GST_TAG_SETTER (asfmux);
          const GstTagMergeMode mode =
              gst_tag_setter_get_tag_merge_mode (setter);
          gst_tag_setter_merge_tags (setter, list, mode);
        } else {
          if (asfpad->taglist == NULL) {
            asfpad->taglist = gst_tag_list_new_empty ();
          }
          gst_tag_list_insert (asfpad->taglist, list, GST_TAG_MERGE_REPLACE);
        }
      }
      break;
    }
    default:
      break;
  }

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

  return ret;
}

/**
 * gst_asf_mux_push_buffer:
 * @asfmux: #GstAsfMux that should push the buffer
 * @buf: #GstBuffer to be pushed
 *
 * Pushes a buffer downstream and adds its size to the total file size
 *
 * Returns: the result of #gst_pad_push on the buffer
 */
static GstFlowReturn
gst_asf_mux_push_buffer (GstAsfMux * asfmux, GstBuffer * buf, gsize bufsize)
{
  GstFlowReturn ret;

  ret = gst_pad_push (asfmux->srcpad, buf);

  if (ret == GST_FLOW_OK)
    asfmux->file_size += bufsize;

  return ret;
}

/**
 * content_description_calc_size_for_tag:
 * @taglist: the #GstTagList that contains the tag
 * @tag: the tag's name
 * @user_data: a #GstAsfTags struct for putting the results
 *
 * Function that has the #GstTagForEach signature and
 * is used to calculate the size in bytes for each tag
 * that can be contained in asf's content description object
 * and extended content description object. This size is added
 * to the total size for each of that objects in the #GstAsfTags
 * struct passed in the user_data pointer.
 */
static void
content_description_calc_size_for_tag (const GstTagList * taglist,
    const gchar * tag, gpointer user_data)
{
  const gchar *asftag = gst_asf_get_asf_tag (tag);
  GValue value = { 0 };
  guint type;
  GstAsfTags *asftags = (GstAsfTags *) user_data;
  guint content_size;

  if (asftag == NULL)
    return;

  if (!gst_tag_list_copy_value (&value, taglist, tag)) {
    return;
  }
  type = gst_asf_get_tag_field_type (&value);
  switch (type) {
    case ASF_TAG_TYPE_UNICODE_STR:
    {
      const gchar *text;

      text = g_value_get_string (&value);
      /* +1 -> because of the \0 at the end
       * 2* -> because we have uft8, and asf demands utf16 
       */
      content_size = 2 * (1 + g_utf8_strlen (text, -1));

      if (gst_asf_tag_present_in_content_description (tag)) {
        asftags->cont_desc_size += content_size;
      }
    }
      break;
    case ASF_TAG_TYPE_DWORD:
      content_size = 4;
      break;
    default:
      GST_WARNING ("Unhandled asf tag field type %u for tag %s", type, tag);
      g_value_reset (&value);
      return;
  }
  if (asftag) {
    /* size of the tag content in utf16 +
     * size of the tag name +
     * 3 uint16 (size of the tag name string,
     * size of the tag content string and 
     * type of content
     */
    asftags->ext_cont_desc_size += content_size +
        (g_utf8_strlen (asftag, -1) + 1) * 2 + 6;
  }
  gst_tag_list_add_value (asftags->tags, GST_TAG_MERGE_REPLACE, tag, &value);
  g_value_reset (&value);
}

/* FIXME
 * it is awful to keep track of the size here
 * and get the same tags in the writing function */
/**
 * gst_asf_mux_get_content_description_tags:
 * @asfmux: #GstAsfMux to have its tags proccessed
 * @asftags: #GstAsfTags to hold the results
 *
 * Inspects the tags received by the GstTagSetter interface
 * or possibly by sink tag events and calculates the total
 * size needed for the default and extended content description objects.
 * This results and a copy of the #GstTagList
 * are stored in the #GstAsfTags. We store a copy so that
 * the sizes estimated here mantain the same until they are 
 * written to the asf file.
 */
static void
gst_asf_mux_get_content_description_tags (GstAsfMux * asfmux,
    GstAsfTags * asftags)
{
  const GstTagList *tags;

  tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (asfmux));
  if (tags && !gst_tag_list_is_empty (tags)) {
    if (asftags->tags != NULL) {
      gst_tag_list_unref (asftags->tags);
    }
    asftags->tags = gst_tag_list_new_empty ();
    asftags->cont_desc_size = 0;
    asftags->ext_cont_desc_size = 0;

    GST_DEBUG_OBJECT (asfmux, "Processing tags");
    gst_tag_list_foreach (tags, content_description_calc_size_for_tag, asftags);
  } else {
    GST_DEBUG_OBJECT (asfmux, "No tags received");
  }

  if (asftags->cont_desc_size > 0) {
    asftags->cont_desc_size += ASF_CONTENT_DESCRIPTION_OBJECT_SIZE;
  }
  if (asftags->ext_cont_desc_size > 0) {
    asftags->ext_cont_desc_size += ASF_EXT_CONTENT_DESCRIPTION_OBJECT_SIZE;
  }
}

/**
 * add_metadata_tag_size:
 * @taglist: #GstTagList
 * @tag: tag name
 * @user_data: pointer to a guint to store the result
 *
 * GstTagForeachFunc implementation that accounts the size of
 * each tag in the taglist and adds them to the guint pointed
 * by the user_data
 */
static void
add_metadata_tag_size (const GstTagList * taglist, const gchar * tag,
    gpointer user_data)
{
  const gchar *asftag = gst_asf_get_asf_tag (tag);
  GValue value = { 0 };
  guint type;
  guint content_size;
  guint *total_size = (guint *) user_data;

  if (asftag == NULL)
    return;

  if (!gst_tag_list_copy_value (&value, taglist, tag)) {
    return;
  }
  type = gst_asf_get_tag_field_type (&value);
  switch (type) {
    case ASF_TAG_TYPE_UNICODE_STR:
    {
      const gchar *text;

      text = g_value_get_string (&value);
      /* +1 -> because of the \0 at the end
       * 2* -> because we have uft8, and asf demands utf16 
       */
      content_size = 2 * (1 + g_utf8_strlen (text, -1));
    }
      break;
    case ASF_TAG_TYPE_DWORD:
      content_size = 4;
      break;
    default:
      GST_WARNING ("Unhandled asf tag field type %u for tag %s", type, tag);
      g_value_reset (&value);
      return;
  }
  /* size of reserved (2) +
   * size of stream number (2) +
   * size of the tag content in utf16 +
   * size of the tag name +
   * 2 uint16 (size of the tag name string and type of content) +
   * 1 uint32 (size of the data)
   */
  *total_size +=
      4 + content_size + (g_utf8_strlen (asftag, -1) + 1) * 2 + 4 + 4;
  g_value_reset (&value);
}

/**
 * gst_asf_mux_get_metadata_object_size:
 * @asfmux: #GstAsfMux
 * @asfpad: pad for which the metadata object size should be calculated
 *
 * Calculates the size of the metadata object for the tags of the stream
 * handled by the asfpad in the parameter
 *
 * Returns: The size calculated
 */
static guint
gst_asf_mux_get_metadata_object_size (GstAsfMux * asfmux, GstAsfPad * asfpad)
{
  guint size = ASF_METADATA_OBJECT_SIZE;
  if (asfpad->taglist == NULL || gst_tag_list_is_empty (asfpad->taglist))
    return 0;

  gst_tag_list_foreach (asfpad->taglist, add_metadata_tag_size, &size);
  return size;
}

/**
 * gst_asf_mux_get_headers_size:
 * @asfmux: #GstAsfMux
 *
 * Calculates the size of the headers of the asf stream
 * to be generated by this #GstAsfMux.
 * Its used for determining the size of the buffer to allocate
 * to exactly fit the headers in.
 * Padding and metadata objects sizes are not included.
 *
 * Returns: the calculated size
 */
static guint
gst_asf_mux_get_headers_size (GstAsfMux * asfmux)
{
  GSList *walk;
  gint stream_num = 0;
  guint size = ASF_HEADER_OBJECT_SIZE +
      ASF_FILE_PROPERTIES_OBJECT_SIZE + ASF_HEADER_EXTENSION_OBJECT_SIZE;

  /* per stream data */
  for (walk = asfmux->collect->data; walk; walk = g_slist_next (walk)) {
    GstAsfPad *asfpad = (GstAsfPad *) walk->data;

    if (asfpad->is_audio)
      size += ASF_AUDIO_SPECIFIC_DATA_SIZE;
    else
      size += ASF_VIDEO_SPECIFIC_DATA_SIZE;

    if (asfpad->codec_data)
      size += gst_buffer_get_size (asfpad->codec_data);

    stream_num++;
  }
  size += stream_num * (ASF_STREAM_PROPERTIES_OBJECT_SIZE +
      ASF_EXTENDED_STREAM_PROPERTIES_OBJECT_SIZE);

  return size;
}

/**
 * gst_asf_mux_write_header_object:
 * @asfmux:
 * @buf: pointer to the data pointer
 * @size: size of the header object
 * @child_objects: number of children objects inside the main header object
 *
 * Writes the main asf header object start. The buffer pointer
 * is incremented to the next writing position.
 */
static void
gst_asf_mux_write_header_object (GstAsfMux * asfmux, guint8 ** buf,
    guint64 size, guint32 child_objects)
{
  gst_asf_put_guid (*buf, guids[ASF_HEADER_OBJECT_INDEX]);
  GST_WRITE_UINT64_LE (*buf + 16, size);        /* object size */
  GST_WRITE_UINT32_LE (*buf + 24, child_objects);       /* # of child objects */
  GST_WRITE_UINT8 (*buf + 28, 0x01);    /* reserved */
  GST_WRITE_UINT8 (*buf + 29, 0x02);    /* reserved */
  *buf += ASF_HEADER_OBJECT_SIZE;
}

/**
 * gst_asf_mux_write_file_properties:
 * @asfmux:
 * @buf: pointer to the data pointer
 *
 * Writes the file properties object to the buffer. The buffer pointer
 * is incremented to the next writing position.
 */
static void
gst_asf_mux_write_file_properties (GstAsfMux * asfmux, guint8 ** buf)
{
  gst_asf_put_guid (*buf, guids[ASF_FILE_PROPERTIES_OBJECT_INDEX]);
  GST_WRITE_UINT64_LE (*buf + 16, ASF_FILE_PROPERTIES_OBJECT_SIZE);     /* object size */
  gst_asf_put_guid (*buf + 24, asfmux->file_id);
  GST_WRITE_UINT64_LE (*buf + 40, 0);   /* file size - needs update */
  gst_asf_put_time (*buf + 48, gst_asf_get_current_time ());    /* creation time */
  GST_WRITE_UINT64_LE (*buf + 56, 0);   /* data packets - needs update */
  GST_WRITE_UINT64_LE (*buf + 64, 0);   /* play duration - needs update */
  GST_WRITE_UINT64_LE (*buf + 72, 0);   /* send duration - needs update */
  GST_WRITE_UINT64_LE (*buf + 80, asfmux->preroll);     /* preroll */
  GST_WRITE_UINT32_LE (*buf + 88, 0x1); /* flags - broadcast on */
  GST_WRITE_UINT32_LE (*buf + 92, asfmux->packet_size); /* minimum data packet size */
  GST_WRITE_UINT32_LE (*buf + 96, asfmux->packet_size); /* maximum data packet size */
  GST_WRITE_UINT32_LE (*buf + 100, 0);  /* maximum bitrate TODO */

  *buf += ASF_FILE_PROPERTIES_OBJECT_SIZE;
}

/**
 * gst_asf_mux_write_stream_properties:
 * @asfmux:
 * @buf: pointer to the data pointer
 * @asfpad: Pad that handles the stream
 *
 * Writes the stream properties object in the buffer
 * for the stream handled by the #GstAsfPad passed.
 * The pointer is incremented to the next writing position
 */
static void
gst_asf_mux_write_stream_properties (GstAsfMux * asfmux, guint8 ** buf,
    GstAsfPad * asfpad)
{
  guint32 codec_data_length = 0;
  guint32 media_specific_data_length = 0;
  guint16 flags = 0;

  /* codec specific data length */
  if (asfpad->codec_data)
    codec_data_length = gst_buffer_get_size (asfpad->codec_data);
  if (asfpad->is_audio)
    media_specific_data_length = ASF_AUDIO_SPECIFIC_DATA_SIZE;
  else
    media_specific_data_length = ASF_VIDEO_SPECIFIC_DATA_SIZE;

  GST_DEBUG_OBJECT (asfmux, "Stream %" G_GUINT16_FORMAT " codec data length: %"
      G_GUINT32_FORMAT ", media specific data length: %" G_GUINT32_FORMAT,
      (guint16) asfpad->stream_number, codec_data_length,
      media_specific_data_length);

  gst_asf_put_guid (*buf, guids[ASF_STREAM_PROPERTIES_OBJECT_INDEX]);
  GST_WRITE_UINT64_LE (*buf + 16, ASF_STREAM_PROPERTIES_OBJECT_SIZE + codec_data_length + media_specific_data_length);  /* object size */

  /* stream type */
  if (asfpad->is_audio)
    gst_asf_put_guid (*buf + 24, guids[ASF_AUDIO_MEDIA_INDEX]);
  else
    gst_asf_put_guid (*buf + 24, guids[ASF_VIDEO_MEDIA_INDEX]);
  /* error correction */
  if (asfpad->is_audio) {
    gst_asf_put_guid (*buf + 40, guids[ASF_NO_ERROR_CORRECTION_INDEX]);
  } else {
    gst_asf_put_guid (*buf + 40, guids[ASF_NO_ERROR_CORRECTION_INDEX]);
  }
  GST_WRITE_UINT64_LE (*buf + 56, 0);   /* time offset */

  GST_WRITE_UINT32_LE (*buf + 64, codec_data_length + media_specific_data_length);      /* type specific data length */
  GST_WRITE_UINT32_LE (*buf + 68, 0);   /* error correction data length */

  flags = (asfpad->stream_number & 0x7F);
  GST_WRITE_UINT16_LE (*buf + 72, flags);
  GST_WRITE_UINT32_LE (*buf + 74, 0);   /* reserved */

  *buf += ASF_STREAM_PROPERTIES_OBJECT_SIZE;
  /* audio specific data */
  if (asfpad->is_audio) {
    GstAsfAudioPad *audiopad = (GstAsfAudioPad *) asfpad;
    GST_WRITE_UINT16_LE (*buf, audiopad->audioinfo.format);
    GST_WRITE_UINT16_LE (*buf + 2, audiopad->audioinfo.channels);
    GST_WRITE_UINT32_LE (*buf + 4, audiopad->audioinfo.rate);
    GST_WRITE_UINT32_LE (*buf + 8, audiopad->audioinfo.av_bps);
    GST_WRITE_UINT16_LE (*buf + 12, audiopad->audioinfo.blockalign);
    GST_WRITE_UINT16_LE (*buf + 14, audiopad->audioinfo.bits_per_sample);
    GST_WRITE_UINT16_LE (*buf + 16, codec_data_length);

    GST_DEBUG_OBJECT (asfmux,
        "wave formatex values: codec_id=%" G_GUINT16_FORMAT ", channels=%"
        G_GUINT16_FORMAT ", rate=%" G_GUINT32_FORMAT ", bytes_per_sec=%"
        G_GUINT32_FORMAT ", block_alignment=%" G_GUINT16_FORMAT
        ", bits_per_sample=%" G_GUINT16_FORMAT ", codec_data_length=%u",
        audiopad->audioinfo.format, audiopad->audioinfo.channels,
        audiopad->audioinfo.rate, audiopad->audioinfo.av_bps,
        audiopad->audioinfo.blockalign, audiopad->audioinfo.bits_per_sample,
        codec_data_length);


    *buf += ASF_AUDIO_SPECIFIC_DATA_SIZE;
  } else {
    GstAsfVideoPad *videopad = (GstAsfVideoPad *) asfpad;
    GST_WRITE_UINT32_LE (*buf, (guint32) videopad->vidinfo.width);
    GST_WRITE_UINT32_LE (*buf + 4, (guint32) videopad->vidinfo.height);
    GST_WRITE_UINT8 (*buf + 8, 2);

    /* the BITMAPINFOHEADER size + codec_data size */
    GST_WRITE_UINT16_LE (*buf + 9,
        ASF_VIDEO_SPECIFIC_DATA_SIZE + codec_data_length - 11);

    /* BITMAPINFOHEADER */
    GST_WRITE_UINT32_LE (*buf + 11,
        ASF_VIDEO_SPECIFIC_DATA_SIZE + codec_data_length - 11);
    gst_asf_put_i32 (*buf + 15, videopad->vidinfo.width);
    gst_asf_put_i32 (*buf + 19, videopad->vidinfo.height);
    GST_WRITE_UINT16_LE (*buf + 23, 1); /* reserved */
    GST_WRITE_UINT16_LE (*buf + 25, videopad->vidinfo.bit_cnt);
    GST_WRITE_UINT32_LE (*buf + 27, videopad->vidinfo.compression);
    GST_WRITE_UINT32_LE (*buf + 31, videopad->vidinfo.width *
        videopad->vidinfo.height * videopad->vidinfo.bit_cnt);
    GST_WRITE_UINT32_LE (*buf + 35, videopad->vidinfo.xpels_meter);
    GST_WRITE_UINT32_LE (*buf + 39, videopad->vidinfo.ypels_meter);
    GST_WRITE_UINT32_LE (*buf + 43, videopad->vidinfo.num_colors);
    GST_WRITE_UINT32_LE (*buf + 47, videopad->vidinfo.imp_colors);

    *buf += ASF_VIDEO_SPECIFIC_DATA_SIZE;
  }

  if (codec_data_length > 0)
    gst_buffer_extract (asfpad->codec_data, 0, *buf, codec_data_length);

  *buf += codec_data_length;
}

/**
 * gst_asf_mux_write_header_extension:
 * @asfmux:
 * @buf: pointer to the buffer pointer
 * @extension_size: size of the extensions
 *
 * Writes the header of the header extension object. The buffer pointer
 * is incremented to the next writing position (the  header extension object
 * childs should be writen from that point)
 */
static void
gst_asf_mux_write_header_extension (GstAsfMux * asfmux, guint8 ** buf,
    guint64 extension_size)
{
  gst_asf_put_guid (*buf, guids[ASF_HEADER_EXTENSION_OBJECT_INDEX]);
  GST_WRITE_UINT64_LE (*buf + 16, ASF_HEADER_EXTENSION_OBJECT_SIZE + extension_size);   /* object size */
  gst_asf_put_guid (*buf + 24, guids[ASF_RESERVED_1_INDEX]);    /* reserved */
  GST_WRITE_UINT16_LE (*buf + 40, 6);   /* reserved */
  GST_WRITE_UINT32_LE (*buf + 42, extension_size);      /* header extension data size */
  *buf += ASF_HEADER_EXTENSION_OBJECT_SIZE;
}

/**
 * gst_asf_mux_write_extended_stream_properties:
 * @asfmux:
 * @buf: pointer to the buffer pointer
 * @asfpad: Pad that handles the stream of the properties to be writen
 *
 * Writes the extended stream properties object (that is part of the
 * header extension objects) for the stream handled by asfpad
 */
static void
gst_asf_mux_write_extended_stream_properties (GstAsfMux * asfmux, guint8 ** buf,
    GstAsfPad * asfpad)
{
  gst_asf_put_guid (*buf, guids[ASF_EXTENDED_STREAM_PROPERTIES_OBJECT_INDEX]);
  GST_WRITE_UINT64_LE (*buf + 16, ASF_EXTENDED_STREAM_PROPERTIES_OBJECT_SIZE);
  GST_WRITE_UINT64_LE (*buf + 24, 0);   /* start time */
  GST_WRITE_UINT64_LE (*buf + 32, 0);   /* end time */
  GST_WRITE_UINT32_LE (*buf + 40, asfpad->bitrate);     /* bitrate */
  GST_WRITE_UINT32_LE (*buf + 44, 0);   /* buffer size */
  GST_WRITE_UINT32_LE (*buf + 48, 0);   /* initial buffer fullness */
  GST_WRITE_UINT32_LE (*buf + 52, asfpad->bitrate);     /* alternate data bitrate */
  GST_WRITE_UINT32_LE (*buf + 56, 0);   /* alternate buffer size */
  GST_WRITE_UINT32_LE (*buf + 60, 0);   /* alternate initial buffer fullness */
  GST_WRITE_UINT32_LE (*buf + 64, 0);   /* maximum object size */

  /* flags */
  if (asfpad->is_audio) {
    /* TODO check if audio is seekable */
    GST_WRITE_UINT32_LE (*buf + 68, 0x0);
  } else {
    /* video has indexes, so it is seekable unless we are streaming */
    if (asfmux->prop_streamable)
      GST_WRITE_UINT32_LE (*buf + 68, 0x0);
    else
      GST_WRITE_UINT32_LE (*buf + 68, 0x2);
  }

  GST_WRITE_UINT16_LE (*buf + 72, asfpad->stream_number);
  GST_WRITE_UINT16_LE (*buf + 74, 0);   /* language index */
  GST_WRITE_UINT64_LE (*buf + 76, 0);   /* avg time per frame */
  GST_WRITE_UINT16_LE (*buf + 84, 0);   /* stream name count */
  GST_WRITE_UINT16_LE (*buf + 86, 0);   /* payload extension count */

  *buf += ASF_EXTENDED_STREAM_PROPERTIES_OBJECT_SIZE;
}

/**
 * gst_asf_mux_write_string_with_size:
 * @asfmux:
 * @size_buf: pointer to the memory position to write the size of the string
 * @str_buf: pointer to the memory position to write the string
 * @str: the string to be writen (in UTF-8)
 * @use32: if the string size should be writen with 32 bits (if true) 
 * or with 16 (if false)
 *
 * Writes a string with its size as it is needed in many asf objects.
 * The size is writen to size_buf as a WORD field if use32 is false, and
 * as a DWORD if use32 is true. The string is writen to str_buf in UTF16-LE.
 * The string should be passed in UTF-8.
 *
 * The string size in UTF16-LE is returned.
 */
static guint64
gst_asf_mux_write_string_with_size (GstAsfMux * asfmux,
    guint8 * size_buf, guint8 * str_buf, const gchar * str, gboolean use32)
{
  GError *error = NULL;
  gsize str_size = 0;
  gchar *str_utf16 = NULL;

  GST_LOG_OBJECT (asfmux, "Writing extended content description string: "
      "%s", str);

  /* 
   * Covert the string to utf16
   * Also force the last bytes to null terminated,
   * tags were with extra weird characters without it.
   */
  str_utf16 = g_convert (str, -1, "UTF-16LE", "UTF-8", NULL, &str_size, &error);

  /* sum up the null terminating char */
  str_size += 2;

  if (use32)
    GST_WRITE_UINT32_LE (size_buf, str_size);
  else
    GST_WRITE_UINT16_LE (size_buf, str_size);
  if (error) {
    GST_WARNING_OBJECT (asfmux, "Error converting string "
        "to UTF-16: %s - %s", str, error->message);
    g_error_free (error);
    memset (str_buf, 0, str_size);
  } else {
    /* HACK: g_convert seems to add only a single byte null char to
     * the end of the stream, we force the second one */
    memcpy (str_buf, str_utf16, str_size - 1);
    str_buf[str_size - 1] = 0;
  }
  g_free (str_utf16);
  return str_size;
}

/**
 * gst_asf_mux_write_content_description_entry:
 * @asfmux:
 * @tags:
 * @tagname:
 * @size_buf:
 * @data_buf:
 *
 * Checks if a string tag with tagname exists in the taglist. If it
 * exists it is writen as an UTF-16LE to data_buf and its size in bytes
 * is writen to size_buf. It is used for writing content description 
 * object fields.
 *
 * Returns: the size of the string
 */
static guint16
gst_asf_mux_write_content_description_entry (GstAsfMux * asfmux,
    const GstTagList * tags, const gchar * tagname,
    guint8 * size_buf, guint8 * data_buf)
{
  gchar *text = NULL;
  guint16 text_size = 0;
  if (gst_tag_list_get_string (tags, tagname, &text)) {
    text_size = gst_asf_mux_write_string_with_size (asfmux, size_buf,
        data_buf, text, FALSE);
    g_free (text);
  } else {
    GST_WRITE_UINT16_LE (size_buf, 0);
  }
  return text_size;
}

static guint64
gst_asf_mux_write_ext_content_description_dword_entry (GstAsfMux * asfmux,
    guint8 * buf, const gchar * asf_tag, const guint32 value)
{
  guint64 tag_size;
  GST_DEBUG_OBJECT (asfmux, "Writing extended content description tag: "
      "%s (%u)", asf_tag, value);

  tag_size = gst_asf_mux_write_string_with_size (asfmux, buf, buf + 2,
      asf_tag, FALSE);
  buf += tag_size + 2;
  GST_WRITE_UINT16_LE (buf, ASF_TAG_TYPE_DWORD);
  GST_WRITE_UINT16_LE (buf + 2, 4);
  GST_WRITE_UINT32_LE (buf + 4, value);

  /* tagsize -> string size
   * 2 -> string size field size
   * 4 -> dword entry
   * 4 -> type of entry + entry size
   */
  return tag_size + 2 + 4 + 4;
}

static guint64
gst_asf_mux_write_ext_content_description_string_entry (GstAsfMux * asfmux,
    guint8 * buf, const gchar * asf_tag, const gchar * text)
{
  guint64 tag_size = 0;
  guint64 text_size = 0;

  GST_DEBUG_OBJECT (asfmux, "Writing extended content description tag: "
      "%s (%s)", asf_tag, text);

  tag_size = gst_asf_mux_write_string_with_size (asfmux,
      buf, buf + 2, asf_tag, FALSE);
  GST_WRITE_UINT16_LE (buf + tag_size + 2, ASF_TAG_TYPE_UNICODE_STR);
  buf += tag_size + 2 + 2;
  text_size = gst_asf_mux_write_string_with_size (asfmux,
      buf, buf + 2, text, FALSE);

  /* the size of the strings in utf16-le plus the 3 WORD fields */
  return tag_size + text_size + 6;
}

static void
gst_asf_mux_write_content_description (GstAsfMux * asfmux, guint8 ** buf,
    const GstTagList * tags)
{
  guint8 *values = (*buf) + ASF_CONTENT_DESCRIPTION_OBJECT_SIZE;
  guint64 size = 0;

  GST_DEBUG_OBJECT (asfmux, "Writing content description object");

  gst_asf_put_guid (*buf, guids[ASF_CONTENT_DESCRIPTION_INDEX]);

  values += gst_asf_mux_write_content_description_entry (asfmux, tags,
      GST_TAG_TITLE, *buf + 24, values);
  values += gst_asf_mux_write_content_description_entry (asfmux, tags,
      GST_TAG_ARTIST, *buf + 26, values);
  values += gst_asf_mux_write_content_description_entry (asfmux, tags,
      GST_TAG_COPYRIGHT, *buf + 28, values);
  values += gst_asf_mux_write_content_description_entry (asfmux, tags,
      GST_TAG_DESCRIPTION, *buf + 30, values);

  /* rating is currently not present in gstreamer tags, so we put 0 */
  GST_WRITE_UINT16_LE (*buf + 32, 0);

  size += values - *buf;
  GST_WRITE_UINT64_LE (*buf + 16, size);
  *buf += size;
}

static void
write_ext_content_description_tag (const GstTagList * taglist,
    const gchar * tag, gpointer user_data)
{
  const gchar *asftag = gst_asf_get_asf_tag (tag);
  GValue value = { 0 };
  guint type;
  GstAsfExtContDescData *data = (GstAsfExtContDescData *) user_data;

  if (asftag == NULL)
    return;

  if (!gst_tag_list_copy_value (&value, taglist, tag)) {
    return;
  }

  type = gst_asf_get_tag_field_type (&value);
  switch (type) {
    case ASF_TAG_TYPE_UNICODE_STR:
    {
      const gchar *text;
      text = g_value_get_string (&value);
      data->size +=
          gst_asf_mux_write_ext_content_description_string_entry (data->asfmux,
          data->buf + data->size, asftag, text);
    }
      break;
    case ASF_TAG_TYPE_DWORD:
    {
      guint num = g_value_get_uint (&value);
      data->size +=
          gst_asf_mux_write_ext_content_description_dword_entry (data->asfmux,
          data->buf + data->size, asftag, num);
    }
      break;
    default:
      GST_WARNING_OBJECT (data->asfmux,
          "Unhandled asf tag field type %u for tag %s", type, tag);
      g_value_reset (&value);
      return;
  }
  data->count++;
  g_value_reset (&value);
}

static void
gst_asf_mux_write_ext_content_description (GstAsfMux * asfmux, guint8 ** buf,
    GstTagList * tags)
{
  GstAsfExtContDescData extContDesc;
  extContDesc.asfmux = asfmux;
  extContDesc.buf = *buf;
  extContDesc.count = 0;
  extContDesc.size = ASF_EXT_CONTENT_DESCRIPTION_OBJECT_SIZE;

  GST_DEBUG_OBJECT (asfmux, "Writing extended content description object");
  gst_asf_put_guid (*buf, guids[ASF_EXT_CONTENT_DESCRIPTION_INDEX]);

  gst_tag_list_foreach (tags, write_ext_content_description_tag, &extContDesc);

  GST_WRITE_UINT64_LE (*buf + 16, extContDesc.size);
  GST_WRITE_UINT16_LE (*buf + 24, extContDesc.count);

  *buf += extContDesc.size;
}

static void
write_metadata_tag (const GstTagList * taglist, const gchar * tag,
    gpointer user_data)
{
  const gchar *asftag = gst_asf_get_asf_tag (tag);
  GValue value = { 0 };
  guint type;
  GstAsfMetadataObjData *data = (GstAsfMetadataObjData *) user_data;
  guint16 tag_size;
  guint32 content_size;

  if (asftag == NULL)
    return;

  if (!gst_tag_list_copy_value (&value, taglist, tag)) {
    return;
  }

  type = gst_asf_get_tag_field_type (&value);
  switch (type) {
    case ASF_TAG_TYPE_UNICODE_STR:
    {
      const gchar *text;
      text = g_value_get_string (&value);
      GST_WRITE_UINT16_LE (data->buf + data->size, 0);
      GST_WRITE_UINT16_LE (data->buf + data->size + 2, data->stream_num);
      data->size += 4;

      tag_size = gst_asf_mux_write_string_with_size (data->asfmux,
          data->buf + data->size, data->buf + data->size + 8, asftag, FALSE);
      data->size += 2;

      GST_WRITE_UINT16_LE (data->buf + data->size, type);
      data->size += 2;

      content_size = gst_asf_mux_write_string_with_size (data->asfmux,
          data->buf + data->size, data->buf + data->size + tag_size + 4, text,
          TRUE);
      data->size += tag_size + content_size + 4;
    }
      break;
    case ASF_TAG_TYPE_DWORD:
    {
      guint num = g_value_get_uint (&value);
      GST_WRITE_UINT16_LE (data->buf + data->size, 0);
      GST_WRITE_UINT16_LE (data->buf + data->size + 2, data->stream_num);
      data->size += 4;

      tag_size = gst_asf_mux_write_string_with_size (data->asfmux,
          data->buf + data->size, data->buf + data->size + 8, asftag, FALSE);
      data->size += 2;

      GST_WRITE_UINT16_LE (data->buf + data->size, type);
      data->size += 2;
      /* dword length */
      GST_WRITE_UINT32_LE (data->buf + data->size, 4);
      data->size += 4 + tag_size;

      GST_WRITE_UINT32_LE (data->buf + data->size, num);
      data->size += 4;
    }
      break;
    default:
      GST_WARNING_OBJECT (data->asfmux,
          "Unhandled asf tag field type %u for tag %s", type, tag);
      g_value_reset (&value);
      return;
  }

  data->count++;
  g_value_reset (&value);
}

static void
gst_asf_mux_write_metadata_object (GstAsfMux * asfmux, guint8 ** buf,
    GstAsfPad * asfpad)
{
  GstAsfMetadataObjData metaObjData;
  metaObjData.asfmux = asfmux;
  metaObjData.buf = *buf;
  metaObjData.count = 0;
  metaObjData.size = ASF_METADATA_OBJECT_SIZE;
  metaObjData.stream_num = asfpad->stream_number;

  if (asfpad->taglist == NULL || gst_tag_list_is_empty (asfpad->taglist))
    return;

  GST_DEBUG_OBJECT (asfmux, "Writing metadata object");
  gst_asf_put_guid (*buf, guids[ASF_METADATA_OBJECT_INDEX]);

  gst_tag_list_foreach (asfpad->taglist, write_metadata_tag, &metaObjData);

  GST_WRITE_UINT64_LE (*buf + 16, metaObjData.size);
  GST_WRITE_UINT16_LE (*buf + 24, metaObjData.count);

  *buf += metaObjData.size;
}

static void
gst_asf_mux_write_padding_object (GstAsfMux * asfmux, guint8 ** buf,
    guint64 padding)
{
  if (padding < ASF_PADDING_OBJECT_SIZE) {
    return;
  }

  GST_DEBUG_OBJECT (asfmux, "Writing padding object of size %" G_GUINT64_FORMAT,
      padding);
  gst_asf_put_guid (*buf, guids[ASF_PADDING_OBJECT_INDEX]);
  GST_WRITE_UINT64_LE (*buf + 16, padding);
  memset (*buf + 24, 0, padding - ASF_PADDING_OBJECT_SIZE);
  *buf += padding;
}

static void
gst_asf_mux_write_data_object (GstAsfMux * asfmux, guint8 ** buf)
{
  gst_asf_put_guid (*buf, guids[ASF_DATA_OBJECT_INDEX]);

  /* Data object size. This is always >= ASF_DATA_OBJECT_SIZE. The standard
   * specifically accepts the value 0 in live streams, but WMP is not accepting
   * this while streaming using WMSP, so we default to minimum size also for
   * live streams. Otherwise this field must be updated later on when we know 
   * the complete stream size.
   */
  GST_WRITE_UINT64_LE (*buf + 16, ASF_DATA_OBJECT_SIZE);

  gst_asf_put_guid (*buf + 24, asfmux->file_id);
  GST_WRITE_UINT64_LE (*buf + 40, 0);   /* total data packets */
  GST_WRITE_UINT16_LE (*buf + 48, 0x0101);      /* reserved */
  *buf += ASF_DATA_OBJECT_SIZE;
}

static void
gst_asf_mux_put_buffer_in_streamheader (GValue * streamheader,
    GstBuffer * buffer)
{
  GValue value = { 0 };
  GstBuffer *buf;

  g_value_init (&value, GST_TYPE_BUFFER);
  buf = gst_buffer_copy (buffer);
  gst_value_set_buffer (&value, buf);
  gst_buffer_unref (buf);
  gst_value_array_append_value (streamheader, &value);
  g_value_unset (&value);
}

static guint
gst_asf_mux_find_payload_parsing_info_size (GstAsfMux * asfmux)
{
  /* Minimum payload parsing information size is 8 bytes */
  guint size = 8;

  if (asfmux->prop_packet_size > 65535)
    size += 4;
  else
    size += 2;

  if (asfmux->prop_padding > 65535)
    size += 4;
  else
    size += 2;

  return size;
}

/**
 * gst_asf_mux_start_file:
 * @asfmux: #GstAsfMux
 *
 * Starts the asf file/stream by creating and pushing
 * the headers downstream.
 */
static GstFlowReturn
gst_asf_mux_start_file (GstAsfMux * asfmux)
{
  GstBuffer *buf = NULL;
  guint8 *bufdata = NULL;
  GSList *walk;
  guint stream_num = g_slist_length (asfmux->collect->data);
  guint metadata_obj_size = 0;
  GstAsfTags *asftags;
  GValue streamheader = { 0 };
  GstCaps *caps;
  GstStructure *structure;
  guint64 padding = asfmux->prop_padding;
  GstSegment segment;
  GstMapInfo map;
  gsize bufsize;
  gchar s_id[32];

  if (padding < ASF_PADDING_OBJECT_SIZE)
    padding = 0;

  /* from this point we started writing the headers */
  GST_INFO_OBJECT (asfmux, "Writing headers");
  asfmux->state = GST_ASF_MUX_STATE_HEADERS;

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

  caps = gst_pad_get_pad_template_caps (asfmux->srcpad);
  gst_pad_set_caps (asfmux->srcpad, caps);
  gst_caps_unref (caps);

  /* let downstream know we think in BYTES and expect to do seeking later */
  gst_segment_init (&segment, GST_FORMAT_BYTES);
  gst_pad_push_event (asfmux->srcpad, gst_event_new_segment (&segment));

  gst_asf_generate_file_id (&asfmux->file_id);

  /* Get the metadata for content description object.
   * We store our own taglist because it might get changed from now
   * to the time we actually add its contents to the file, changing
   * the size of the data we already calculated here.
   */
  asftags = g_new0 (GstAsfTags, 1);
  gst_asf_mux_get_content_description_tags (asfmux, asftags);

  /* get the total metadata objects size */
  for (walk = asfmux->collect->data; walk; walk = g_slist_next (walk)) {
    metadata_obj_size += gst_asf_mux_get_metadata_object_size (asfmux,
        (GstAsfPad *) walk->data);
  }

  /* alloc a buffer for all header objects */
  buf = gst_buffer_new_and_alloc (gst_asf_mux_get_headers_size (asfmux) +
      asftags->cont_desc_size +
      asftags->ext_cont_desc_size +
      metadata_obj_size + padding + ASF_DATA_OBJECT_SIZE);

  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  bufdata = map.data;
  bufsize = map.size;

  gst_asf_mux_write_header_object (asfmux, &bufdata, map.size -
      ASF_DATA_OBJECT_SIZE, 2 + stream_num);

  /* get the position of the file properties object for 
   * updating it in gst_asf_mux_stop_file */
  asfmux->file_properties_object_position = bufdata - map.data;
  gst_asf_mux_write_file_properties (asfmux, &bufdata);

  for (walk = asfmux->collect->data; walk; walk = g_slist_next (walk)) {
    gst_asf_mux_write_stream_properties (asfmux, &bufdata,
        (GstAsfPad *) walk->data);
  }

  if (asftags->cont_desc_size) {
    gst_asf_mux_write_content_description (asfmux, &bufdata, asftags->tags);
  }
  if (asftags->ext_cont_desc_size) {
    gst_asf_mux_write_ext_content_description (asfmux, &bufdata, asftags->tags);
  }

  if (asftags->tags)
    gst_tag_list_unref (asftags->tags);
  g_free (asftags);

  /* writing header extension objects */
  gst_asf_mux_write_header_extension (asfmux, &bufdata, stream_num *
      ASF_EXTENDED_STREAM_PROPERTIES_OBJECT_SIZE + metadata_obj_size);
  for (walk = asfmux->collect->data; walk; walk = g_slist_next (walk)) {
    gst_asf_mux_write_extended_stream_properties (asfmux, &bufdata,
        (GstAsfPad *) walk->data);
  }
  for (walk = asfmux->collect->data; walk; walk = g_slist_next (walk)) {
    gst_asf_mux_write_metadata_object (asfmux, &bufdata,
        (GstAsfPad *) walk->data);
  }

  gst_asf_mux_write_padding_object (asfmux, &bufdata, padding);

  /* store data object position for later updating some fields */
  asfmux->data_object_position = bufdata - map.data;
  gst_asf_mux_write_data_object (asfmux, &bufdata);

  /* set streamheader in source pad if 'streamable' */
  if (asfmux->prop_streamable) {
    g_value_init (&streamheader, GST_TYPE_ARRAY);
    gst_asf_mux_put_buffer_in_streamheader (&streamheader, buf);

    caps = gst_pad_get_current_caps (asfmux->srcpad);
    caps = gst_caps_make_writable (caps);
    structure = gst_caps_get_structure (caps, 0);
    gst_structure_set_value (structure, "streamheader", &streamheader);
    gst_pad_set_caps (asfmux->srcpad, caps);
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
    g_value_unset (&streamheader);
    gst_caps_unref (caps);
  }

  g_assert (bufdata - map.data == map.size);
  gst_buffer_unmap (buf, &map);
  return gst_asf_mux_push_buffer (asfmux, buf, bufsize);
}

/**
 * gst_asf_mux_add_simple_index_entry:
 * @asfmux:
 * @videopad:
 *
 * Adds a new entry to the simple index of the stream handler by videopad.
 * This functions doesn't check if the time ellapsed
 * is larger than the established time interval between entries. The caller
 * is responsible for verifying this.
 */
static void
gst_asf_mux_add_simple_index_entry (GstAsfMux * asfmux,
    GstAsfVideoPad * videopad)
{
  SimpleIndexEntry *entry = NULL;
  GST_DEBUG_OBJECT (asfmux, "Adding new simple index entry "
      "packet number: %" G_GUINT32_FORMAT ", "
      "packet count: %" G_GUINT16_FORMAT,
      videopad->last_keyframe_packet, videopad->last_keyframe_packet_count);
  entry = g_malloc0 (sizeof (SimpleIndexEntry));
  entry->packet_number = videopad->last_keyframe_packet;
  entry->packet_count = videopad->last_keyframe_packet_count;
  if (entry->packet_count > videopad->max_keyframe_packet_count)
    videopad->max_keyframe_packet_count = entry->packet_count;
  videopad->simple_index = g_slist_append (videopad->simple_index, entry);
}

/**
 * gst_asf_mux_send_packet:
 * @asfmux:
 * @buf: The asf data packet
 *
 * Pushes an asf data packet downstream. The total number
 * of packets and bytes of the stream are incremented.
 *
 * Returns: the result of pushing the buffer downstream
 */
static GstFlowReturn
gst_asf_mux_send_packet (GstAsfMux * asfmux, GstBuffer * buf, gsize bufsize)
{
  g_assert (bufsize == asfmux->packet_size);
  asfmux->total_data_packets++;
  GST_LOG_OBJECT (asfmux,
      "Pushing a packet of size %" G_GSIZE_FORMAT " and timestamp %"
      G_GUINT64_FORMAT, bufsize, GST_BUFFER_TIMESTAMP (buf));
  GST_LOG_OBJECT (asfmux, "Total data packets: %" G_GUINT64_FORMAT,
      asfmux->total_data_packets);
  return gst_asf_mux_push_buffer (asfmux, buf, bufsize);
}

/**
 * gst_asf_mux_flush_payloads:
 * @asfmux: #GstAsfMux to flush the payloads from
 *
 * Fills an asf packet with asfmux queued payloads and
 * pushes it downstream.
 *
 * Returns: The result of pushing the packet
 */
static GstFlowReturn
gst_asf_mux_flush_payloads (GstAsfMux * asfmux)
{
  GstBuffer *buf;
  guint8 payloads_count = 0;    /* we only use 6 bits, max is 63 */
  guint i;
  GstClockTime send_ts = GST_CLOCK_TIME_NONE;
  guint64 size_left;
  guint8 *data;
  gsize size;
  GSList *walk;
  GstAsfPad *pad;
  gboolean has_keyframe;
  AsfPayload *payload;
  guint32 payload_size;
  guint offset;
  GstMapInfo map;

  if (asfmux->payloads == NULL)
    return GST_FLOW_OK;         /* nothing to send is ok */

  GST_LOG_OBJECT (asfmux, "Flushing payloads");

  buf = gst_buffer_new_and_alloc (asfmux->packet_size);
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  memset (map.data, 0, asfmux->packet_size);

  /* 1 for the multiple payload flags */
  data = map.data + asfmux->payload_parsing_info_size + 1;
  size_left = asfmux->packet_size - asfmux->payload_parsing_info_size - 1;

  has_keyframe = FALSE;
  walk = asfmux->payloads;
  while (walk && payloads_count < MAX_PAYLOADS_IN_A_PACKET) {
    payload = (AsfPayload *) walk->data;
    pad = (GstAsfPad *) payload->pad;
    payload_size = gst_asf_payload_get_size (payload);
    if (size_left < payload_size) {
      break;                    /* next payload doesn't fit fully */
    }

    if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (send_ts))) {
      send_ts = GST_BUFFER_TIMESTAMP (payload->data);
    }

    /* adding new simple index entry (if needed) */
    if (!pad->is_audio
        && GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (payload->data))) {
      GstAsfVideoPad *videopad = (GstAsfVideoPad *) pad;
      if (videopad->has_keyframe) {
        for (; videopad->next_index_time <=
            ASF_MILI_TO_100NANO (payload->presentation_time);
            videopad->next_index_time += videopad->time_interval) {
          gst_asf_mux_add_simple_index_entry (asfmux, videopad);
        }
      }
    }

    /* serialize our payload */
    GST_DEBUG_OBJECT (asfmux, "Serializing payload into packet");
    GST_DEBUG_OBJECT (asfmux, "stream number: %d", pad->stream_number & 0x7F);
    GST_DEBUG_OBJECT (asfmux, "media object number: %d",
        (gint) payload->media_obj_num);
    GST_DEBUG_OBJECT (asfmux, "offset into media object: %" G_GUINT32_FORMAT,
        payload->offset_in_media_obj);
    GST_DEBUG_OBJECT (asfmux, "media object size: %" G_GUINT32_FORMAT,
        payload->media_object_size);
    GST_DEBUG_OBJECT (asfmux, "replicated data length: %d",
        (gint) payload->replicated_data_length);
    GST_DEBUG_OBJECT (asfmux, "payload size: %" G_GSIZE_FORMAT,
        gst_buffer_get_size (payload->data));
    GST_DEBUG_OBJECT (asfmux, "presentation time: %" G_GUINT32_FORMAT " (%"
        GST_TIME_FORMAT ")", payload->presentation_time,
        GST_TIME_ARGS (payload->presentation_time * GST_MSECOND));
    GST_DEBUG_OBJECT (asfmux, "keyframe: %s",
        (payload->stream_number & 0x80 ? "yes" : "no"));
    GST_DEBUG_OBJECT (asfmux, "buffer timestamp: %" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (payload->data)));
    GST_DEBUG_OBJECT (asfmux, "buffer duration %" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_BUFFER_DURATION (payload->data)));

    gst_asf_put_payload (data, payload);
    if (!payload->has_packet_info) {
      payload->has_packet_info = TRUE;
      payload->packet_number = asfmux->total_data_packets;
    }
    GST_DEBUG_OBJECT (asfmux, "packet number: %" G_GUINT32_FORMAT,
        payload->packet_number);

    if (ASF_PAYLOAD_IS_KEYFRAME (payload)) {
      has_keyframe = TRUE;
      if (!pad->is_audio) {
        GstAsfVideoPad *videopad = (GstAsfVideoPad *) pad;
        videopad->last_keyframe_packet = payload->packet_number;
        videopad->last_keyframe_packet_count = payload->packet_count;
        videopad->has_keyframe = TRUE;
      }
    }

    /* update our variables */
    data += payload_size;
    size_left -= payload_size;
    payloads_count++;
    walk = g_slist_next (walk);
  }

  /* remove flushed payloads */
  GST_LOG_OBJECT (asfmux, "Freeing already used payloads");
  for (i = 0; i < payloads_count; i++) {
    GSList *aux = g_slist_nth (asfmux->payloads, 0);
    AsfPayload *payload;
    g_assert (aux);
    payload = (AsfPayload *) aux->data;
    asfmux->payloads = g_slist_remove (asfmux->payloads, payload);
    asfmux->payload_data_size -=
        (gst_buffer_get_size (payload->data) +
        ASF_MULTIPLE_PAYLOAD_HEADER_SIZE);
    gst_asf_payload_free (payload);
  }

  /* check if we can add part of the next payload */
  if (asfmux->payloads && size_left > ASF_MULTIPLE_PAYLOAD_HEADER_SIZE) {
    AsfPayload *payload =
        (AsfPayload *) g_slist_nth (asfmux->payloads, 0)->data;
    guint16 bytes_writen;
    GST_DEBUG_OBJECT (asfmux, "Adding part of a payload to a packet");

    if (ASF_PAYLOAD_IS_KEYFRAME (payload))
      has_keyframe = TRUE;

    if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (send_ts))) {
      send_ts = GST_BUFFER_TIMESTAMP (payload->data);
    }

    bytes_writen = gst_asf_put_subpayload (data, payload, size_left);
    if (!payload->has_packet_info) {
      payload->has_packet_info = TRUE;
      payload->packet_number = asfmux->total_data_packets;
    }
    asfmux->payload_data_size -= bytes_writen;
    size_left -= (bytes_writen + ASF_MULTIPLE_PAYLOAD_HEADER_SIZE);
    payloads_count++;
  }

  GST_LOG_OBJECT (asfmux, "Payload data size: %" G_GUINT32_FORMAT,
      asfmux->payload_data_size);

  /* fill payload parsing info */
  data = map.data;
  size = map.size;

  /* flags */
  GST_WRITE_UINT8 (data, (0x0 << 7) |   /* no error correction */
      (ASF_FIELD_TYPE_DWORD << 5) |     /* packet length type */
      (ASF_FIELD_TYPE_DWORD << 3) |     /* padding length type */
      (ASF_FIELD_TYPE_NONE << 1) |      /* sequence type type */
      0x1);                     /* multiple payloads */
  offset = 1;

  /* property flags - according to the spec, this should not change */
  GST_WRITE_UINT8 (data + offset, (ASF_FIELD_TYPE_BYTE << 6) |  /* stream number length type */
      (ASF_FIELD_TYPE_BYTE << 4) |      /* media obj number length type */
      (ASF_FIELD_TYPE_DWORD << 2) |     /* offset info media object length type */
      (ASF_FIELD_TYPE_BYTE));   /* replicated data length type */
  offset++;

  /* Due to a limitation in WMP while streaming through WMSP we reduce the
   * packet & padding size to 16bit if they are <= 65535 bytes
   */
  if (asfmux->packet_size > 65535) {
    GST_WRITE_UINT32_LE (data + offset, asfmux->packet_size - size_left);
    offset += 4;
  } else {
    *data &= ~(ASF_FIELD_TYPE_MASK << 5);
    *data |= ASF_FIELD_TYPE_WORD << 5;
    GST_WRITE_UINT16_LE (data + offset, asfmux->packet_size - size_left);
    offset += 2;
  }
  if (asfmux->prop_padding > 65535) {
    GST_WRITE_UINT32_LE (data + offset, size_left);
    offset += 4;
  } else {
    *data &= ~(ASF_FIELD_TYPE_MASK << 3);
    *data |= ASF_FIELD_TYPE_WORD << 3;
    GST_WRITE_UINT16_LE (data + offset, size_left);
    offset += 2;
  }

  /* packet send time */
  if (GST_CLOCK_TIME_IS_VALID (send_ts)) {
    GST_WRITE_UINT32_LE (data + offset, (send_ts / GST_MSECOND));
    GST_BUFFER_TIMESTAMP (buf) = send_ts;
  }
  offset += 4;

  /* packet duration */
  GST_WRITE_UINT16_LE (data + offset, 0);       /* FIXME send duration needs to be estimated */
  offset += 2;

  /* multiple payloads flags */
  GST_WRITE_UINT8 (data + offset, 0x2 << 6 | payloads_count);
  gst_buffer_unmap (buf, &map);

  if (payloads_count == 0) {
    GST_WARNING_OBJECT (asfmux, "Sending packet without any payload");
  }
  asfmux->data_object_size += size;

  if (!has_keyframe)
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);

  return gst_asf_mux_send_packet (asfmux, buf, size);
}

/**
 * stream_number_compare:
 * @a: a #GstAsfPad
 * @b: another #GstAsfPad
 *
 * Utility function to compare #GstAsfPad by their stream numbers
 *
 * Returns: The difference between their stream numbers
 */
static gint
stream_number_compare (gconstpointer a, gconstpointer b)
{
  GstAsfPad *pad_a = (GstAsfPad *) a;
  GstAsfPad *pad_b = (GstAsfPad *) b;
  return pad_b->stream_number - pad_a->stream_number;
}

static GstFlowReturn
gst_asf_mux_push_simple_index (GstAsfMux * asfmux, GstAsfVideoPad * pad)
{
  guint64 object_size = ASF_SIMPLE_INDEX_OBJECT_SIZE +
      g_slist_length (pad->simple_index) * ASF_SIMPLE_INDEX_ENTRY_SIZE;
  GstBuffer *buf;
  GSList *walk;
  guint8 *data;
  guint32 entries_count = g_slist_length (pad->simple_index);
  GstMapInfo map;
  gsize bufsize;

  buf = gst_buffer_new_and_alloc (object_size);
  bufsize = object_size;

  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  data = map.data;

  gst_asf_put_guid (data, guids[ASF_SIMPLE_INDEX_OBJECT_INDEX]);
  GST_WRITE_UINT64_LE (data + 16, object_size);
  gst_asf_put_guid (data + 24, asfmux->file_id);
  GST_WRITE_UINT64_LE (data + 40, pad->time_interval);
  GST_WRITE_UINT32_LE (data + 48, pad->max_keyframe_packet_count);
  GST_WRITE_UINT32_LE (data + 52, entries_count);
  data += ASF_SIMPLE_INDEX_OBJECT_SIZE;

  GST_DEBUG_OBJECT (asfmux,
      "Simple index object values - size:%" G_GUINT64_FORMAT ", time interval:%"
      G_GUINT64_FORMAT ", max packet count:%" G_GUINT32_FORMAT ", entries:%"
      G_GUINT32_FORMAT, object_size, pad->time_interval,
      pad->max_keyframe_packet_count, entries_count);

  for (walk = pad->simple_index; walk; walk = g_slist_next (walk)) {
    SimpleIndexEntry *entry = (SimpleIndexEntry *) walk->data;
    GST_DEBUG_OBJECT (asfmux, "Simple index entry: packet_number:%"
        G_GUINT32_FORMAT " packet_count:%" G_GUINT16_FORMAT,
        entry->packet_number, entry->packet_count);
    GST_WRITE_UINT32_LE (data, entry->packet_number);
    GST_WRITE_UINT16_LE (data + 4, entry->packet_count);
    data += ASF_SIMPLE_INDEX_ENTRY_SIZE;
  }

  GST_DEBUG_OBJECT (asfmux, "Pushing the simple index");
  g_assert (data - map.data == object_size);
  gst_buffer_unmap (buf, &map);
  return gst_asf_mux_push_buffer (asfmux, buf, bufsize);
}

static GstFlowReturn
gst_asf_mux_write_indexes (GstAsfMux * asfmux)
{
  GSList *ordered_pads;
  GSList *walker;
  GstFlowReturn ret = GST_FLOW_OK;

  /* write simple indexes for video medias */
  ordered_pads =
      g_slist_sort (g_slist_copy (asfmux->collect->data),
      (GCompareFunc) stream_number_compare);
  for (walker = ordered_pads; walker; walker = g_slist_next (walker)) {
    GstAsfPad *pad = (GstAsfPad *) walker->data;
    if (!pad->is_audio) {
      ret = gst_asf_mux_push_simple_index (asfmux, (GstAsfVideoPad *) pad);
      if (ret != GST_FLOW_OK) {
        GST_ERROR_OBJECT (asfmux, "Failed to write simple index for stream %"
            G_GUINT16_FORMAT, (guint16) pad->stream_number);
        goto cleanup_and_return;
      }
    }
  }
cleanup_and_return:
  g_slist_free (ordered_pads);
  return ret;
}

/**
 * gst_asf_mux_stop_file:
 * @asfmux: #GstAsfMux
 * 
 * Finalizes the asf stream by pushing the indexes after
 * the data object. Also seeks back to the header positions
 * to rewrite some fields such as the total number of bytes
 * of the file, or any other that couldn't be predicted/known
 * back on the header generation.
 *
 * Returns: GST_FLOW_OK on success
 */
static GstFlowReturn
gst_asf_mux_stop_file (GstAsfMux * asfmux)
{
  GstEvent *event;
  GstBuffer *buf;
  GstFlowReturn ret = GST_FLOW_OK;
  GSList *walk;
  GstClockTime play_duration = 0;
  guint32 bitrate = 0;
  GstSegment segment;
  GstMapInfo map;
  guint8 *data;

  /* write indexes */
  ret = gst_asf_mux_write_indexes (asfmux);
  if (ret != GST_FLOW_OK) {
    GST_ERROR_OBJECT (asfmux, "Failed to write indexes");
    return ret;
  }

  /* find max stream duration and bitrate */
  for (walk = asfmux->collect->data; walk; walk = g_slist_next (walk)) {
    GstAsfPad *pad = (GstAsfPad *) walk->data;
    bitrate += pad->bitrate;
    if (pad->play_duration > play_duration)
      play_duration = pad->play_duration;
  }

  /* going back to file properties object to fill in 
   * values we didn't know back then */
  GST_DEBUG_OBJECT (asfmux,
      "Sending new segment to file properties object position");
  gst_segment_init (&segment, GST_FORMAT_BYTES);
  segment.start = segment.position =
      asfmux->file_properties_object_position + 40;
  event = gst_event_new_segment (&segment);
  if (!gst_pad_push_event (asfmux->srcpad, event)) {
    GST_ERROR_OBJECT (asfmux, "Failed to update file properties object");
    return GST_FLOW_ERROR;
  }
  /* All file properties fields except the first 40 bytes */
  buf = gst_buffer_new_and_alloc (ASF_FILE_PROPERTIES_OBJECT_SIZE - 40);
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  data = map.data;

  GST_WRITE_UINT64_LE (data, asfmux->file_size);
  gst_asf_put_time (data + 8, gst_asf_get_current_time ());
  GST_WRITE_UINT64_LE (data + 16, asfmux->total_data_packets);
  GST_WRITE_UINT64_LE (data + 24, (play_duration / 100) +
      ASF_MILI_TO_100NANO (asfmux->preroll));
  GST_WRITE_UINT64_LE (data + 32, (play_duration / 100));       /* TODO send duration */

  /* if play duration is smaller then preroll, player might have problems */
  if (asfmux->preroll > play_duration / GST_MSECOND) {
    GST_ELEMENT_WARNING (asfmux, STREAM, MUX, (_("Generated file has a larger"
                " preroll time than its streams duration")),
        ("Preroll time larger than streams duration, "
            "try setting a smaller preroll value next time"));
  }
  GST_WRITE_UINT64_LE (data + 40, asfmux->preroll);
  GST_WRITE_UINT32_LE (data + 48, 0x2); /* flags - seekable */
  GST_WRITE_UINT32_LE (data + 52, asfmux->packet_size);
  GST_WRITE_UINT32_LE (data + 56, asfmux->packet_size);
  /* FIXME - we want the max instantaneous bitrate, for vbr streams, we can't
   * get it this way, this would be the average, right? */
  GST_WRITE_UINT32_LE (data + 60, bitrate);     /* max bitrate */
  gst_buffer_unmap (buf, &map);

  /* we don't use gst_asf_mux_push_buffer because we are overwriting
   * already sent data */
  ret = gst_pad_push (asfmux->srcpad, buf);
  if (ret != GST_FLOW_OK) {
    GST_ERROR_OBJECT (asfmux, "Failed to update file properties object");
    return ret;
  }

  GST_DEBUG_OBJECT (asfmux, "Seeking back to data object");

  /* seek back to the data object */
  segment.start = segment.position = asfmux->data_object_position + 16;
  event = gst_event_new_segment (&segment);
  if (!gst_pad_push_event (asfmux->srcpad, event)) {
    GST_ERROR_OBJECT (asfmux, "Seek to update data object failed");
    return GST_FLOW_ERROR;
  }

  buf = gst_buffer_new_and_alloc (32);  /* qword+guid+qword */
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  data = map.data;
  GST_WRITE_UINT64_LE (data, asfmux->data_object_size + ASF_DATA_OBJECT_SIZE);
  gst_asf_put_guid (data + 8, asfmux->file_id);
  GST_WRITE_UINT64_LE (data + 24, asfmux->total_data_packets);
  gst_buffer_unmap (buf, &map);

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

/**
 * gst_asf_mux_process_buffer:
 * @asfmux:
 * @pad: stream of the buffer
 * @buf: The buffer to be processed
 *
 * Processes the buffer by parsing it and
 * queueing it up as an asf payload for later
 * being added and pushed inside an asf packet.
 *
 * Returns: a #GstFlowReturn
 */
static GstFlowReturn
gst_asf_mux_process_buffer (GstAsfMux * asfmux, GstAsfPad * pad,
    GstBuffer * buf)
{
  guint8 keyframe;
  AsfPayload *payload;

  payload = g_malloc0 (sizeof (AsfPayload));
  payload->pad = (GstCollectData *) pad;
  payload->data = buf;

  GST_LOG_OBJECT (asfmux, "Processing payload data for stream number %u",
      pad->stream_number);

  /* stream number */
  if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
    keyframe = 0;
  } else {
    keyframe = 0x1 << 7;
  }
  payload->stream_number = keyframe | pad->stream_number;

  payload->media_obj_num = pad->media_object_number;
  payload->offset_in_media_obj = 0;
  payload->replicated_data_length = 8;

  /* replicated data - 1) media object size */
  payload->media_object_size = gst_buffer_get_size (buf);
  /* replicated data - 2) presentation time */
  if (!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf))) {
    GST_ERROR_OBJECT (asfmux, "Received buffer without timestamp");
    gst_asf_payload_free (payload);
    return GST_FLOW_ERROR;
  }

  g_assert (GST_CLOCK_TIME_IS_VALID (asfmux->first_ts));
  g_assert (GST_CLOCK_TIME_IS_VALID (pad->first_ts));

  payload->presentation_time = asfmux->preroll +
      ((GST_BUFFER_TIMESTAMP (buf) - asfmux->first_ts) / GST_MSECOND);

  /* update counting values */
  pad->media_object_number = (pad->media_object_number + 1) % 256;
  if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE) {
    pad->play_duration += GST_BUFFER_DURATION (buf);
  } else {
    GST_WARNING_OBJECT (asfmux, "Received buffer without duration, it will not "
        "be accounted in the total file time");
  }

  asfmux->payloads = g_slist_append (asfmux->payloads, payload);
  asfmux->payload_data_size +=
      gst_buffer_get_size (buf) + ASF_MULTIPLE_PAYLOAD_HEADER_SIZE;
  GST_LOG_OBJECT (asfmux, "Payload data size: %" G_GUINT32_FORMAT,
      asfmux->payload_data_size);

  while (asfmux->payload_data_size + asfmux->payload_parsing_info_size >=
      asfmux->packet_size) {
    GstFlowReturn ret = gst_asf_mux_flush_payloads (asfmux);
    if (ret != GST_FLOW_OK)
      return ret;
  }

  return GST_FLOW_OK;
}

static GstFlowReturn
gst_asf_mux_collected (GstCollectPads * collect, gpointer data)
{
  GstAsfMux *asfmux = GST_ASF_MUX_CAST (data);
  GstFlowReturn ret = GST_FLOW_OK;
  GstAsfPad *best_pad = NULL;
  GstClockTime best_time = GST_CLOCK_TIME_NONE;
  GstBuffer *buf = NULL;
  GSList *walk;

  if (G_UNLIKELY (asfmux->state == GST_ASF_MUX_STATE_NONE)) {
    ret = gst_asf_mux_start_file (asfmux);
    if (ret != GST_FLOW_OK) {
      GST_WARNING_OBJECT (asfmux, "Failed to send headers");
      return ret;
    } else {
      asfmux->state = GST_ASF_MUX_STATE_DATA;
    }
  }

  if (G_UNLIKELY (asfmux->state == GST_ASF_MUX_STATE_EOS))
    return GST_FLOW_EOS;

  /* select the earliest buffer */
  walk = asfmux->collect->data;
  while (walk) {
    GstAsfPad *pad;
    GstCollectData *data;
    GstClockTime time;

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

    walk = g_slist_next (walk);

    buf = gst_collect_pads_peek (collect, data);
    if (buf == NULL) {
      GST_LOG_OBJECT (asfmux, "Pad %s has no buffers",
          GST_PAD_NAME (pad->collect.pad));
      continue;
    }
    time = GST_BUFFER_TIMESTAMP (buf);

    /* check the ts for getting the first time */
    if (!GST_CLOCK_TIME_IS_VALID (pad->first_ts) &&
        GST_CLOCK_TIME_IS_VALID (time)) {
      GST_DEBUG_OBJECT (asfmux,
          "First ts for stream number %u: %" GST_TIME_FORMAT,
          pad->stream_number, GST_TIME_ARGS (time));
      pad->first_ts = time;
      if (!GST_CLOCK_TIME_IS_VALID (asfmux->first_ts) ||
          time < asfmux->first_ts) {
        GST_DEBUG_OBJECT (asfmux, "New first ts for file %" GST_TIME_FORMAT,
            GST_TIME_ARGS (time));
        asfmux->first_ts = time;
      }
    }

    gst_buffer_unref (buf);

    if (best_pad == NULL || !GST_CLOCK_TIME_IS_VALID (time) ||
        (GST_CLOCK_TIME_IS_VALID (best_time) && time < best_time)) {
      best_pad = pad;
      best_time = time;
    }
  }

  if (best_pad != NULL) {
    /* we have data */
    GST_LOG_OBJECT (asfmux, "selected pad %s with time %" GST_TIME_FORMAT,
        GST_PAD_NAME (best_pad->collect.pad), GST_TIME_ARGS (best_time));
    buf = gst_collect_pads_pop (collect, &best_pad->collect);
    ret = gst_asf_mux_process_buffer (asfmux, best_pad, buf);
  } else {
    /* no data, let's finish it up */
    while (asfmux->payloads) {
      ret = gst_asf_mux_flush_payloads (asfmux);
      if (ret != GST_FLOW_OK) {
        return ret;
      }
    }
    g_assert (asfmux->payloads == NULL);
    g_assert (asfmux->payload_data_size == 0);
    /* in not on 'streamable' mode we need to push indexes
     * and update headers */
    if (!asfmux->prop_streamable) {
      ret = gst_asf_mux_stop_file (asfmux);
    }
    if (ret == GST_FLOW_OK) {
      gst_pad_push_event (asfmux->srcpad, gst_event_new_eos ());
      ret = GST_FLOW_EOS;
    }
    asfmux->state = GST_ASF_MUX_STATE_EOS;
  }

  return ret;
}

static void
gst_asf_mux_pad_reset (GstAsfPad * pad)
{
  pad->stream_number = 0;
  pad->media_object_number = 0;
  pad->play_duration = (GstClockTime) 0;
  pad->bitrate = 0;
  if (pad->codec_data)
    gst_buffer_unref (pad->codec_data);
  pad->codec_data = NULL;
  if (pad->taglist)
    gst_tag_list_unref (pad->taglist);
  pad->taglist = NULL;

  pad->first_ts = GST_CLOCK_TIME_NONE;

  if (pad->is_audio) {
    GstAsfAudioPad *audiopad = (GstAsfAudioPad *) pad;
    audiopad->audioinfo.rate = 0;
    audiopad->audioinfo.channels = 0;
    audiopad->audioinfo.format = 0;
    audiopad->audioinfo.av_bps = 0;
    audiopad->audioinfo.blockalign = 0;
    audiopad->audioinfo.bits_per_sample = 0;
  } else {
    GstAsfVideoPad *videopad = (GstAsfVideoPad *) pad;
    videopad->vidinfo.size = 0;
    videopad->vidinfo.width = 0;
    videopad->vidinfo.height = 0;
    videopad->vidinfo.planes = 1;
    videopad->vidinfo.bit_cnt = 0;
    videopad->vidinfo.compression = 0;
    videopad->vidinfo.image_size = 0;
    videopad->vidinfo.xpels_meter = 0;
    videopad->vidinfo.ypels_meter = 0;
    videopad->vidinfo.num_colors = 0;
    videopad->vidinfo.imp_colors = 0;

    videopad->last_keyframe_packet = 0;
    videopad->has_keyframe = FALSE;
    videopad->last_keyframe_packet_count = 0;
    videopad->max_keyframe_packet_count = 0;
    videopad->next_index_time = 0;
    videopad->time_interval = DEFAULT_SIMPLE_INDEX_TIME_INTERVAL;
    if (videopad->simple_index) {
      GSList *walk;
      for (walk = videopad->simple_index; walk; walk = g_slist_next (walk)) {
        g_free (walk->data);
        walk->data = NULL;
      }
      g_slist_free (videopad->simple_index);
    }
    videopad->simple_index = NULL;
  }
}

static gboolean
gst_asf_mux_audio_set_caps (GstPad * pad, GstCaps * caps)
{
  GstAsfMux *asfmux;
  GstAsfAudioPad *audiopad;
  GstStructure *structure;
  const gchar *caps_name;
  gint channels, rate;
  gchar *aux;
  const GValue *codec_data;

  asfmux = GST_ASF_MUX (gst_pad_get_parent (pad));

  audiopad = (GstAsfAudioPad *) gst_pad_get_element_private (pad);
  g_assert (audiopad);

  aux = gst_caps_to_string (caps);
  GST_DEBUG_OBJECT (asfmux, "%s:%s, caps=%s", GST_DEBUG_PAD_NAME (pad), aux);
  g_free (aux);

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

  if (!gst_structure_get_int (structure, "channels", &channels) ||
      !gst_structure_get_int (structure, "rate", &rate))
    goto refuse_caps;

  audiopad->audioinfo.channels = (guint16) channels;
  audiopad->audioinfo.rate = (guint32) rate;

  /* taken from avimux
   * codec initialization data, if any 
   */
  codec_data = gst_structure_get_value (structure, "codec_data");
  if (codec_data) {
    audiopad->pad.codec_data = gst_value_get_buffer (codec_data);
    gst_buffer_ref (audiopad->pad.codec_data);
  }

  if (strcmp (caps_name, "audio/x-wma") == 0) {
    gint version;
    gint block_align = 0;
    gint bitrate = 0;

    if (!gst_structure_get_int (structure, "wmaversion", &version)) {
      goto refuse_caps;
    }

    if (gst_structure_get_int (structure, "block_align", &block_align)) {
      audiopad->audioinfo.blockalign = (guint16) block_align;
    }
    if (gst_structure_get_int (structure, "bitrate", &bitrate)) {
      audiopad->pad.bitrate = (guint32) bitrate;
      audiopad->audioinfo.av_bps = bitrate / 8;
    }

    if (version == 1) {
      audiopad->audioinfo.format = GST_RIFF_WAVE_FORMAT_WMAV1;
    } else if (version == 2) {
      audiopad->audioinfo.format = GST_RIFF_WAVE_FORMAT_WMAV2;
    } else if (version == 3) {
      audiopad->audioinfo.format = GST_RIFF_WAVE_FORMAT_WMAV3;
    } else {
      goto refuse_caps;
    }
  } else if (strcmp (caps_name, "audio/mpeg") == 0) {
    gint version;
    gint layer;

    if (!gst_structure_get_int (structure, "mpegversion", &version) ||
        !gst_structure_get_int (structure, "layer", &layer)) {
      goto refuse_caps;
    }
    if (version != 1 || layer != 3) {
      goto refuse_caps;
    }

    audiopad->audioinfo.format = GST_RIFF_WAVE_FORMAT_MPEGL3;
  } else {
    goto refuse_caps;
  }

  gst_object_unref (asfmux);
  return TRUE;

refuse_caps:
  GST_WARNING_OBJECT (asfmux, "pad %s refused caps %" GST_PTR_FORMAT,
      GST_PAD_NAME (pad), caps);
  gst_object_unref (asfmux);
  return FALSE;
}

/* TODO Read pixel aspect ratio */
static gboolean
gst_asf_mux_video_set_caps (GstPad * pad, GstCaps * caps)
{
  GstAsfMux *asfmux;
  GstAsfVideoPad *videopad;
  GstStructure *structure;
  const gchar *caps_name;
  gint width, height;
  gchar *aux;
  const GValue *codec_data;

  asfmux = GST_ASF_MUX (gst_pad_get_parent (pad));

  videopad = (GstAsfVideoPad *) gst_pad_get_element_private (pad);
  g_assert (videopad);

  aux = gst_caps_to_string (caps);
  GST_DEBUG_OBJECT (asfmux, "%s:%s, caps=%s", GST_DEBUG_PAD_NAME (pad), aux);
  g_free (aux);

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

  if (!gst_structure_get_int (structure, "width", &width) ||
      !gst_structure_get_int (structure, "height", &height))
    goto refuse_caps;

  videopad->vidinfo.width = (gint32) width;
  videopad->vidinfo.height = (gint32) height;

  /* taken from avimux
   * codec initialization data, if any 
   */
  codec_data = gst_structure_get_value (structure, "codec_data");
  if (codec_data) {
    videopad->pad.codec_data = gst_value_get_buffer (codec_data);
    gst_buffer_ref (videopad->pad.codec_data);
  }

  if (strcmp (caps_name, "video/x-wmv") == 0) {
    gint wmvversion;
    const gchar *fstr;

    videopad->vidinfo.bit_cnt = 24;

    /* in case we have a format, we use it */
    fstr = gst_structure_get_string (structure, "format");
    if (fstr && strlen (fstr) == 4) {
      videopad->vidinfo.compression = GST_STR_FOURCC (fstr);
    } else if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
      if (wmvversion == 2) {
        videopad->vidinfo.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '2');
      } else if (wmvversion == 1) {
        videopad->vidinfo.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '1');
      } else if (wmvversion == 3) {
        videopad->vidinfo.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '3');
      }
    } else
      goto refuse_caps;
  } else {
    goto refuse_caps;
  }

  gst_object_unref (asfmux);
  return TRUE;

refuse_caps:
  GST_WARNING_OBJECT (asfmux, "pad %s refused caps %" GST_PTR_FORMAT,
      GST_PAD_NAME (pad), caps);
  gst_object_unref (asfmux);
  return FALSE;
}

static GstPad *
gst_asf_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  GstAsfMux *asfmux = GST_ASF_MUX_CAST (element);
  GstPad *newpad;
  GstAsfPad *collect_pad;
  gboolean is_audio;
  guint collect_size = 0;
  gchar *name = NULL;
  const gchar *pad_name = NULL;
  gint pad_id;

  GST_DEBUG_OBJECT (asfmux, "Requested pad: %s", GST_STR_NULL (req_name));

  if (asfmux->state != GST_ASF_MUX_STATE_NONE) {
    GST_WARNING_OBJECT (asfmux, "Not providing request pad after element is at "
        "paused/playing state.");
    return 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", asfmux->stream_number + 1);
      pad_name = name;
    }
    GST_DEBUG_OBJECT (asfmux, "Adding new pad %s", name);
    newpad = gst_pad_new_from_template (templ, pad_name);
    is_audio = TRUE;
  } 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", asfmux->stream_number + 1);
      pad_name = name;
    }
    GST_DEBUG_OBJECT (asfmux, "Adding new pad %s", name);
    newpad = gst_pad_new_from_template (templ, name);
    is_audio = FALSE;
  } else {
    GST_WARNING_OBJECT (asfmux, "This is not our template!");
    return NULL;
  }

  g_free (name);

  /* add pad to collections */
  if (is_audio) {
    collect_size = sizeof (GstAsfAudioPad);
  } else {
    collect_size = sizeof (GstAsfVideoPad);
  }
  collect_pad = (GstAsfPad *)
      gst_collect_pads_add_pad (asfmux->collect, newpad, collect_size,
      (GstCollectDataDestroyNotify) (gst_asf_mux_pad_reset), TRUE);

  /* set up pad */
  collect_pad->is_audio = is_audio;
  if (!is_audio)
    ((GstAsfVideoPad *) collect_pad)->simple_index = NULL;
  collect_pad->taglist = NULL;
  gst_asf_mux_pad_reset (collect_pad);

  /* set pad stream number */
  asfmux->stream_number += 1;
  collect_pad->stream_number = asfmux->stream_number;

  gst_pad_set_active (newpad, TRUE);
  gst_element_add_pad (element, newpad);

  return newpad;
}

static void
gst_asf_mux_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstAsfMux *asfmux;

  asfmux = GST_ASF_MUX (object);
  switch (prop_id) {
    case PROP_PACKET_SIZE:
      g_value_set_uint (value, asfmux->prop_packet_size);
      break;
    case PROP_PREROLL:
      g_value_set_uint64 (value, asfmux->prop_preroll);
      break;
    case PROP_MERGE_STREAM_TAGS:
      g_value_set_boolean (value, asfmux->prop_merge_stream_tags);
      break;
    case PROP_PADDING:
      g_value_set_uint64 (value, asfmux->prop_padding);
      break;
    case PROP_STREAMABLE:
      g_value_set_boolean (value, asfmux->prop_streamable);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_asf_mux_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstAsfMux *asfmux;

  asfmux = GST_ASF_MUX (object);
  switch (prop_id) {
    case PROP_PACKET_SIZE:
      asfmux->prop_packet_size = g_value_get_uint (value);
      break;
    case PROP_PREROLL:
      asfmux->prop_preroll = g_value_get_uint64 (value);
      break;
    case PROP_MERGE_STREAM_TAGS:
      asfmux->prop_merge_stream_tags = g_value_get_boolean (value);
      break;
    case PROP_PADDING:
      asfmux->prop_padding = g_value_get_uint64 (value);
      break;
    case PROP_STREAMABLE:
      asfmux->prop_streamable = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_asf_mux_change_state (GstElement * element, GstStateChange transition)
{
  GstAsfMux *asfmux;
  GstStateChangeReturn ret;

  asfmux = GST_ASF_MUX (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* TODO - check if it is possible to mux 2 files without going
       * through here */
      asfmux->payload_parsing_info_size =
          gst_asf_mux_find_payload_parsing_info_size (asfmux);
      asfmux->packet_size = asfmux->prop_packet_size;
      asfmux->preroll = asfmux->prop_preroll;
      asfmux->merge_stream_tags = asfmux->prop_merge_stream_tags;
      gst_collect_pads_start (asfmux->collect);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_collect_pads_stop (asfmux->collect);
      asfmux->state = GST_ASF_MUX_STATE_NONE;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    goto done;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

done:
  return ret;
}

gboolean
gst_asf_mux_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "asfmux",
      GST_RANK_PRIMARY, GST_TYPE_ASF_MUX);
}
