/* GStreamer EBML I/O
 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * (c) 2005 Michal Benes <michal.benes@xeris.cz>
 *
 * ebml-write.c: write EBML data to file/stream
 *
 * 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.
 */

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

#include <string.h>

#include "ebml-write.h"
#include "ebml-ids.h"


GST_DEBUG_CATEGORY_STATIC (gst_ebml_write_debug);
#define GST_CAT_DEFAULT gst_ebml_write_debug

#define _do_init \
      GST_DEBUG_CATEGORY_INIT (gst_ebml_write_debug, "ebmlwrite", 0, "Write EBML structured data")
#define parent_class gst_ebml_write_parent_class
G_DEFINE_TYPE_WITH_CODE (GstEbmlWrite, gst_ebml_write, GST_TYPE_OBJECT,
    _do_init);

static void gst_ebml_write_finalize (GObject * object);

static void
gst_ebml_write_class_init (GstEbmlWriteClass * klass)
{
  GObjectClass *object = G_OBJECT_CLASS (klass);

  object->finalize = gst_ebml_write_finalize;
}

static void
gst_ebml_write_init (GstEbmlWrite * ebml)
{
  ebml->srcpad = NULL;
  ebml->pos = 0;
  ebml->last_pos = G_MAXUINT64; /* force segment event */

  ebml->cache = NULL;
  ebml->streamheader = NULL;
  ebml->streamheader_pos = 0;
  ebml->writing_streamheader = FALSE;
  ebml->caps = NULL;
}

static void
gst_ebml_write_finalize (GObject * object)
{
  GstEbmlWrite *ebml = GST_EBML_WRITE (object);

  gst_object_unref (ebml->srcpad);

  if (ebml->cache) {
    gst_byte_writer_free (ebml->cache);
    ebml->cache = NULL;
  }

  if (ebml->streamheader) {
    gst_byte_writer_free (ebml->streamheader);
    ebml->streamheader = NULL;
  }

  if (ebml->caps) {
    gst_caps_unref (ebml->caps);
    ebml->caps = NULL;
  }

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


/**
 * gst_ebml_write_new:
 * @srcpad: Source pad to which the output will be pushed.
 *
 * Creates a new #GstEbmlWrite.
 *
 * Returns: a new #GstEbmlWrite
 */
GstEbmlWrite *
gst_ebml_write_new (GstPad * srcpad)
{
  GstEbmlWrite *ebml =
      GST_EBML_WRITE (g_object_new (GST_TYPE_EBML_WRITE, NULL));

  ebml->srcpad = gst_object_ref (srcpad);
  ebml->timestamp = GST_CLOCK_TIME_NONE;

  gst_ebml_write_reset (ebml);

  return ebml;
}


/**
 * gst_ebml_write_reset:
 * @ebml: a #GstEbmlWrite.
 *
 * Reset internal state of #GstEbmlWrite.
 */
void
gst_ebml_write_reset (GstEbmlWrite * ebml)
{
  ebml->pos = 0;
  ebml->last_pos = G_MAXUINT64; /* force segment event */

  if (ebml->cache) {
    gst_byte_writer_free (ebml->cache);
    ebml->cache = NULL;
  }

  if (ebml->caps) {
    gst_caps_unref (ebml->caps);
    ebml->caps = NULL;
  }

  ebml->last_write_result = GST_FLOW_OK;
  ebml->timestamp = GST_CLOCK_TIME_NONE;
}


/**
 * gst_ebml_last_write_result:
 * @ebml: a #GstEbmlWrite.
 *
 * Returns: GST_FLOW_OK if there was not write error since the last call of
 *          gst_ebml_last_write_result or code of the error.
 */
GstFlowReturn
gst_ebml_last_write_result (GstEbmlWrite * ebml)
{
  GstFlowReturn res = ebml->last_write_result;

  ebml->last_write_result = GST_FLOW_OK;

  return res;
}


void
gst_ebml_start_streamheader (GstEbmlWrite * ebml)
{
  g_return_if_fail (ebml->streamheader == NULL);

  GST_DEBUG ("Starting streamheader at %" G_GUINT64_FORMAT, ebml->pos);
  ebml->streamheader = gst_byte_writer_new_with_size (1000, FALSE);
  ebml->streamheader_pos = ebml->pos;
  ebml->writing_streamheader = TRUE;
}

GstBuffer *
gst_ebml_stop_streamheader (GstEbmlWrite * ebml)
{
  GstBuffer *buffer;

  if (!ebml->streamheader)
    return NULL;

  buffer = gst_byte_writer_free_and_get_buffer (ebml->streamheader);
  ebml->streamheader = NULL;
  GST_DEBUG ("Streamheader was size %" G_GSIZE_FORMAT,
      gst_buffer_get_size (buffer));

  ebml->writing_streamheader = FALSE;
  return buffer;
}

/**
 * gst_ebml_write_set_cache:
 * @ebml: a #GstEbmlWrite.
 * @size: size of the cache.
 * Create a cache.
 *
 * The idea is that you use this for writing a lot
 * of small elements. This will just "queue" all of
 * them and they'll be pushed to the next element all
 * at once. This saves memory and time for buffer
 * allocation and init, and it looks better.
 */
void
gst_ebml_write_set_cache (GstEbmlWrite * ebml, guint size)
{
  g_return_if_fail (ebml->cache == NULL);

  GST_DEBUG ("Starting cache at %" G_GUINT64_FORMAT, ebml->pos);
  ebml->cache = gst_byte_writer_new_with_size (size, FALSE);
  ebml->cache_pos = ebml->pos;
}

static gboolean
gst_ebml_writer_send_segment_event (GstEbmlWrite * ebml, guint64 new_pos)
{
  GstSegment segment;
  gboolean res;

  GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos);

  gst_segment_init (&segment, GST_FORMAT_BYTES);
  segment.start = new_pos;
  segment.stop = -1;
  segment.position = 0;

  res = gst_pad_push_event (ebml->srcpad, gst_event_new_segment (&segment));

  if (!res)
    GST_WARNING ("seek to %" G_GUINT64_FORMAT "failed", new_pos);

  return res;
}

/**
 * gst_ebml_write_flush_cache:
 * @ebml:      a #GstEbmlWrite.
 * @timestamp: timestamp of the buffer.
 *
 * Flush the cache.
 */
void
gst_ebml_write_flush_cache (GstEbmlWrite * ebml, gboolean is_keyframe,
    GstClockTime timestamp)
{
  GstBuffer *buffer;

  if (!ebml->cache)
    return;

  buffer = gst_byte_writer_free_and_get_buffer (ebml->cache);
  ebml->cache = NULL;
  GST_DEBUG ("Flushing cache of size %" G_GSIZE_FORMAT,
      gst_buffer_get_size (buffer));
  GST_BUFFER_TIMESTAMP (buffer) = timestamp;
  GST_BUFFER_OFFSET (buffer) = ebml->pos - gst_buffer_get_size (buffer);
  GST_BUFFER_OFFSET_END (buffer) = ebml->pos;
  if (ebml->last_write_result == GST_FLOW_OK) {
    if (GST_BUFFER_OFFSET (buffer) != ebml->last_pos) {
      gst_ebml_writer_send_segment_event (ebml, GST_BUFFER_OFFSET (buffer));
      GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
    }
    if (ebml->writing_streamheader) {
      GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
    }
    if (!is_keyframe) {
      GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
    }
    ebml->last_pos = ebml->pos;
    ebml->last_write_result = gst_pad_push (ebml->srcpad, buffer);
  } else {
    gst_buffer_unref (buffer);
  }
}


/**
 * gst_ebml_write_element_new:
 * @ebml: a #GstEbmlWrite.
 * @size: size of the requested buffer.
 *
 * Create a buffer for one element. If there is
 * a cache, use that instead.
 *
 * Returns: A new #GstBuffer.
 */
static GstBuffer *
gst_ebml_write_element_new (GstEbmlWrite * ebml, GstMapInfo * map, guint size)
{
  /* Create new buffer of size + ID + length */
  GstBuffer *buf;

  /* length, ID */
  size += 12;

  buf = gst_buffer_new_and_alloc (size);
  GST_BUFFER_TIMESTAMP (buf) = ebml->timestamp;

  /* FIXME unmap not possible */
  gst_buffer_map (buf, map, GST_MAP_WRITE);

  return buf;
}


/**
 * gst_ebml_write_element_id:
 * @data_inout: Pointer to data pointer
 * @id: Element ID that should be written.
 * 
 * Write element ID into a buffer.
 */
static void
gst_ebml_write_element_id (guint8 ** data_inout, guint32 id)
{
  guint8 *data = *data_inout;
  guint bytes = 4, mask = 0x10;

  /* get ID length */
  while (!(id & (mask << ((bytes - 1) * 8))) && bytes > 0) {
    mask <<= 1;
    bytes--;
  }

  /* if invalid ID, use dummy */
  if (bytes == 0) {
    GST_WARNING ("Invalid ID, voiding");
    bytes = 1;
    id = GST_EBML_ID_VOID;
  }

  /* write out, BE */
  *data_inout += bytes;
  while (bytes--) {
    data[bytes] = id & 0xff;
    id >>= 8;
  }
}


/**
 * gst_ebml_write_element_size:
 * @data_inout: Pointer to data pointer
 * @size: Element length.
 *
 * Write element length into a buffer.
 */
static void
gst_ebml_write_element_size (guint8 ** data_inout, guint64 size)
{
  guint8 *data = *data_inout;
  guint bytes = 1, mask = 0x80;

  if (size != GST_EBML_SIZE_UNKNOWN) {
    /* how many bytes? - use mask-1 because an all-1 bitset is not allowed */
    while ((size >> ((bytes - 1) * 8)) >= (mask - 1) && bytes <= 8) {
      mask >>= 1;
      bytes++;
    }

    /* if invalid size, use max. */
    if (bytes > 8) {
      GST_WARNING ("Invalid size, writing size unknown");
      mask = 0x01;
      bytes = 8;
      /* Now here's a real FIXME: we cannot read those yet! */
      size = GST_EBML_SIZE_UNKNOWN;
    }
  } else {
    mask = 0x01;
    bytes = 8;
  }

  /* write out, BE, with length size marker */
  *data_inout += bytes;
  while (bytes-- > 0) {
    data[bytes] = size & 0xff;
    size >>= 8;
    if (!bytes)
      *data |= mask;
  }
}


/**
 * gst_ebml_write_element_data:
 * @data_inout: Pointer to data pointer
 * @write: Data that should be written.
 * @length: Length of the data.
 *
 * Write element data into a buffer.
 */
static void
gst_ebml_write_element_data (guint8 ** data_inout, guint8 * write,
    guint64 length)
{
  memcpy (*data_inout, write, length);
  *data_inout += length;
}


/**
 * gst_ebml_write_element_push:
 * @ebml: #GstEbmlWrite
 * @buf: #GstBuffer to be written.
 * @buf_data: Start of data to push from @buf (or NULL for whole buffer).
 * @buf_data_end: Data pointer positioned after the last byte in @buf_data (or
 * NULL for whole buffer).
 * 
 * Write out buffer by moving it to the next element.
 */
static void
gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf,
    guint8 * buf_data, guint8 * buf_data_end)
{
  GstMapInfo map;
  guint data_size;

  map.data = NULL;

  if (buf_data_end)
    data_size = buf_data_end - buf_data;
  else
    data_size = gst_buffer_get_size (buf);

  ebml->pos += data_size;

  /* if there's no cache, then don't push it! */
  if (ebml->writing_streamheader) {
    if (!buf_data) {
      gst_buffer_map (buf, &map, GST_MAP_READ);
      buf_data = map.data;
    }
    if (!gst_byte_writer_put_data (ebml->streamheader, buf_data, data_size))
      GST_WARNING ("Error writing data to streamheader");
  }
  if (ebml->cache) {
    if (!buf_data) {
      gst_buffer_map (buf, &map, GST_MAP_READ);
      buf_data = map.data;
    }
    if (!gst_byte_writer_put_data (ebml->cache, buf_data, data_size))
      GST_WARNING ("Error writing data to cache");
    if (map.data)
      gst_buffer_unmap (buf, &map);
    gst_buffer_unref (buf);
    return;
  }

  if (buf_data && map.data)
    gst_buffer_unmap (buf, &map);

  if (ebml->last_write_result == GST_FLOW_OK) {
    buf = gst_buffer_make_writable (buf);
    GST_BUFFER_OFFSET (buf) = ebml->pos - data_size;
    GST_BUFFER_OFFSET_END (buf) = ebml->pos;
    if (ebml->writing_streamheader) {
      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
    }
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);

    if (GST_BUFFER_OFFSET (buf) != ebml->last_pos) {
      gst_ebml_writer_send_segment_event (ebml, GST_BUFFER_OFFSET (buf));
      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    }
    ebml->last_pos = ebml->pos;
    ebml->last_write_result = gst_pad_push (ebml->srcpad, buf);
  } else {
    gst_buffer_unref (buf);
  }
}


/**
 * gst_ebml_write_seek:
 * @ebml: #GstEbmlWrite
 * @pos: Seek position.
 * 
 * Seek.
 */
void
gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos)
{
  if (ebml->writing_streamheader) {
    GST_DEBUG ("wanting to seek to pos %" G_GUINT64_FORMAT, pos);
    if (pos >= ebml->streamheader_pos &&
        pos <= ebml->streamheader_pos + ebml->streamheader->parent.size) {
      gst_byte_writer_set_pos (ebml->streamheader,
          pos - ebml->streamheader_pos);
      GST_DEBUG ("seeked in streamheader to position %" G_GUINT64_FORMAT,
          pos - ebml->streamheader_pos);
    } else {
      GST_WARNING
          ("we are writing streamheader still and seek is out of bounds");
    }
  }
  /* Cache seeking. A bit dangerous, we assume the client writer
   * knows what he's doing... */
  if (ebml->cache) {
    /* within bounds? */
    if (pos >= ebml->cache_pos &&
        pos <= ebml->cache_pos + ebml->cache->parent.size) {
      GST_DEBUG ("seeking in cache to %" G_GUINT64_FORMAT, pos);
      ebml->pos = pos;
      gst_byte_writer_set_pos (ebml->cache, ebml->pos - ebml->cache_pos);
      return;
    } else {
      GST_LOG ("Seek outside cache range. Clearing...");
      gst_ebml_write_flush_cache (ebml, FALSE, GST_CLOCK_TIME_NONE);
    }
  }

  GST_INFO ("scheduling seek to %" G_GUINT64_FORMAT, pos);
  ebml->pos = pos;
}


/**
 * gst_ebml_write_get_uint_size:
 * @num: Number to be encoded.
 * 
 * Get number of bytes needed to write a uint.
 *
 * Returns: Encoded uint length.
 */
static guint
gst_ebml_write_get_uint_size (guint64 num)
{
  guint size = 1;

  /* get size */
  while (num >= (G_GINT64_CONSTANT (1) << (size * 8)) && size < 8) {
    size++;
  }

  return size;
}


/**
 * gst_ebml_write_set_uint:
 * @data_inout: Pointer to data pointer
 * @num: Number to be written.
 * @size: Encoded number length.
 *
 * Write an uint into a buffer.
 */
static void
gst_ebml_write_set_uint (guint8 ** data_inout, guint64 num, guint size)
{
  guint8 *data = *data_inout;

  *data_inout += size;

  while (size-- > 0) {
    data[size] = num & 0xff;
    num >>= 8;
  }
}


/**
 * gst_ebml_write_uint:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @num: Number to be written.
 *
 * Write uint element.
 */
void
gst_ebml_write_uint (GstEbmlWrite * ebml, guint32 id, guint64 num)
{
  GstBuffer *buf;
  guint8 *data_start, *data_end;
  guint size = gst_ebml_write_get_uint_size (num);
  GstMapInfo map;

  buf = gst_ebml_write_element_new (ebml, &map, sizeof (num));
  data_end = data_start = map.data;

  /* write */
  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, size);
  gst_ebml_write_set_uint (&data_end, num, size);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_sint:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @num: Number to be written.
 *
 * Write sint element.
 */
void
gst_ebml_write_sint (GstEbmlWrite * ebml, guint32 id, gint64 num)
{
  GstBuffer *buf;
  guint8 *data_start, *data_end;
  GstMapInfo map;

  /* if the signed number is on the edge of a extra-byte,
   * then we'll fall over when detecting it. Example: if I
   * have a number (-)0x8000 (G_MINSHORT), then my abs()<<1
   * will be 0x10000; this is G_MAXUSHORT+1! So: if (<0) -1. */
  guint64 unum = (num < 0 ? (-num - 1) << 1 : num << 1);
  guint size = gst_ebml_write_get_uint_size (unum);

  buf = gst_ebml_write_element_new (ebml, &map, sizeof (num));
  data_end = data_start = map.data;

  /* make unsigned */
  if (num >= 0) {
    unum = num;
  } else {
    unum = 0x80 << (size - 1);
    unum += num;
    unum |= 0x80 << (size - 1);
  }

  /* write */
  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, size);
  gst_ebml_write_set_uint (&data_end, unum, size);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_float:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @num: Number to be written.
 *
 * Write float element.
 */
void
gst_ebml_write_float (GstEbmlWrite * ebml, guint32 id, gdouble num)
{
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, sizeof (num));
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, 8);
  num = GDOUBLE_TO_BE (num);
  gst_ebml_write_element_data (&data_end, (guint8 *) & num, 8);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_ascii:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @str: String to be written.
 *
 * Write string element.
 */
void
gst_ebml_write_ascii (GstEbmlWrite * ebml, guint32 id, const gchar * str)
{
  gint len = strlen (str) + 1;  /* add trailing '\0' */
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, len);
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, len);
  gst_ebml_write_element_data (&data_end, (guint8 *) str, len);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_utf8:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @str: String to be written.
 *
 * Write utf8 encoded string element.
 */
void
gst_ebml_write_utf8 (GstEbmlWrite * ebml, guint32 id, const gchar * str)
{
  gst_ebml_write_ascii (ebml, id, str);
}


/**
 * gst_ebml_write_date:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @date: Date in seconds since the unix epoch.
 *
 * Write date element.
 */
void
gst_ebml_write_date (GstEbmlWrite * ebml, guint32 id, gint64 date)
{
  gst_ebml_write_sint (ebml, id, (date - GST_EBML_DATE_OFFSET) * GST_SECOND);
}

/**
 * gst_ebml_write_master_start:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 *
 * Start wiriting mater element.
 *
 * Master writing is annoying. We use a size marker of
 * the max. allowed length, so that we can later fill it
 * in validly. 
 *
 * Returns: Master starting position.
 */
guint64
gst_ebml_write_master_start (GstEbmlWrite * ebml, guint32 id)
{
  guint64 pos = ebml->pos;
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, 0);
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  pos += data_end - data_start;
  gst_ebml_write_element_size (&data_end, GST_EBML_SIZE_UNKNOWN);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);

  return pos;
}


/**
 * gst_ebml_write_master_finish_full:
 * @ebml: #GstEbmlWrite
 * @startpos: Master starting position.
 *
 * Finish writing master element.  Size of master element is difference between
 * current position and the element start, and @extra_size added to this.
 */
void
gst_ebml_write_master_finish_full (GstEbmlWrite * ebml, guint64 startpos,
    guint64 extra_size)
{
  guint64 pos = ebml->pos;
  guint8 *data = g_malloc (8);
  GstBuffer *buf = gst_buffer_new_wrapped (data, 8);

  gst_ebml_write_seek (ebml, startpos);

  GST_WRITE_UINT64_BE (data,
      (G_GINT64_CONSTANT (1) << 56) | (pos - startpos - 8 + extra_size));

  gst_ebml_write_element_push (ebml, buf, NULL, NULL);
  gst_ebml_write_seek (ebml, pos);
}

void
gst_ebml_write_master_finish (GstEbmlWrite * ebml, guint64 startpos)
{
  gst_ebml_write_master_finish_full (ebml, startpos, 0);
}

/**
 * gst_ebml_write_binary:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @binary: Data to be written.
 * @length: Length of the data
 *
 * Write an element with binary data.
 */
void
gst_ebml_write_binary (GstEbmlWrite * ebml,
    guint32 id, guint8 * binary, guint64 length)
{
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, length);
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, length);
  gst_ebml_write_element_data (&data_end, binary, length);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_buffer_header:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @length: Length of the data
 * 
 * Write header of the binary element (use with gst_ebml_write_buffer function).
 * 
 * For things like video frames and audio samples,
 * you want to use this function, as it doesn't have
 * the overhead of memcpy() that other functions
 * such as write_binary() do have.
 */
void
gst_ebml_write_buffer_header (GstEbmlWrite * ebml, guint32 id, guint64 length)
{
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, 0);
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, length);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_buffer:
 * @ebml: #GstEbmlWrite
 * @buf: #GstBuffer cointaining the data.
 *
 * Write  binary element (see gst_ebml_write_buffer_header).
 */
void
gst_ebml_write_buffer (GstEbmlWrite * ebml, GstBuffer * buf)
{
  gst_ebml_write_element_push (ebml, buf, NULL, NULL);
}


/**
 * gst_ebml_replace_uint:
 * @ebml: #GstEbmlWrite
 * @pos: Position of the uint that should be replaced.
 * @num: New value.
 *
 * Replace uint with a new value.
 * 
 * When replacing a uint, we assume that it is *always*
 * 8-byte, since that's the safest guess we can do. This
 * is just for simplicity.
 *
 * FIXME: this function needs to be replaced with something
 * proper. This is a crude hack.
 */
void
gst_ebml_replace_uint (GstEbmlWrite * ebml, guint64 pos, guint64 num)
{
  guint64 oldpos = ebml->pos;
  guint8 *data_start, *data_end;
  GstBuffer *buf;

  data_start = g_malloc (8);
  data_end = data_start;
  buf = gst_buffer_new_wrapped (data_start, 8);

  gst_ebml_write_seek (ebml, pos);
  gst_ebml_write_set_uint (&data_end, num, 8);

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
  gst_ebml_write_seek (ebml, oldpos);
}

/**
 * gst_ebml_write_header:
 * @ebml: #GstEbmlWrite
 * @doctype: Document type.
 * @version: Document type version.
 * 
 * Write EBML header.
 */
void
gst_ebml_write_header (GstEbmlWrite * ebml, const gchar * doctype,
    guint version)
{
  guint64 pos;

  /* write the basic EBML header */
  gst_ebml_write_set_cache (ebml, 0x40);
  pos = gst_ebml_write_master_start (ebml, GST_EBML_ID_HEADER);
#if (GST_EBML_VERSION != 1)
  gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLVERSION, GST_EBML_VERSION);
  gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLREADVERSION, GST_EBML_VERSION);
#endif
#if 0
  /* we don't write these until they're "non-default" (never!) */
  gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLMAXIDLENGTH, sizeof (guint32));
  gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLMAXSIZELENGTH, sizeof (guint64));
#endif
  gst_ebml_write_ascii (ebml, GST_EBML_ID_DOCTYPE, doctype);
  gst_ebml_write_uint (ebml, GST_EBML_ID_DOCTYPEVERSION, version);
  gst_ebml_write_uint (ebml, GST_EBML_ID_DOCTYPEREADVERSION, version);
  gst_ebml_write_master_finish (ebml, pos);
  gst_ebml_write_flush_cache (ebml, FALSE, 0);
}
