/* AVI muxer plugin for GStreamer
 * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
 *           (C) 2006 Mark Nauwelaerts <manauw@skynet.be>
 *
 * 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:
 * - the old avimuxer (by Wim Taymans)
 * - xawtv's aviwriter (by Gerd Knorr)
 * - mjpegtools' avilib (by Rainer Johanni)
 * - openDML large-AVI docs
 */

/**
 * SECTION:element-avimux
 *
 * Muxes raw or compressed audio and/or video streams into an AVI file.
 *
 * <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,width=320,height=240,framerate=(fraction)25/1' \
 * ! queue ! mux. \
 * audiotestsrc num-buffers=440 ! audioconvert \
 * ! 'audio/x-raw,rate=44100,channels=2' ! queue ! mux. \
 * avimux name=mux ! filesink location=test.avi
 * ]| This will create an .AVI file containing an uncompressed video stream
 * with a test picture and an uncompressed audio stream containing a
 * test sound.
 * |[
 * gst-launch-1.0 videotestsrc num-buffers=250 \
 * ! 'video/x-raw,format=(string)I420,width=320,height=240,framerate=(fraction)25/1' \
 * ! xvidenc ! queue ! mux. \
 * audiotestsrc num-buffers=440 ! audioconvert ! 'audio/x-raw,rate=44100,channels=2' \
 * ! lame ! queue ! mux. \
 * avimux name=mux ! filesink location=test.avi
 * ]| This will create an .AVI file containing the same test video and sound
 * as above, only that both streams will be compressed this time. This will
 * only work if you have the necessary encoder elements installed of course.
 * </refsect2>
 */

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

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

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

#include "gstavimux.h"

GST_DEBUG_CATEGORY_STATIC (avimux_debug);
#define GST_CAT_DEFAULT avimux_debug

enum
{
  ARG_0,
  ARG_BIGFILE
};

#define DEFAULT_BIGFILE TRUE

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-msvideo")
    );

static GstStaticPadTemplate video_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("video_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("video/x-raw, "
        "format = (string) { YUY2, I420, BGR, BGRx, BGRA, GRAY8, UYVY }, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], "
        "framerate = (fraction) [ 0, MAX ]; "
        "image/jpeg, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], "
        "framerate = (fraction) [ 0, MAX ]; "
        "video/x-divx, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], "
        "framerate = (fraction) [ 0, MAX ], "
        "divxversion = (int) [ 3, 5 ]; "
        "video/x-msmpeg, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], "
        "framerate = (fraction) [ 0, MAX ], "
        "msmpegversion = (int) [ 41, 43 ]; "
        "video/mpeg, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], "
        "framerate = (fraction) [ 0, MAX ], "
        "mpegversion = (int) { 1, 2, 4}, "
        "systemstream = (boolean) FALSE; "
        "video/x-h263, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], "
        "framerate = (fraction) [ 0, MAX ]; "
        "video/x-h264, "
        "stream-format = (string) byte-stream, "
        "alignment = (string) au, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], "
        "framerate = (fraction) [ 0, MAX ]; "
        "video/x-dv, "
        "width = (int) 720, "
        "height = (int) { 576, 480 }, "
        "framerate = (fraction) [ 0, MAX ], "
        "systemstream = (boolean) FALSE; "
        "video/x-huffyuv, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0, MAX ];"
        "video/x-wmv, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0, MAX ], "
        "wmvversion = (int) [ 1, 3];"
        "image/x-jpc, "
        "width = (int) [ 1, 2147483647 ], "
        "height = (int) [ 1, 2147483647 ], "
        "framerate = (fraction) [ 0, MAX ];"
        "video/x-vp8, "
        "width = (int) [ 1, 2147483647 ], "
        "height = (int) [ 1, 2147483647 ], "
        "framerate = (fraction) [ 0, MAX ]")
    );

static GstStaticPadTemplate audio_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("audio_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) { U8, S16LE }, "
        "rate = (int) [ 1000, 96000 ], "
        "channels = (int) [ 1, 2 ]; "
        "audio/mpeg, "
        "mpegversion = (int) 1, "
        "layer = (int) [ 1, 3 ], "
        "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ]; "
        "audio/mpeg, "
        "mpegversion = (int) 4, "
        "stream-format = (string) raw, "
        "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ]; "
/*#if 0 VC6 doesn't support #if here ...
        "audio/x-vorbis, "
        "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ]; "
#endif*/
        "audio/x-ac3, "
        "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 6 ]; "
        "audio/x-alaw, "
        "rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]; "
        "audio/x-mulaw, "
        "rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]; "
        "audio/x-wma, "
        "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ], "
        "wmaversion = (int) [ 1, 2 ] ")
    );

static void gst_avi_mux_pad_reset (GstAviPad * avipad, gboolean free);

static GstFlowReturn gst_avi_mux_collect_pads (GstCollectPads * pads,
    GstAviMux * avimux);
static gboolean gst_avi_mux_handle_event (GstCollectPads * pad,
    GstCollectData * data, GstEvent * event, gpointer user_data);
static GstPad *gst_avi_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gst_avi_mux_release_pad (GstElement * element, GstPad * pad);
static void gst_avi_mux_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_avi_mux_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_avi_mux_change_state (GstElement * element,
    GstStateChange transition);

#define gst_avi_mux_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstAviMux, gst_avi_mux, GST_TYPE_ELEMENT,
    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));

static void
gst_avi_mux_finalize (GObject * object)
{
  GstAviMux *mux = GST_AVI_MUX (object);
  GSList *node;

  /* completely free each sinkpad */
  node = mux->sinkpads;
  while (node) {
    GstAviPad *avipad = (GstAviPad *) node->data;

    node = node->next;

    gst_avi_mux_pad_reset (avipad, TRUE);
    g_free (avipad);
  }
  g_slist_free (mux->sinkpads);
  mux->sinkpads = NULL;

  g_free (mux->idx);
  mux->idx = NULL;

  gst_object_unref (mux->collect);

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

static void
gst_avi_mux_class_init (GstAviMuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  GST_DEBUG_CATEGORY_INIT (avimux_debug, "avimux", 0, "Muxer for AVI streams");

  gobject_class->get_property = gst_avi_mux_get_property;
  gobject_class->set_property = gst_avi_mux_set_property;
  gobject_class->finalize = gst_avi_mux_finalize;

  g_object_class_install_property (gobject_class, ARG_BIGFILE,
      g_param_spec_boolean ("bigfile", "Bigfile Support (>2GB)",
          "Support for openDML-2.0 (big) AVI files", DEFAULT_BIGFILE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_avi_mux_request_new_pad);
  gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_avi_mux_release_pad);
  gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_avi_mux_change_state);

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

  gst_element_class_set_static_metadata (gstelement_class, "Avi muxer",
      "Codec/Muxer",
      "Muxes audio and video into an avi stream",
      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
}

/* reset pad to initial state
 * free - if true, release all, not only stream related, data */
static void
gst_avi_mux_pad_reset (GstAviPad * avipad, gboolean free)
{
  /* generic part */
  memset (&(avipad->hdr), 0, sizeof (gst_riff_strh));

  memset (&(avipad->idx[0]), 0, sizeof (avipad->idx));

  if (free) {
    g_free (avipad->tag);
    avipad->tag = NULL;
    g_free (avipad->idx_tag);
    avipad->idx_tag = NULL;
  }

  if (avipad->is_video) {
    GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;

    avipad->hdr.type = GST_MAKE_FOURCC ('v', 'i', 'd', 's');
    if (vidpad->vids_codec_data) {
      gst_buffer_unref (vidpad->vids_codec_data);
      vidpad->vids_codec_data = NULL;
    }

    if (vidpad->prepend_buffer) {
      gst_buffer_unref (vidpad->prepend_buffer);
      vidpad->prepend_buffer = NULL;
    }

    memset (&(vidpad->vids), 0, sizeof (gst_riff_strf_vids));
    memset (&(vidpad->vprp), 0, sizeof (gst_riff_vprp));
  } else {
    GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;

    audpad->samples = 0;

    avipad->hdr.type = GST_MAKE_FOURCC ('a', 'u', 'd', 's');
    if (audpad->auds_codec_data) {
      gst_buffer_unref (audpad->auds_codec_data);
      audpad->auds_codec_data = NULL;
    }

    memset (&(audpad->auds), 0, sizeof (gst_riff_strf_auds));

    audpad->audio_size = 0;
    audpad->audio_time = 0;
    audpad->max_audio_chunk = 0;
  }
}

static void
gst_avi_mux_reset (GstAviMux * avimux)
{
  GSList *node, *newlist = NULL;

  /* free and reset each sinkpad */
  node = avimux->sinkpads;
  while (node) {
    GstAviPad *avipad = (GstAviPad *) node->data;

    node = node->next;

    gst_avi_mux_pad_reset (avipad, FALSE);
    /* if this pad has collectdata, keep it, otherwise dump it completely */
    if (avipad->collect)
      newlist = g_slist_append (newlist, avipad);
    else {
      gst_avi_mux_pad_reset (avipad, TRUE);
      g_free (avipad);
    }
  }

  /* free the old list of sinkpads, only keep the real collecting ones */
  g_slist_free (avimux->sinkpads);
  avimux->sinkpads = newlist;

  /* avi data */
  avimux->num_frames = 0;
  memset (&(avimux->avi_hdr), 0, sizeof (gst_riff_avih));
  avimux->avi_hdr.max_bps = 10000000;
  avimux->codec_data_size = 0;

  if (avimux->tags_snap) {
    gst_tag_list_unref (avimux->tags_snap);
    avimux->tags_snap = NULL;
  }

  g_free (avimux->idx);
  avimux->idx = NULL;

  /* state info */
  avimux->write_header = TRUE;

  /* tags */
  gst_tag_setter_reset_tags (GST_TAG_SETTER (avimux));
}

static void
gst_avi_mux_init (GstAviMux * avimux)
{
  avimux->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
  gst_pad_use_fixed_caps (avimux->srcpad);
  gst_element_add_pad (GST_ELEMENT (avimux), avimux->srcpad);

  /* property */
  avimux->enable_large_avi = DEFAULT_BIGFILE;

  avimux->collect = gst_collect_pads_new ();
  gst_collect_pads_set_function (avimux->collect,
      (GstCollectPadsFunction) (GST_DEBUG_FUNCPTR (gst_avi_mux_collect_pads)),
      avimux);
  gst_collect_pads_set_event_function (avimux->collect,
      (GstCollectPadsEventFunction) (GST_DEBUG_FUNCPTR
          (gst_avi_mux_handle_event)), avimux);

  /* set to clean state */
  gst_avi_mux_reset (avimux);
}

static gboolean
gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
{
  GstAviMux *avimux;
  GstAviVideoPad *avipad;
  GstAviCollectData *collect_pad;
  GstStructure *structure;
  const gchar *mimetype;
  const GValue *fps, *par;
  const GValue *codec_data;
  gint width, height;
  gint par_n, par_d;
  gboolean codec_data_in_headers = TRUE;
  gboolean valid_caps = TRUE;

  avimux = GST_AVI_MUX (gst_pad_get_parent (pad));

  /* find stream data */
  collect_pad = (GstAviCollectData *) gst_pad_get_element_private (pad);
  g_assert (collect_pad);
  avipad = (GstAviVideoPad *) collect_pad->avipad;
  g_assert (avipad);
  g_assert (avipad->parent.is_video);
  g_assert (avipad->parent.hdr.type == GST_MAKE_FOURCC ('v', 'i', 'd', 's'));

  GST_DEBUG_OBJECT (avimux, "%s:%s, caps=%" GST_PTR_FORMAT,
      GST_DEBUG_PAD_NAME (pad), vscaps);

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

  /* global */
  avipad->vids.size = sizeof (gst_riff_strf_vids);
  avipad->vids.planes = 1;
  if (!gst_structure_get_int (structure, "width", &width) ||
      !gst_structure_get_int (structure, "height", &height)) {
    goto refuse_caps;
  }

  avipad->vids.width = width;
  avipad->vids.height = height;

  fps = gst_structure_get_value (structure, "framerate");
  if (fps == NULL || !GST_VALUE_HOLDS_FRACTION (fps))
    goto refuse_caps;

  avipad->parent.hdr.rate = gst_value_get_fraction_numerator (fps);
  avipad->parent.hdr.scale = gst_value_get_fraction_denominator (fps);
  if (avipad->parent.hdr.rate <= 0 || avipad->parent.hdr.scale <= 0)
    goto refuse_caps;

  /* (pixel) aspect ratio data, if any */
  par = gst_structure_get_value (structure, "pixel-aspect-ratio");
  /* only use video properties header if there is non-trivial aspect info */
  if (par && GST_VALUE_HOLDS_FRACTION (par) &&
      ((par_n = gst_value_get_fraction_numerator (par)) !=
          (par_d = gst_value_get_fraction_denominator (par)))) {
    GValue to_ratio = { 0, };
    guint ratio_n, ratio_d;

    /* some fraction voodoo to obtain simplest possible ratio */
    g_value_init (&to_ratio, GST_TYPE_FRACTION);
    gst_value_set_fraction (&to_ratio, width * par_n, height * par_d);
    ratio_n = gst_value_get_fraction_numerator (&to_ratio);
    ratio_d = gst_value_get_fraction_denominator (&to_ratio);
    GST_DEBUG_OBJECT (avimux, "generating vprp data with aspect ratio %d/%d",
        ratio_n, ratio_d);
    /* simply fill in */
    avipad->vprp.vert_rate = avipad->parent.hdr.rate / avipad->parent.hdr.scale;
    avipad->vprp.hor_t_total = width;
    avipad->vprp.vert_lines = height;
    avipad->vprp.aspect = (ratio_n) << 16 | (ratio_d & 0xffff);
    avipad->vprp.width = width;
    avipad->vprp.height = height;
    avipad->vprp.fields = 1;
    avipad->vprp.field_info[0].compressed_bm_height = height;
    avipad->vprp.field_info[0].compressed_bm_width = width;
    avipad->vprp.field_info[0].valid_bm_height = height;
    avipad->vprp.field_info[0].valid_bm_width = width;
  }

  if (!strcmp (mimetype, "video/x-raw")) {
    const gchar *format;
    GstVideoFormat fmt;

    format = gst_structure_get_string (structure, "format");
    fmt = gst_video_format_from_string (format);

    switch (fmt) {
      case GST_VIDEO_FORMAT_YUY2:
        avipad->vids.compression = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
        avipad->vids.bit_cnt = 16;
        break;
      case GST_VIDEO_FORMAT_UYVY:
        avipad->vids.compression = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
        avipad->vids.bit_cnt = 16;
        break;
      case GST_VIDEO_FORMAT_I420:
        avipad->vids.compression = GST_MAKE_FOURCC ('I', '4', '2', '0');
        avipad->vids.bit_cnt = 12;
        break;
      case GST_VIDEO_FORMAT_GRAY8:
        avipad->vids.compression = GST_MAKE_FOURCC ('Y', '8', '0', '0');
        avipad->vids.bit_cnt = 8;
        break;
      case GST_VIDEO_FORMAT_BGR:
        avipad->vids.compression = GST_MAKE_FOURCC (0x00, 0x00, 0x00, 0x00);
        avipad->vids.bit_cnt = 24;
        break;
      case GST_VIDEO_FORMAT_BGRx:
      case GST_VIDEO_FORMAT_BGRA:
        avipad->vids.compression = GST_MAKE_FOURCC (0x00, 0x00, 0x00, 0x00);
        avipad->vids.bit_cnt = 32;
        break;
      default:
        valid_caps = FALSE;
        break;
    }
  } else {
    avipad->vids.bit_cnt = 24;
    avipad->vids.compression = 0;

    /* find format */
    if (!strcmp (mimetype, "video/x-huffyuv")) {
      avipad->vids.compression = GST_MAKE_FOURCC ('H', 'F', 'Y', 'U');
    } else if (!strcmp (mimetype, "image/jpeg")) {
      avipad->vids.compression = GST_MAKE_FOURCC ('M', 'J', 'P', 'G');
    } else if (!strcmp (mimetype, "video/x-divx")) {
      gint divxversion;

      gst_structure_get_int (structure, "divxversion", &divxversion);
      switch (divxversion) {
        case 3:
          avipad->vids.compression = GST_MAKE_FOURCC ('D', 'I', 'V', '3');
          break;
        case 4:
          avipad->vids.compression = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
          break;
        case 5:
          avipad->vids.compression = GST_MAKE_FOURCC ('D', 'X', '5', '0');
          break;
        default:
          valid_caps = FALSE;
      }
    } else if (gst_structure_has_name (structure, "video/x-msmpeg")) {
      gint msmpegversion;

      gst_structure_get_int (structure, "msmpegversion", &msmpegversion);
      switch (msmpegversion) {
        case 41:
          avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', 'G', '4');
          break;
        case 42:
          avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', '4', '2');
          break;
        case 43:
          avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', '4', '3');
          break;
        default:
          GST_INFO ("unhandled msmpegversion : %d, fall back to fourcc=MPEG",
              msmpegversion);
          avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', 'E', 'G');
          break;
      }
    } else if (!strcmp (mimetype, "video/x-dv")) {
      avipad->vids.compression = GST_MAKE_FOURCC ('D', 'V', 'S', 'D');
    } else if (!strcmp (mimetype, "video/x-h263")) {
      avipad->vids.compression = GST_MAKE_FOURCC ('H', '2', '6', '3');
    } else if (!strcmp (mimetype, "video/x-h264")) {
      avipad->vids.compression = GST_MAKE_FOURCC ('H', '2', '6', '4');
    } else if (!strcmp (mimetype, "video/mpeg")) {
      gint mpegversion;

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

      switch (mpegversion) {
        case 2:
          avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', 'G', '2');
          break;
        case 4:
          /* mplayer/ffmpeg might not work with DIVX, but with FMP4 */
          avipad->vids.compression = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');

          /* DIVX/XVID in AVI store the codec_data chunk as part of the
             first data buffer. So for this case, we prepend the codec_data
             blob (if any) to that first buffer */
          codec_data_in_headers = FALSE;
          break;
        default:
          GST_INFO ("unhandled mpegversion : %d, fall back to fourcc=MPEG",
              mpegversion);
          avipad->vids.compression = GST_MAKE_FOURCC ('M', 'P', 'E', 'G');
          break;
      }
    } else if (!strcmp (mimetype, "video/x-wmv")) {
      gint wmvversion;

      if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
        switch (wmvversion) {
          case 1:
            avipad->vids.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '1');
            break;
          case 2:
            avipad->vids.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '2');
            break;
          case 3:
            avipad->vids.compression = GST_MAKE_FOURCC ('W', 'M', 'V', '3');
            break;
          default:
            valid_caps = FALSE;
            break;
        }
      }
    } else if (!strcmp (mimetype, "image/x-jpc")) {
      avipad->vids.compression = GST_MAKE_FOURCC ('M', 'J', '2', 'C');
    } else if (!strcmp (mimetype, "video/x-vp8")) {
      avipad->vids.compression = GST_MAKE_FOURCC ('V', 'P', '8', '0');
    } else {
      valid_caps = FALSE;
    }

    if (!valid_caps)
      goto refuse_caps;
  }

  /* codec initialization data, if any */
  codec_data = gst_structure_get_value (structure, "codec_data");
  if (codec_data) {
    if (codec_data_in_headers) {
      avipad->vids_codec_data = gst_value_get_buffer (codec_data);
      gst_buffer_ref (avipad->vids_codec_data);
      /* keep global track of size */
      avimux->codec_data_size += gst_buffer_get_size (avipad->vids_codec_data);
    } else {
      avipad->prepend_buffer =
          gst_buffer_ref (gst_value_get_buffer (codec_data));
    }
  }

  avipad->parent.hdr.fcc_handler = avipad->vids.compression;
  avipad->vids.image_size = avipad->vids.height * avipad->vids.width;
  /* hm, maybe why avi only handles one stream well ... */
  avimux->avi_hdr.width = avipad->vids.width;
  avimux->avi_hdr.height = avipad->vids.height;
  avimux->avi_hdr.us_frame = 1000000. * avipad->parent.hdr.scale /
      avipad->parent.hdr.rate;

  gst_object_unref (avimux);
  return TRUE;

refuse_caps:
  {
    GST_WARNING_OBJECT (avimux, "refused caps %" GST_PTR_FORMAT, vscaps);
    gst_object_unref (avimux);
    return FALSE;
  }
}

static GstFlowReturn
gst_avi_mux_audsink_scan_mpeg_audio (GstAviMux * avimux, GstAviPad * avipad,
    GstBuffer * buffer)
{
  GstMapInfo map;
  guint spf;
  guint32 header;
  gulong layer;
  gulong version;
  gint lsf, mpg25;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  if (map.size < 4)
    goto not_parsed;

  header = GST_READ_UINT32_BE (map.data);

  if ((header & 0xffe00000) != 0xffe00000)
    goto not_parsed;

  /* thanks go to mp3parse */
  if (header & (1 << 20)) {
    lsf = (header & (1 << 19)) ? 0 : 1;
    mpg25 = 0;
  } else {
    lsf = 1;
    mpg25 = 1;
  }

  version = 1 + lsf + mpg25;
  layer = 4 - ((header >> 17) & 0x3);

  /* see http://www.codeproject.com/audio/MPEGAudioInfo.asp */
  if (layer == 1)
    spf = 384;
  else if (layer == 2)
    spf = 1152;
  else if (version == 1) {
    spf = 1152;
  } else {
    /* MPEG-2 or "2.5" */
    spf = 576;
  }

  if (G_UNLIKELY (avipad->hdr.scale <= 1))
    avipad->hdr.scale = spf;
  else if (G_UNLIKELY (avipad->hdr.scale != spf)) {
    GST_WARNING_OBJECT (avimux, "input mpeg audio has varying frame size");
    goto cbr_fallback;
  }
done:
  gst_buffer_unmap (buffer, &map);

  return GST_FLOW_OK;

  /* EXITS */
not_parsed:
  {
    GST_WARNING_OBJECT (avimux, "input mpeg audio is not parsed");
    /* fall-through */
  }
cbr_fallback:
  {
    GST_WARNING_OBJECT (avimux, "falling back to CBR muxing");
    avipad->hdr.scale = 1;
    /* no need to check further */
    avipad->hook = NULL;
    goto done;
  }
}

static void
gst_avi_mux_audsink_set_fields (GstAviMux * avimux, GstAviAudioPad * avipad)
{
  if (avipad->parent.hdr.scale > 1) {
    /* vbr case: fixed duration per frame/chunk */
    avipad->parent.hdr.rate = avipad->auds.rate;
    avipad->parent.hdr.samplesize = 0;
    /* this triggers determining largest audio chunk size to write at end */
    avipad->max_audio_chunk = avipad->auds.blockalign =
        avipad->parent.hdr.scale;
  } else {
    /* by spec, hdr.rate is av_bps related, is calculated that way in stop_file,
     * and reduces to sample rate in PCM like cases */
    avipad->parent.hdr.rate = avipad->auds.av_bps / avipad->auds.blockalign;
    avipad->parent.hdr.samplesize = avipad->auds.blockalign;
    avipad->parent.hdr.scale = 1;
  }
}

static gboolean
gst_avi_mux_audsink_set_caps (GstPad * pad, GstCaps * vscaps)
{
  GstAviMux *avimux;
  GstAviAudioPad *avipad;
  GstAviCollectData *collect_pad;
  GstStructure *structure;
  const gchar *mimetype;
  const GValue *codec_data;
  gint channels, rate;

  avimux = GST_AVI_MUX (gst_pad_get_parent (pad));

  /* find stream data */
  collect_pad = (GstAviCollectData *) gst_pad_get_element_private (pad);
  g_assert (collect_pad);
  avipad = (GstAviAudioPad *) collect_pad->avipad;
  g_assert (avipad);
  g_assert (!avipad->parent.is_video);
  g_assert (avipad->parent.hdr.type == GST_MAKE_FOURCC ('a', 'u', 'd', 's'));

  GST_DEBUG_OBJECT (avimux, "%s:%s, caps=%" GST_PTR_FORMAT,
      GST_DEBUG_PAD_NAME (pad), vscaps);

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

  /* we want these for all */
  if (!gst_structure_get_int (structure, "channels", &channels) ||
      !gst_structure_get_int (structure, "rate", &rate)) {
    goto refuse_caps;
  }

  avipad->auds.channels = channels;
  avipad->auds.rate = rate;

  /* codec initialization data, if any */
  codec_data = gst_structure_get_value (structure, "codec_data");
  if (codec_data) {
    avipad->auds_codec_data = gst_value_get_buffer (codec_data);
    gst_buffer_ref (avipad->auds_codec_data);
    /* keep global track of size */
    avimux->codec_data_size += gst_buffer_get_size (avipad->auds_codec_data);
  }

  if (!strcmp (mimetype, "audio/x-raw")) {
    const gchar *format;
    GstAudioFormat fmt;

    format = gst_structure_get_string (structure, "format");
    fmt = gst_audio_format_from_string (format);

    switch (fmt) {
      case GST_AUDIO_FORMAT_U8:
        avipad->auds.blockalign = 8;
        avipad->auds.bits_per_sample = 8;
        break;
      case GST_AUDIO_FORMAT_S16:
        avipad->auds.blockalign = 16;
        avipad->auds.bits_per_sample = 16;
        break;
      default:
        goto refuse_caps;
    }

    avipad->auds.format = GST_RIFF_WAVE_FORMAT_PCM;
    /* set some more info straight */
    avipad->auds.blockalign /= 8;
    avipad->auds.blockalign *= avipad->auds.channels;
    avipad->auds.av_bps = avipad->auds.blockalign * avipad->auds.rate;
  } else {
    avipad->auds.format = 0;
    /* set some defaults */
    avipad->auds.blockalign = 1;
    avipad->auds.av_bps = 0;
    avipad->auds.bits_per_sample = 16;

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

      gst_structure_get_int (structure, "mpegversion", &mpegversion);
      switch (mpegversion) {
        case 1:{
          gint layer = 3;
          gboolean parsed = FALSE;

          gst_structure_get_int (structure, "layer", &layer);
          gst_structure_get_boolean (structure, "parsed", &parsed);
          switch (layer) {
            case 3:
              avipad->auds.format = GST_RIFF_WAVE_FORMAT_MPEGL3;
              break;
            case 1:
            case 2:
              avipad->auds.format = GST_RIFF_WAVE_FORMAT_MPEGL12;
              break;
          }
          if (parsed) {
            /* treat as VBR, should also cover CBR case;
             * setup hook to parse frame header and determine spf */
            avipad->parent.hook = gst_avi_mux_audsink_scan_mpeg_audio;
          } else {
            GST_WARNING_OBJECT (avimux, "unparsed MPEG audio input (?), "
                "doing CBR muxing");
          }
          break;
        }
        case 4:
        {
          GstBuffer *codec_data_buf = avipad->auds_codec_data;
          const gchar *stream_format;
          guint codec;
          guint8 data[2];

          stream_format = gst_structure_get_string (structure, "stream-format");
          if (stream_format) {
            if (strcmp (stream_format, "raw") != 0) {
              GST_WARNING_OBJECT (avimux, "AAC's stream format '%s' is not "
                  "supported, please use 'raw'", stream_format);
              break;
            }
          } else {
            GST_WARNING_OBJECT (avimux, "AAC's stream-format not specified, "
                "assuming 'raw'");
          }

          /* vbr case needs some special handling */
          if (!codec_data_buf || gst_buffer_get_size (codec_data_buf) < 2) {
            GST_WARNING_OBJECT (avimux, "no (valid) codec_data for AAC audio");
            break;
          }
          avipad->auds.format = GST_RIFF_WAVE_FORMAT_AAC;
          /* need to determine frame length */
          gst_buffer_extract (codec_data_buf, 0, data, 2);
          codec = GST_READ_UINT16_BE (data);
          avipad->parent.hdr.scale = (codec & 0x4) ? 960 : 1024;
          break;
        }
      }
    } else if (!strcmp (mimetype, "audio/x-vorbis")) {
      avipad->auds.format = GST_RIFF_WAVE_FORMAT_VORBIS3;
    } else if (!strcmp (mimetype, "audio/x-ac3")) {
      avipad->auds.format = GST_RIFF_WAVE_FORMAT_A52;
    } else if (!strcmp (mimetype, "audio/x-alaw")) {
      avipad->auds.format = GST_RIFF_WAVE_FORMAT_ALAW;
      avipad->auds.bits_per_sample = 8;
      avipad->auds.blockalign = avipad->auds.channels;
      avipad->auds.av_bps = avipad->auds.blockalign * avipad->auds.rate;
    } else if (!strcmp (mimetype, "audio/x-mulaw")) {
      avipad->auds.format = GST_RIFF_WAVE_FORMAT_MULAW;
      avipad->auds.bits_per_sample = 8;
      avipad->auds.blockalign = avipad->auds.channels;
      avipad->auds.av_bps = avipad->auds.blockalign * avipad->auds.rate;
    } else if (!strcmp (mimetype, "audio/x-wma")) {
      gint version;
      gint bitrate;
      gint block_align;

      if (gst_structure_get_int (structure, "wmaversion", &version)) {
        switch (version) {
          case 1:
            avipad->auds.format = GST_RIFF_WAVE_FORMAT_WMAV1;
            break;
          case 2:
            avipad->auds.format = GST_RIFF_WAVE_FORMAT_WMAV2;
            break;
          default:
            break;
        }
      }

      if (avipad->auds.format != 0) {
        if (gst_structure_get_int (structure, "block_align", &block_align)) {
          avipad->auds.blockalign = block_align;
        }
        if (gst_structure_get_int (structure, "bitrate", &bitrate)) {
          avipad->auds.av_bps = bitrate / 8;
        }
      }
    }
  }

  if (!avipad->auds.format)
    goto refuse_caps;

  avipad->parent.hdr.fcc_handler = avipad->auds.format;
  gst_avi_mux_audsink_set_fields (avimux, avipad);

  gst_object_unref (avimux);
  return TRUE;

refuse_caps:
  {
    GST_WARNING_OBJECT (avimux, "refused caps %" GST_PTR_FORMAT, vscaps);
    gst_object_unref (avimux);
    return FALSE;
  }
}


static GstPad *
gst_avi_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
  GstAviMux *avimux;
  GstPad *newpad;
  GstAviPad *avipad;
  GstElementClass *klass;
  gchar *name = NULL;
  const gchar *pad_name = NULL;
  gint pad_id;

  g_return_val_if_fail (templ != NULL, NULL);

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

  g_return_val_if_fail (GST_IS_AVI_MUX (element), NULL);
  avimux = GST_AVI_MUX (element);

  if (!avimux->write_header)
    goto too_late;

  klass = GST_ELEMENT_GET_CLASS (element);

  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", avimux->audio_pads++);
      pad_name = name;
    }

    /* init pad specific data */
    avipad = g_malloc0 (sizeof (GstAviAudioPad));
    avipad->is_video = FALSE;
    avipad->hdr.type = GST_MAKE_FOURCC ('a', 'u', 'd', 's');
    /* audio goes last */
    avimux->sinkpads = g_slist_append (avimux->sinkpads, avipad);
  } else if (templ == gst_element_class_get_pad_template (klass, "video_%u")) {
    /* though streams are pretty generic and relatively self-contained,
     * some video info goes in a single avi header -and therefore mux struct-
     * so video restricted to one stream */
    if (avimux->video_pads > 0)
      goto too_many_video_pads;

    /* setup pad */
    pad_name = "video_0";
    avimux->video_pads++;

    /* init pad specific data */
    avipad = g_malloc0 (sizeof (GstAviVideoPad));
    avipad->is_video = TRUE;
    avipad->hdr.type = GST_MAKE_FOURCC ('v', 'i', 'd', 's');
    /* video goes first */
    avimux->sinkpads = g_slist_prepend (avimux->sinkpads, avipad);
  } else
    goto wrong_template;

  newpad = gst_pad_new_from_template (templ, pad_name);

  g_free (name);

  avipad->collect = gst_collect_pads_add_pad (avimux->collect,
      newpad, sizeof (GstAviCollectData), NULL, TRUE);
  ((GstAviCollectData *) (avipad->collect))->avipad = avipad;

  if (!gst_element_add_pad (element, newpad))
    goto pad_add_failed;

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

  return newpad;

  /* ERRORS */
wrong_direction:
  {
    g_warning ("avimux: request pad that is not a SINK pad\n");
    return NULL;
  }
too_late:
  {
    g_warning ("avimux: request pad cannot be added after streaming started\n");
    return NULL;
  }
wrong_template:
  {
    g_warning ("avimux: this is not our template!\n");
    return NULL;
  }
too_many_video_pads:
  {
    GST_WARNING_OBJECT (avimux, "Can only have one video stream");
    return NULL;
  }
pad_add_failed:
  {
    GST_WARNING_OBJECT (avimux, "Adding the new pad '%s' failed", pad_name);
    gst_object_unref (newpad);
    return NULL;
  }
}

static void
gst_avi_mux_release_pad (GstElement * element, GstPad * pad)
{
  GstAviMux *avimux = GST_AVI_MUX (element);
  GSList *node;

  node = avimux->sinkpads;
  while (node) {
    GstAviPad *avipad = (GstAviPad *) node->data;

    if (avipad->collect->pad == pad) {
      /* pad count should not be adjusted,
       * as it also represent number of streams present */
      avipad->collect = NULL;
      GST_DEBUG_OBJECT (avimux, "removed pad '%s'", GST_PAD_NAME (pad));
      gst_collect_pads_remove_pad (avimux->collect, pad);
      gst_element_remove_pad (element, pad);
      /* if not started yet, we can remove any sign this pad ever existed */
      /* in this case _start will take care of the real pad count */
      if (avimux->write_header) {
        avimux->sinkpads = g_slist_remove (avimux->sinkpads, avipad);
        gst_avi_mux_pad_reset (avipad, TRUE);
        g_free (avipad);
      }
      return;
    }

    node = node->next;
  }

  g_warning ("Unknown pad %s", GST_PAD_NAME (pad));
}

static inline guint
gst_avi_mux_start_chunk (GstByteWriter * bw, const gchar * tag, guint32 fourcc)
{
  guint chunk_offset;
  gboolean hdl = TRUE;

  if (tag)
    hdl &= gst_byte_writer_put_data (bw, (const guint8 *) tag, 4);
  else
    hdl &= gst_byte_writer_put_uint32_le (bw, fourcc);

  chunk_offset = gst_byte_writer_get_pos (bw);
  /* real chunk size comes later */
  hdl &= gst_byte_writer_put_uint32_le (bw, 0);

  return chunk_offset;
}

static inline void
gst_avi_mux_end_chunk (GstByteWriter * bw, guint chunk_offset)
{
  guint size;
  gboolean hdl = TRUE;

  size = gst_byte_writer_get_pos (bw);

  gst_byte_writer_set_pos (bw, chunk_offset);
  hdl &= gst_byte_writer_put_uint32_le (bw, size - chunk_offset - 4);
  gst_byte_writer_set_pos (bw, size);

  /* arrange for even padding */
  if (size & 1)
    hdl &= gst_byte_writer_put_uint8 (bw, 0);
}

/* maybe some of these functions should be moved to riff.h? */

static void
gst_avi_mux_write_tag (const GstTagList * list, const gchar * tag,
    gpointer data)
{
  const struct
  {
    guint32 fcc;
    const gchar *tag;
  } rifftags[] = {
    {
    GST_RIFF_INFO_IARL, GST_TAG_LOCATION}, {
    GST_RIFF_INFO_IART, GST_TAG_ARTIST}, {
    GST_RIFF_INFO_ICMT, GST_TAG_COMMENT}, {
    GST_RIFF_INFO_ICOP, GST_TAG_COPYRIGHT}, {
    GST_RIFF_INFO_ICRD, GST_TAG_DATE}, {
    GST_RIFF_INFO_IGNR, GST_TAG_GENRE}, {
    GST_RIFF_INFO_IKEY, GST_TAG_KEYWORDS}, {
    GST_RIFF_INFO_INAM, GST_TAG_TITLE}, {
    GST_RIFF_INFO_ISFT, GST_TAG_ENCODER}, {
    GST_RIFF_INFO_ISRC, GST_TAG_ISRC}, {
    0, NULL}
  };
  gint n;
  gchar *str = NULL;
  GstByteWriter *bw = data;
  guint chunk;

  for (n = 0; rifftags[n].fcc != 0; n++) {
    if (!strcmp (rifftags[n].tag, tag)) {
      if (rifftags[n].fcc == GST_RIFF_INFO_ICRD) {
        GDate *date;
        /* special case for the date tag */
        if (gst_tag_list_get_date (list, tag, &date)) {
          str =
              g_strdup_printf ("%04d:%02d:%02d", g_date_get_year (date),
              g_date_get_month (date), g_date_get_day (date));
          g_date_free (date);
        }
      } else {
        gst_tag_list_get_string (list, tag, &str);
      }
      if (str) {
        chunk = gst_avi_mux_start_chunk (bw, NULL, rifftags[n].fcc);
        gst_byte_writer_put_string (bw, str);
        gst_avi_mux_end_chunk (bw, chunk);
        g_free (str);
        str = NULL;
        break;
      }
    }
  }
}

static GstBuffer *
gst_avi_mux_riff_get_avi_header (GstAviMux * avimux)
{
  const GstTagList *tags;
  GstBuffer *buffer = NULL;
  gint size = 0;
  GstByteWriter bw;
  GSList *node;
  guint avih, riff, hdrl;
  GstMapInfo map;
  gboolean hdl = TRUE;

  GST_DEBUG_OBJECT (avimux, "creating avi header, data_size %u, idx_size %u",
      avimux->data_size, avimux->idx_size);

  if (avimux->tags_snap)
    tags = avimux->tags_snap;
  else {
    /* need to make snapshot of current state of tags to ensure the same set
     * is used next time around during header rewrite at the end */
    tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (avimux));
    if (tags)
      tags = avimux->tags_snap = gst_tag_list_copy (tags);
  }

  gst_byte_writer_init_with_size (&bw, 1024, FALSE);

  /* avi header metadata */
  riff = gst_avi_mux_start_chunk (&bw, "RIFF", 0);
  hdl &= gst_byte_writer_put_data (&bw, (guint8 *) "AVI ", 4);
  hdrl = gst_avi_mux_start_chunk (&bw, "LIST", 0);
  hdl &= gst_byte_writer_put_data (&bw, (guint8 *) "hdrl", 4);

  avih = gst_avi_mux_start_chunk (&bw, "avih", 0);
  /* the AVI header itself */
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.us_frame);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.max_bps);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.pad_gran);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.flags);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.tot_frames);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.init_frames);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.streams);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.bufsize);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.width);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.height);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.scale);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.rate);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.start);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->avi_hdr.length);
  gst_avi_mux_end_chunk (&bw, avih);

  /* stream data */
  node = avimux->sinkpads;
  while (node) {
    GstAviPad *avipad = (GstAviPad *) node->data;
    GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;
    GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;
    gint codec_size = 0;
    guint strh, strl, strf, indx;

    /* stream list metadata */
    strl = gst_avi_mux_start_chunk (&bw, "LIST", 0);
    hdl &= gst_byte_writer_put_data (&bw, (guint8 *) "strl", 4);

    /* generic header */
    strh = gst_avi_mux_start_chunk (&bw, "strh", 0);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.type);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.fcc_handler);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.flags);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.priority);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.init_frames);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.scale);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.rate);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.start);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.length);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.bufsize);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.quality);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->hdr.samplesize);
    hdl &= gst_byte_writer_put_uint16_le (&bw, 0);
    hdl &= gst_byte_writer_put_uint16_le (&bw, 0);
    hdl &= gst_byte_writer_put_uint16_le (&bw, 0);
    hdl &= gst_byte_writer_put_uint16_le (&bw, 0);
    gst_avi_mux_end_chunk (&bw, strh);

    if (avipad->is_video) {
      codec_size = vidpad->vids_codec_data ?
          gst_buffer_get_size (vidpad->vids_codec_data) : 0;
      /* the video header */
      strf = gst_avi_mux_start_chunk (&bw, "strf", 0);
      /* the actual header */
      hdl &=
          gst_byte_writer_put_uint32_le (&bw, vidpad->vids.size + codec_size);
      hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vids.width);
      hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vids.height);
      hdl &= gst_byte_writer_put_uint16_le (&bw, vidpad->vids.planes);
      hdl &= gst_byte_writer_put_uint16_le (&bw, vidpad->vids.bit_cnt);
      hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vids.compression);
      hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vids.image_size);
      hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vids.xpels_meter);
      hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vids.ypels_meter);
      hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vids.num_colors);
      hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vids.imp_colors);
      if (vidpad->vids_codec_data) {
        gst_buffer_map (vidpad->vids_codec_data, &map, GST_MAP_READ);
        hdl &= gst_byte_writer_put_data (&bw, map.data, map.size);
        gst_buffer_unmap (vidpad->vids_codec_data, &map);
      }
      gst_avi_mux_end_chunk (&bw, strf);

      /* add video property data, mainly for aspect ratio, if any */
      if (vidpad->vprp.aspect) {
        gint f;
        guint vprp;

        /* let's be on the safe side */
        vidpad->vprp.fields = MIN (vidpad->vprp.fields,
            GST_RIFF_VPRP_VIDEO_FIELDS);
        /* the vprp header */
        vprp = gst_avi_mux_start_chunk (&bw, "vprp", 0);
        /* the actual data */
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.format_token);
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.standard);
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.vert_rate);
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.hor_t_total);
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.vert_lines);
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.aspect);
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.width);
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.height);
        hdl &= gst_byte_writer_put_uint32_le (&bw, vidpad->vprp.fields);

        for (f = 0; f < vidpad->vprp.fields; ++f) {
          gst_riff_vprp_video_field_desc *fd;

          fd = &(vidpad->vprp.field_info[f]);
          hdl &= gst_byte_writer_put_uint32_le (&bw, fd->compressed_bm_height);
          hdl &= gst_byte_writer_put_uint32_le (&bw, fd->compressed_bm_width);
          hdl &= gst_byte_writer_put_uint32_le (&bw, fd->valid_bm_height);
          hdl &= gst_byte_writer_put_uint32_le (&bw, fd->valid_bm_width);
          hdl &= gst_byte_writer_put_uint32_le (&bw, fd->valid_bm_x_offset);
          hdl &= gst_byte_writer_put_uint32_le (&bw, fd->valid_bm_y_offset);
          hdl &= gst_byte_writer_put_uint32_le (&bw, fd->video_x_t_offset);
          hdl &= gst_byte_writer_put_uint32_le (&bw, fd->video_y_start);
        }
        gst_avi_mux_end_chunk (&bw, vprp);
      }
    } else {
      codec_size = audpad->auds_codec_data ?
          gst_buffer_get_size (audpad->auds_codec_data) : 0;
      /* the audio header */
      strf = gst_avi_mux_start_chunk (&bw, "strf", 0);
      /* the actual header */
      hdl &= gst_byte_writer_put_uint16_le (&bw, audpad->auds.format);
      hdl &= gst_byte_writer_put_uint16_le (&bw, audpad->auds.channels);
      hdl &= gst_byte_writer_put_uint32_le (&bw, audpad->auds.rate);
      hdl &= gst_byte_writer_put_uint32_le (&bw, audpad->auds.av_bps);
      hdl &= gst_byte_writer_put_uint16_le (&bw, audpad->auds.blockalign);
      hdl &= gst_byte_writer_put_uint16_le (&bw, audpad->auds.bits_per_sample);
      hdl &= gst_byte_writer_put_uint16_le (&bw, codec_size);
      if (audpad->auds_codec_data) {
        gst_buffer_map (audpad->auds_codec_data, &map, GST_MAP_READ);
        hdl &= gst_byte_writer_put_data (&bw, map.data, map.size);
        gst_buffer_unmap (audpad->auds_codec_data, &map);
      }
      gst_avi_mux_end_chunk (&bw, strf);
    }

    /* odml superindex chunk */
    if (avipad->idx_index > 0)
      indx = gst_avi_mux_start_chunk (&bw, "indx", 0);
    else
      indx = gst_avi_mux_start_chunk (&bw, "JUNK", 0);
    hdl &= gst_byte_writer_put_uint16_le (&bw, 4);      /* bytes per entry */
    hdl &= gst_byte_writer_put_uint8 (&bw, 0);  /* index subtype */
    hdl &= gst_byte_writer_put_uint8 (&bw, GST_AVI_INDEX_OF_INDEXES);   /* index type */
    hdl &= gst_byte_writer_put_uint32_le (&bw, avipad->idx_index);      /* entries in use */
    hdl &= gst_byte_writer_put_data (&bw, (guint8 *) avipad->tag, 4);   /* stream id */
    hdl &= gst_byte_writer_put_uint32_le (&bw, 0);      /* reserved */
    hdl &= gst_byte_writer_put_uint32_le (&bw, 0);      /* reserved */
    hdl &= gst_byte_writer_put_uint32_le (&bw, 0);      /* reserved */
    hdl &= gst_byte_writer_put_data (&bw, (guint8 *) avipad->idx,
        GST_AVI_SUPERINDEX_COUNT * sizeof (gst_avi_superindex_entry));
    gst_avi_mux_end_chunk (&bw, indx);

    /* end strl for this stream */
    gst_avi_mux_end_chunk (&bw, strl);

    node = node->next;
  }

  if (avimux->video_pads > 0) {
    guint odml, dmlh;
    /* odml header */
    odml = gst_avi_mux_start_chunk (&bw, "LIST", 0);
    hdl &= gst_byte_writer_put_data (&bw, (guint8 *) "odml", 4);
    dmlh = gst_avi_mux_start_chunk (&bw, "dmlh", 0);
    hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->total_frames);
    gst_avi_mux_end_chunk (&bw, dmlh);
    gst_avi_mux_end_chunk (&bw, odml);
  }

  /* end hdrl */
  gst_avi_mux_end_chunk (&bw, hdrl);

  /* tags */
  if (tags) {
    guint info;

    info = gst_avi_mux_start_chunk (&bw, "LIST", 0);
    hdl &= gst_byte_writer_put_data (&bw, (guint8 *) "INFO", 4);

    gst_tag_list_foreach (tags, gst_avi_mux_write_tag, &bw);
    if (info + 8 == gst_byte_writer_get_pos (&bw)) {
      /* no tags writen, remove the empty INFO LIST as it is useless
       * and prevents playback in vlc */
      gst_byte_writer_set_pos (&bw, info - 4);
    } else {
      gst_avi_mux_end_chunk (&bw, info);
    }
  }

  /* pop RIFF */
  gst_avi_mux_end_chunk (&bw, riff);

  /* avi data header */
  hdl &= gst_byte_writer_put_data (&bw, (guint8 *) "LIST", 4);
  hdl &= gst_byte_writer_put_uint32_le (&bw, avimux->data_size);
  hdl &= gst_byte_writer_put_data (&bw, (guint8 *) "movi", 4);

  if (!hdl)
    goto beach;

  /* now get the data */
  buffer = gst_byte_writer_reset_and_get_buffer (&bw);

  /* ... but RIFF includes more than just header */
  gst_buffer_map (buffer, &map, GST_MAP_READWRITE);
  size = GST_READ_UINT32_LE (map.data + 4);
  size += 8 + avimux->data_size + avimux->idx_size;
  GST_WRITE_UINT32_LE (map.data + 4, size);

  GST_MEMDUMP_OBJECT (avimux, "avi header", map.data, map.size);
  gst_buffer_unmap (buffer, &map);

beach:
  return buffer;
}

static GstBuffer *
gst_avi_mux_riff_get_avix_header (guint32 datax_size)
{
  GstBuffer *buffer;
  GstMapInfo map;

  buffer = gst_buffer_new_and_alloc (24);

  gst_buffer_map (buffer, &map, GST_MAP_WRITE);
  memcpy (map.data + 0, "RIFF", 4);
  GST_WRITE_UINT32_LE (map.data + 4, datax_size + 3 * 4);
  memcpy (map.data + 8, "AVIX", 4);
  memcpy (map.data + 12, "LIST", 4);
  GST_WRITE_UINT32_LE (map.data + 16, datax_size);
  memcpy (map.data + 20, "movi", 4);
  gst_buffer_unmap (buffer, &map);

  return buffer;
}

static inline GstBuffer *
gst_avi_mux_riff_get_header (GstAviPad * avipad, guint32 video_frame_size)
{
  GstBuffer *buffer;
  GstMapInfo map;

  buffer = gst_buffer_new_and_alloc (8);

  gst_buffer_map (buffer, &map, GST_MAP_WRITE);
  memcpy (map.data + 0, avipad->tag, 4);
  GST_WRITE_UINT32_LE (map.data + 4, video_frame_size);
  gst_buffer_unmap (buffer, &map);

  return buffer;
}

/* write an odml index chunk in the movi list */
static GstFlowReturn
gst_avi_mux_write_avix_index (GstAviMux * avimux, GstAviPad * avipad,
    gchar * code, gchar * chunk, gst_avi_superindex_entry * super_index,
    gint * super_index_count)
{
  GstFlowReturn res;
  GstBuffer *buffer;
  guint8 *data;
  gst_riff_index_entry *entry;
  gint i;
  guint32 size, entry_count;
  gboolean is_pcm = FALSE;
  guint32 pcm_samples = 0;
  GstMapInfo map;

  /* check if it is pcm */
  if (avipad && !avipad->is_video) {
    GstAviAudioPad *audiopad = (GstAviAudioPad *) avipad;
    if (audiopad->auds.format == GST_RIFF_WAVE_FORMAT_PCM) {
      pcm_samples = audiopad->samples;
      is_pcm = TRUE;
    }
  }

  /* allocate the maximum possible */
  buffer = gst_buffer_new_and_alloc (32 + 8 * avimux->idx_index);

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

  /* general index chunk info */
  memcpy (map.data + 0, chunk, 4);      /* chunk id */
  GST_WRITE_UINT32_LE (map.data + 4, 0);        /* chunk size; fill later */
  GST_WRITE_UINT16_LE (map.data + 8, 2);        /* index entry is 2 words */
  map.data[10] = 0;             /* index subtype */
  map.data[11] = GST_AVI_INDEX_OF_CHUNKS;       /* index type: AVI_INDEX_OF_CHUNKS */
  GST_WRITE_UINT32_LE (map.data + 12, 0);       /* entries in use; fill later */
  memcpy (map.data + 16, code, 4);      /* stream to which index refers */
  GST_WRITE_UINT64_LE (map.data + 20, avimux->avix_start);      /* base offset */
  GST_WRITE_UINT32_LE (map.data + 28, 0);       /* reserved */
  map.data += 32;

  /* now the actual index entries */
  i = avimux->idx_index;
  entry = avimux->idx;
  while (i > 0) {
    if (memcmp (&entry->id, code, 4) == 0) {
      /* enter relative offset to the data (!) */
      GST_WRITE_UINT32_LE (map.data, GUINT32_FROM_LE (entry->offset) + 8);
      /* msb is set if not (!) keyframe */
      GST_WRITE_UINT32_LE (map.data + 4, GUINT32_FROM_LE (entry->size)
          | (GUINT32_FROM_LE (entry->flags)
              & GST_RIFF_IF_KEYFRAME ? 0 : 1U << 31));
      map.data += 8;
    }
    i--;
    entry++;
  }

  /* ok, now we know the size and no of entries, fill in where needed */
  size = map.data - data;
  GST_WRITE_UINT32_LE (data + 4, size - 8);
  entry_count = (size - 32) / 8;
  GST_WRITE_UINT32_LE (data + 12, entry_count);
  gst_buffer_unmap (buffer, &map);
  gst_buffer_resize (buffer, 0, size);

  /* send */
  if ((res = gst_pad_push (avimux->srcpad, buffer)) != GST_FLOW_OK)
    return res;

  /* keep track of this in superindex (if room) ... */
  if (*super_index_count < GST_AVI_SUPERINDEX_COUNT) {
    i = *super_index_count;
    super_index[i].offset = GUINT64_TO_LE (avimux->total_data);
    super_index[i].size = GUINT32_TO_LE (size);
    if (is_pcm) {
      super_index[i].duration = GUINT32_TO_LE (pcm_samples);
    } else {
      super_index[i].duration = GUINT32_TO_LE (entry_count);
    }
    (*super_index_count)++;
  } else
    GST_WARNING_OBJECT (avimux, "No more room in superindex of stream %s",
        code);

  /* ... and in size */
  avimux->total_data += size;
  if (avimux->is_bigfile)
    avimux->datax_size += size;
  else
    avimux->data_size += size;

  return GST_FLOW_OK;
}

/* some other usable functions (thankyou xawtv ;-) ) */

static void
gst_avi_mux_add_index (GstAviMux * avimux, GstAviPad * avipad, guint32 flags,
    guint32 size)
{
  gchar *code = avipad->tag;
  if (avimux->idx_index == avimux->idx_count) {
    avimux->idx_count += 256;
    avimux->idx =
        g_realloc (avimux->idx,
        avimux->idx_count * sizeof (gst_riff_index_entry));
  }

  /* in case of pcm audio, we need to count the number of samples for
   * putting in the indx entries */
  if (!avipad->is_video) {
    GstAviAudioPad *audiopad = (GstAviAudioPad *) avipad;
    if (audiopad->auds.format == GST_RIFF_WAVE_FORMAT_PCM) {
      audiopad->samples += size / audiopad->auds.blockalign;
    }
  }

  memcpy (&(avimux->idx[avimux->idx_index].id), code, 4);
  avimux->idx[avimux->idx_index].flags = GUINT32_TO_LE (flags);
  avimux->idx[avimux->idx_index].offset = GUINT32_TO_LE (avimux->idx_offset);
  avimux->idx[avimux->idx_index].size = GUINT32_TO_LE (size);
  avimux->idx_index++;
}

static GstFlowReturn
gst_avi_mux_write_index (GstAviMux * avimux)
{
  GstFlowReturn res;
  GstBuffer *buffer;
  GstMapInfo map;
  guint8 *data;
  gsize size;

  buffer = gst_buffer_new_and_alloc (8);

  gst_buffer_map (buffer, &map, GST_MAP_WRITE);
  memcpy (map.data + 0, "idx1", 4);
  GST_WRITE_UINT32_LE (map.data + 4,
      avimux->idx_index * sizeof (gst_riff_index_entry));
  gst_buffer_unmap (buffer, &map);

  res = gst_pad_push (avimux->srcpad, buffer);
  if (res != GST_FLOW_OK)
    return res;

  buffer = gst_buffer_new ();

  size = avimux->idx_index * sizeof (gst_riff_index_entry);
  data = (guint8 *) avimux->idx;
  avimux->idx = NULL;           /* will be free()'ed by gst_buffer_unref() */

  gst_buffer_append_memory (buffer,
      gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));

  avimux->total_data += size + 8;

  res = gst_pad_push (avimux->srcpad, buffer);
  if (res != GST_FLOW_OK)
    return res;

  avimux->idx_size += avimux->idx_index * sizeof (gst_riff_index_entry) + 8;

  /* update header */
  avimux->avi_hdr.flags |= GST_RIFF_AVIH_HASINDEX;
  return GST_FLOW_OK;
}

static GstFlowReturn
gst_avi_mux_bigfile (GstAviMux * avimux, gboolean last)
{
  GstFlowReturn res = GST_FLOW_OK;
  GstBuffer *header;
  GSList *node;

  /* first some odml standard index chunks in the movi list */
  node = avimux->sinkpads;
  while (node) {
    GstAviPad *avipad = (GstAviPad *) node->data;

    node = node->next;

    res = gst_avi_mux_write_avix_index (avimux, avipad, avipad->tag,
        avipad->idx_tag, avipad->idx, &avipad->idx_index);
    if (res != GST_FLOW_OK)
      return res;
  }

  if (avimux->is_bigfile) {
    GstSegment segment;

    gst_segment_init (&segment, GST_FORMAT_BYTES);

    /* search back */
    segment.start = avimux->avix_start;
    segment.time = avimux->avix_start;
    gst_pad_push_event (avimux->srcpad, gst_event_new_segment (&segment));

    /* rewrite AVIX header */
    header = gst_avi_mux_riff_get_avix_header (avimux->datax_size);
    res = gst_pad_push (avimux->srcpad, header);

    /* go back to current location, at least try */
    segment.start = avimux->total_data;
    segment.time = avimux->total_data;
    gst_pad_push_event (avimux->srcpad, gst_event_new_segment (&segment));

    if (res != GST_FLOW_OK)
      return res;
  } else {                      /* write a standard index in the first riff chunk */
    res = gst_avi_mux_write_index (avimux);
    /* the index data/buffer is freed by pushing it */
    avimux->idx_count = 0;
    if (res != GST_FLOW_OK)
      return res;
  }

  avimux->avix_start = avimux->total_data;

  if (last)
    return res;

  avimux->is_bigfile = TRUE;
  avimux->numx_frames = 0;
  avimux->datax_size = 4;       /* movi tag */
  avimux->idx_index = 0;
  node = avimux->sinkpads;
  while (node) {
    GstAviPad *avipad = (GstAviPad *) node->data;
    node = node->next;
    if (!avipad->is_video) {
      GstAviAudioPad *audiopad = (GstAviAudioPad *) avipad;
      audiopad->samples = 0;
    }
  }

  header = gst_avi_mux_riff_get_avix_header (0);
  avimux->total_data += gst_buffer_get_size (header);
  /* avix_start is used as base offset for the odml index chunk */
  avimux->idx_offset = avimux->total_data - avimux->avix_start;

  return gst_pad_push (avimux->srcpad, header);
}

/* enough header blabla now, let's go on to actually writing the headers */

static GstFlowReturn
gst_avi_mux_start_file (GstAviMux * avimux)
{
  GstFlowReturn res;
  GstBuffer *header;
  GSList *node;
  GstCaps *caps;
  GstSegment segment;

  avimux->total_data = 0;
  avimux->total_frames = 0;
  avimux->data_size = 4;        /* movi tag */
  avimux->datax_size = 0;
  avimux->num_frames = 0;
  avimux->numx_frames = 0;
  avimux->avix_start = 0;

  avimux->idx_index = 0;
  avimux->idx_offset = 0;       /* see 10 lines below */
  avimux->idx_size = 0;
  avimux->idx_count = 0;
  avimux->idx = NULL;

  /* state */
  avimux->write_header = FALSE;
  avimux->restart = FALSE;

  /* init streams, see what we've got */
  node = avimux->sinkpads;
  avimux->audio_pads = avimux->video_pads = 0;
  while (node) {
    GstAviPad *avipad = (GstAviPad *) node->data;

    node = node->next;

    if (!avipad->is_video) {
      /* audio stream numbers must start at 1 iff there is a video stream 0;
       * request_pad inserts video pad at head of list, so this test suffices */
      if (avimux->video_pads)
        avimux->audio_pads++;
      avipad->tag = g_strdup_printf ("%02uwb", avimux->audio_pads);
      avipad->idx_tag = g_strdup_printf ("ix%02u", avimux->audio_pads);
      if (!avimux->video_pads)
        avimux->audio_pads++;
    } else {
      avipad->tag = g_strdup_printf ("%02udb", avimux->video_pads);
      avipad->idx_tag = g_strdup_printf ("ix%02u", avimux->video_pads++);
    }
  }

  /* stream-start (FIXME: create id based on input ids) */
  {
    gchar s_id[32];

    g_snprintf (s_id, sizeof (s_id), "avimux-%08x", g_random_int ());
    gst_pad_push_event (avimux->srcpad, gst_event_new_stream_start (s_id));
  }

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

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

  /* header */
  avimux->avi_hdr.streams = g_slist_length (avimux->sinkpads);
  avimux->is_bigfile = FALSE;

  header = gst_avi_mux_riff_get_avi_header (avimux);
  avimux->total_data += gst_buffer_get_size (header);

  res = gst_pad_push (avimux->srcpad, header);

  avimux->idx_offset = avimux->total_data;

  return res;
}

static GstFlowReturn
gst_avi_mux_stop_file (GstAviMux * avimux)
{
  GstFlowReturn res = GST_FLOW_OK;
  GstBuffer *header;
  GSList *node;
  GstSegment segment;

  /* if bigfile, rewrite header, else write indexes */
  /* don't bail out at once if error, still try to re-write header */
  if (avimux->video_pads > 0) {
    if (avimux->is_bigfile) {
      res = gst_avi_mux_bigfile (avimux, TRUE);
    } else {
      res = gst_avi_mux_write_index (avimux);
    }
  }

  /* we do our best to make it interleaved at least ... */
  if (avimux->audio_pads > 0 && avimux->video_pads > 0)
    avimux->avi_hdr.flags |= GST_RIFF_AVIH_ISINTERLEAVED;

  /* set rate and everything having to do with that */
  avimux->avi_hdr.max_bps = 0;
  node = avimux->sinkpads;
  while (node) {
    GstAviPad *avipad = (GstAviPad *) node->data;

    node = node->next;

    if (!avipad->is_video) {
      GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;

      /* calculate bps if needed */
      if (!audpad->auds.av_bps) {
        if (audpad->audio_time) {
          audpad->auds.av_bps =
              (GST_SECOND * audpad->audio_size) / audpad->audio_time;
          /* round bps to nearest multiple of 8;
           * which is much more likely to be the (cbr) bitrate in use;
           * which in turn results in better timestamp calculation on playback */
          audpad->auds.av_bps = GST_ROUND_UP_8 (audpad->auds.av_bps - 4);
        } else {
          GST_ELEMENT_WARNING (avimux, STREAM, MUX,
              (_("No or invalid input audio, AVI stream will be corrupt.")),
              (NULL));
          audpad->auds.av_bps = 0;
        }
      }
      /* housekeeping for vbr case */
      if (audpad->max_audio_chunk)
        audpad->auds.blockalign = audpad->max_audio_chunk;
      gst_avi_mux_audsink_set_fields (avimux, audpad);
      avimux->avi_hdr.max_bps += audpad->auds.av_bps;
      avipad->hdr.length = gst_util_uint64_scale (audpad->audio_time,
          avipad->hdr.rate, avipad->hdr.scale * GST_SECOND);
    } else {
      GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;

      avimux->avi_hdr.max_bps += ((vidpad->vids.bit_cnt + 7) / 8) *
          (1000000. / avimux->avi_hdr.us_frame) * vidpad->vids.image_size;
      avipad->hdr.length = avimux->total_frames;
    }
  }

  /* statistics/total_frames/... */
  avimux->avi_hdr.tot_frames = avimux->num_frames;

  /* seek and rewrite the header */
  gst_segment_init (&segment, GST_FORMAT_BYTES);
  gst_pad_push_event (avimux->srcpad, gst_event_new_segment (&segment));

  /* the first error survives */
  header = gst_avi_mux_riff_get_avi_header (avimux);
  if (res == GST_FLOW_OK)
    res = gst_pad_push (avimux->srcpad, header);
  else
    gst_pad_push (avimux->srcpad, header);

  segment.start = avimux->total_data;
  segment.time = avimux->total_data;
  gst_pad_push_event (avimux->srcpad, gst_event_new_segment (&segment));

  avimux->write_header = TRUE;

  return res;
}

static GstFlowReturn
gst_avi_mux_restart_file (GstAviMux * avimux)
{
  GstFlowReturn res;

  if ((res = gst_avi_mux_stop_file (avimux)) != GST_FLOW_OK)
    return res;

  gst_pad_push_event (avimux->srcpad, gst_event_new_eos ());

  return gst_avi_mux_start_file (avimux);
}

/* handle events (search) */
static gboolean
gst_avi_mux_handle_event (GstCollectPads * pads, GstCollectData * data,
    GstEvent * event, gpointer user_data)
{
  GstAviMux *avimux;
  gboolean ret = TRUE;

  avimux = GST_AVI_MUX (user_data);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;
      GstAviCollectData *collect_pad;
      GstAviVideoPad *avipad;

      gst_event_parse_caps (event, &caps);

      /* find stream data */
      collect_pad = (GstAviCollectData *) data;
      g_assert (collect_pad);
      avipad = (GstAviVideoPad *) collect_pad->avipad;
      g_assert (avipad);

      if (avipad->parent.is_video) {
        ret = gst_avi_mux_vidsink_set_caps (data->pad, caps);
      } else {
        ret = gst_avi_mux_audsink_set_caps (data->pad, caps);
      }
      gst_event_unref (event);
      event = NULL;
      break;
    }
    case GST_EVENT_TAG:{
      GstTagList *list;
      GstTagSetter *setter = GST_TAG_SETTER (avimux);
      const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);

      gst_event_parse_tag (event, &list);
      gst_tag_setter_merge_tags (setter, list, mode);
      gst_event_unref (event);
      event = NULL;
      break;
    }
    default:
      break;
  }

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

  return ret;
}

/* send extra 'padding' data */
static GstFlowReturn
gst_avi_mux_send_pad_data (GstAviMux * avimux, gulong num_bytes)
{
  GstBuffer *buffer;

  buffer = gst_buffer_new_and_alloc (num_bytes);
  gst_buffer_memset (buffer, 0, 0, num_bytes);

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

#define gst_avi_mux_is_uncompressed(fourcc)		\
  (fourcc == GST_RIFF_DIB ||				\
   fourcc == GST_RIFF_rgb ||				\
   fourcc == GST_RIFF_RGB || fourcc == GST_RIFF_RAW)

/*
 * Helper for gst_avi_demux_invert()
 */
static inline void
swap_line (guint8 * d1, guint8 * d2, guint8 * tmp, gint bytes)
{
  memcpy (tmp, d1, bytes);
  memcpy (d1, d2, bytes);
  memcpy (d2, tmp, bytes);
}

/*
 * Invert DIB buffers... Takes existing buffer and
 * returns either the buffer or a new one (with old
 * one dereferenced).
 * FFMPEG does this by simply negating the height in the header. Should we?
 * FIXME: can't we preallocate tmp? and remember stride, bpp?
 *        this could be done in do_one_buffer() I suppose
 */
static GstBuffer *
gst_avi_mux_invert (GstAviPad * avipad, GstBuffer * buf)
{
  gint y, w, h;
  gint bpp, stride;
  guint8 *tmp = NULL;
  GstMapInfo map;

  GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;

  h = vidpad->vids.height;
  w = vidpad->vids.width;
  bpp = vidpad->vids.bit_cnt ? vidpad->vids.bit_cnt : 8;
  stride = GST_ROUND_UP_4 (w * (bpp / 8));

  buf = gst_buffer_make_writable (buf);

  gst_buffer_map (buf, &map, GST_MAP_READWRITE);
  if (map.size < (stride * h)) {
    GST_WARNING ("Buffer is smaller than reported Width x Height x Depth");
    gst_buffer_unmap (buf, &map);
    return buf;
  }

  tmp = g_malloc (stride);

  for (y = 0; y < h / 2; y++) {
    swap_line (map.data + stride * y, map.data + stride * (h - 1 - y), tmp,
        stride);
  }

  g_free (tmp);

  gst_buffer_unmap (buf, &map);

  return buf;
}

/* do buffer */
static GstFlowReturn
gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
{
  GstFlowReturn res;
  GstBuffer *data, *header;
  gulong total_size, pad_bytes = 0;
  guint flags;
  gsize datasize;
  GstClockTime time;

  data = gst_collect_pads_pop (avimux->collect, avipad->collect);
  /* arrange downstream running time */
  time = gst_segment_to_running_time (&avipad->collect->segment,
      GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (data));
  if (time != GST_BUFFER_TIMESTAMP (data)) {
    data = gst_buffer_make_writable (data);
    GST_BUFFER_TIMESTAMP (data) = time;
  }

  /* Prepend a special buffer to the first one for some formats */
  if (avipad->is_video) {
    GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;

    if (vidpad->prepend_buffer) {
      /* Keep a reference to data until we copy the timestamps, then release it */
      GstBuffer *newdata =
          gst_buffer_append (vidpad->prepend_buffer, gst_buffer_ref (data));
      gst_buffer_copy_into (newdata, data, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
      gst_buffer_unref (data);

      data = newdata;
      vidpad->prepend_buffer = NULL;
    }

    /* DIB buffers are stored topdown (I don't know why) */
    if (gst_avi_mux_is_uncompressed (avipad->hdr.fcc_handler)) {
      data = gst_avi_mux_invert (avipad, data);
    }
  }

  if (avimux->restart) {
    if ((res = gst_avi_mux_restart_file (avimux)) != GST_FLOW_OK)
      goto done;
  }

  datasize = gst_buffer_get_size (data);

  /* need to restart or start a next avix chunk ? */
  if ((avimux->is_bigfile ? avimux->datax_size : avimux->data_size) +
      datasize > GST_AVI_MAX_SIZE) {
    if (avimux->enable_large_avi) {
      if ((res = gst_avi_mux_bigfile (avimux, FALSE)) != GST_FLOW_OK)
        goto done;
    } else {
      if ((res = gst_avi_mux_restart_file (avimux)) != GST_FLOW_OK)
        goto done;
    }
  }

  /* get header and record some stats */
  if (datasize & 1) {
    pad_bytes = 2 - (datasize & 1);
  }
  header = gst_avi_mux_riff_get_header (avipad, datasize);
  total_size = gst_buffer_get_size (header) + datasize + pad_bytes;

  if (avimux->is_bigfile) {
    avimux->datax_size += total_size;
  } else {
    avimux->data_size += total_size;
  }

  if (G_UNLIKELY (avipad->hook)) {
    gst_buffer_ref (data);
    avipad->hook (avimux, avipad, data);
  }

  /* the suggested buffer size is the max frame size */
  if (avipad->hdr.bufsize < datasize)
    avipad->hdr.bufsize = datasize;

  if (avipad->is_video) {
    avimux->total_frames++;

    if (avimux->is_bigfile) {
      avimux->numx_frames++;
    } else {
      avimux->num_frames++;
    }

    flags = 0x02;
    if (!GST_BUFFER_FLAG_IS_SET (data, GST_BUFFER_FLAG_DELTA_UNIT))
      flags |= 0x10;
  } else {
    GstAviAudioPad *audpad = (GstAviAudioPad *) avipad;

    flags = 0;
    audpad->audio_size += datasize;
    audpad->audio_time += GST_BUFFER_DURATION (data);
    if (audpad->max_audio_chunk && datasize > audpad->max_audio_chunk)
      audpad->max_audio_chunk = datasize;
  }

  gst_avi_mux_add_index (avimux, avipad, flags, datasize);

  /* send buffers */
  GST_LOG_OBJECT (avimux, "pushing buffers: head, data");

  if ((res = gst_pad_push (avimux->srcpad, header)) != GST_FLOW_OK)
    goto done;

  gst_buffer_ref (data);
  if ((res = gst_pad_push (avimux->srcpad, data)) != GST_FLOW_OK)
    goto done;

  if (pad_bytes) {
    if ((res = gst_avi_mux_send_pad_data (avimux, pad_bytes)) != GST_FLOW_OK)
      goto done;
  }

  /* if any push above fails, we're in trouble with file consistency anyway */
  avimux->total_data += total_size;
  avimux->idx_offset += total_size;

done:
  gst_buffer_unref (data);
  return res;
}

/* pick the oldest buffer from the pads and push it */
static GstFlowReturn
gst_avi_mux_do_one_buffer (GstAviMux * avimux)
{
  GstAviPad *avipad, *best_pad;
  GSList *node;
  GstBuffer *buffer;
  GstClockTime time, best_time, delay;

  node = avimux->sinkpads;
  best_pad = NULL;
  best_time = GST_CLOCK_TIME_NONE;
  for (; node; node = node->next) {
    avipad = (GstAviPad *) node->data;

    if (!avipad->collect)
      continue;

    buffer = gst_collect_pads_peek (avimux->collect, avipad->collect);
    if (!buffer)
      continue;
    time = GST_BUFFER_TIMESTAMP (buffer);
    gst_buffer_unref (buffer);

    /* invalid should pass */
    if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (time))) {
      time = gst_segment_to_running_time (&avipad->collect->segment,
          GST_FORMAT_TIME, time);
      if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time))) {
        GST_DEBUG_OBJECT (avimux, "clipping buffer on pad %s outside segment",
            GST_PAD_NAME (avipad->collect->pad));
        buffer = gst_collect_pads_pop (avimux->collect, avipad->collect);
        gst_buffer_unref (buffer);
        return GST_FLOW_OK;
      }
    }

    delay = avipad->is_video ? GST_SECOND / 2 : 0;

    /* invalid timestamp buffers pass first,
     * these are probably initialization buffers */
    if (best_pad == NULL || !GST_CLOCK_TIME_IS_VALID (time)
        || (GST_CLOCK_TIME_IS_VALID (best_time) && time + delay < best_time)) {
      best_pad = avipad;
      best_time = time + delay;
    }
  }

  if (best_pad) {
    GST_LOG_OBJECT (avimux, "selected pad %s with time %" GST_TIME_FORMAT,
        GST_PAD_NAME (best_pad->collect->pad), GST_TIME_ARGS (best_time));

    return gst_avi_mux_do_buffer (avimux, best_pad);
  } else {
    /* simply finish off the file and send EOS */
    gst_avi_mux_stop_file (avimux);
    gst_pad_push_event (avimux->srcpad, gst_event_new_eos ());
    return GST_FLOW_EOS;
  }

}

static GstFlowReturn
gst_avi_mux_collect_pads (GstCollectPads * pads, GstAviMux * avimux)
{
  GstFlowReturn res;

  if (G_UNLIKELY (avimux->write_header)) {
    if ((res = gst_avi_mux_start_file (avimux)) != GST_FLOW_OK)
      return res;
  }

  return gst_avi_mux_do_one_buffer (avimux);
}


static void
gst_avi_mux_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstAviMux *avimux;

  avimux = GST_AVI_MUX (object);

  switch (prop_id) {
    case ARG_BIGFILE:
      g_value_set_boolean (value, avimux->enable_large_avi);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_avi_mux_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstAviMux *avimux;

  avimux = GST_AVI_MUX (object);

  switch (prop_id) {
    case ARG_BIGFILE:
      avimux->enable_large_avi = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_avi_mux_change_state (GstElement * element, GstStateChange transition)
{
  GstAviMux *avimux;
  GstStateChangeReturn ret;

  avimux = GST_AVI_MUX (element);

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

done:
  return ret;
}
