/* 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-1.0 videotestsrc num-buffers=250 \
 * ! "video/x-raw,format=(string)I420,framerate=(fraction)25/1" ! avenc_wmv2 \
 * ! asfmux name=mux ! filesink location=test.asf \
 * audiotestsrc num-buffers=440 ! audioconvert \
 * ! "audio/x-raw,rate=44100" ! avenc_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-1.0 -ve videotestsrc ! avenc_wmv2 ! asfmux name=mux streamable=true \
 * ! rtpasfpay ! udpsink host=127.0.0.1 port=3333 \
 * audiotestsrc ! avenc_wmav2 ! mux.
 * ]|
 * Client (receiver)
 * |[
 * gst-launch-1.0 udpsrc port=3333 ! "caps_from_rtpasfpay_at_sender" \
 * ! rtpasfdepay ! decodebin 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_static_pad_template (gstelement_class, &src_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &audio_sink_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &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 */
  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;

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

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

  /* 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);

  /* send a BYTE format segment if we're going to seek to fix up the headers
   * later, otherwise send a TIME segment */
  if (asfmux->prop_streamable)
    gst_segment_init (&segment, GST_FORMAT_TIME);
  else
    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);
}
