/* GStreamer
 * Copyright (C) <2007> Julien Moutte <julien@moutte.net>
 *
 * 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.
 */

/**
 * SECTION:element-flvdemux
 *
 * flvdemux demuxes an FLV file into the different contained streams.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v filesrc location=/path/to/flv ! flvdemux ! audioconvert ! autoaudiosink
 * ]| This pipeline demuxes an FLV file and outputs the contained raw audio streams.
 * </refsect2>
 */

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

#include "gstflvdemux.h"
#include "gstflvmux.h"

#include <string.h>
#include <gst/base/gstbytereader.h>
#include <gst/base/gstbytewriter.h>
#include <gst/pbutils/descriptions.h>
#include <gst/pbutils/pbutils.h>
#include <gst/audio/audio.h>

/* FIXME: don't rely on own GstIndex */
#include "gstindex.c"
#include "gstmemindex.c"
#define GST_ASSOCIATION_FLAG_NONE GST_INDEX_ASSOCIATION_FLAG_NONE
#define GST_ASSOCIATION_FLAG_KEY_UNIT GST_INDEX_ASSOCIATION_FLAG_KEY_UNIT
#define GST_ASSOCIATION_FLAG_DELTA_UNIT GST_INDEX_ASSOCIATION_FLAG_DELTA_UNIT

static GstStaticPadTemplate flv_sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-flv")
    );

static GstStaticPadTemplate audio_src_template =
    GST_STATIC_PAD_TEMPLATE ("audio",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS
    ("audio/x-adpcm, layout = (string) swf, channels = (int) { 1, 2 }, rate = (int) { 5512, 11025, 22050, 44100 }; "
        "audio/mpeg, mpegversion = (int) 1, layer = (int) 3, channels = (int) { 1, 2 }, rate = (int) { 5512, 8000, 11025, 22050, 44100 }, parsed = (boolean) TRUE; "
        "audio/mpeg, mpegversion = (int) 4, stream-format = (string) raw, framed = (boolean) TRUE; "
        "audio/x-nellymoser, channels = (int) { 1, 2 }, rate = (int) { 5512, 8000, 11025, 16000, 22050, 44100 }; "
        "audio/x-raw, format = (string) { U8, S16LE }, layout = (string) interleaved, channels = (int) { 1, 2 }, rate = (int) { 5512, 11025, 22050, 44100 }; "
        "audio/x-alaw, channels = (int) { 1, 2 }, rate = (int) { 5512, 11025, 22050, 44100 }; "
        "audio/x-mulaw, channels = (int) { 1, 2 }, rate = (int) { 5512, 11025, 22050, 44100 }; "
        "audio/x-speex, channels = (int) { 1, 2 }, rate = (int) { 5512, 11025, 22050, 44100 };")
    );

static GstStaticPadTemplate video_src_template =
    GST_STATIC_PAD_TEMPLATE ("video",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("video/x-flash-video, flvversion=(int) 1; "
        "video/x-flash-screen; "
        "video/x-vp6-flash; " "video/x-vp6-alpha; "
        "video/x-h264, stream-format=avc;")
    );

GST_DEBUG_CATEGORY_STATIC (flvdemux_debug);
#define GST_CAT_DEFAULT flvdemux_debug

#define gst_flv_demux_parent_class parent_class
G_DEFINE_TYPE (GstFlvDemux, gst_flv_demux, GST_TYPE_ELEMENT);

/* 9 bytes of header + 4 bytes of first previous tag size */
#define FLV_HEADER_SIZE 13
/* 1 byte of tag type + 3 bytes of tag data size */
#define FLV_TAG_TYPE_SIZE 4

/* two seconds - consider pts are resynced to another base if this different */
#define RESYNC_THRESHOLD 2000

static gboolean flv_demux_handle_seek_push (GstFlvDemux * demux,
    GstEvent * event);
static gboolean gst_flv_demux_handle_seek_pull (GstFlvDemux * demux,
    GstEvent * event, gboolean seeking);

static gboolean gst_flv_demux_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_flv_demux_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static GstIndex *gst_flv_demux_get_index (GstElement * element);

static void
gst_flv_demux_parse_and_add_index_entry (GstFlvDemux * demux, GstClockTime ts,
    guint64 pos, gboolean keyframe)
{
  GstIndexAssociation associations[2];
  GstIndex *index;
  GstIndexEntry *entry;

  GST_LOG_OBJECT (demux,
      "adding key=%d association %" GST_TIME_FORMAT "-> %" G_GUINT64_FORMAT,
      keyframe, GST_TIME_ARGS (ts), pos);

  /* if upstream is not seekable there is no point in building an index */
  if (!demux->upstream_seekable)
    return;

  index = gst_flv_demux_get_index (GST_ELEMENT (demux));

  if (!index)
    return;

  /* entry may already have been added before, avoid adding indefinitely */
  entry = gst_index_get_assoc_entry (index, demux->index_id,
      GST_INDEX_LOOKUP_EXACT, GST_ASSOCIATION_FLAG_NONE, GST_FORMAT_BYTES, pos);

  if (entry) {
#ifndef GST_DISABLE_GST_DEBUG
    gint64 time = 0;
    gboolean key;

    gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time);
    key = ! !(GST_INDEX_ASSOC_FLAGS (entry) & GST_ASSOCIATION_FLAG_KEY_UNIT);
    GST_LOG_OBJECT (demux, "position already mapped to time %" GST_TIME_FORMAT
        ", keyframe %d", GST_TIME_ARGS (time), key);
    /* there is not really a way to delete the existing one */
    if (time != ts || key != ! !keyframe)
      GST_DEBUG_OBJECT (demux, "metadata mismatch");
#endif
    gst_object_unref (index);
    return;
  }

  associations[0].format = GST_FORMAT_TIME;
  associations[0].value = ts;
  associations[1].format = GST_FORMAT_BYTES;
  associations[1].value = pos;

  gst_index_add_associationv (index, demux->index_id,
      (keyframe) ? GST_ASSOCIATION_FLAG_KEY_UNIT :
      GST_ASSOCIATION_FLAG_DELTA_UNIT, 2,
      (const GstIndexAssociation *) &associations);

  if (pos > demux->index_max_pos)
    demux->index_max_pos = pos;
  if (ts > demux->index_max_time)
    demux->index_max_time = ts;

  gst_object_unref (index);
}

static gchar *
FLV_GET_STRING (GstByteReader * reader)
{
  guint16 string_size = 0;
  gchar *string = NULL;
  const guint8 *str = NULL;

  g_return_val_if_fail (reader != NULL, NULL);

  if (G_UNLIKELY (!gst_byte_reader_get_uint16_be (reader, &string_size)))
    return NULL;

  if (G_UNLIKELY (string_size > gst_byte_reader_get_remaining (reader)))
    return NULL;

  string = g_try_malloc0 (string_size + 1);
  if (G_UNLIKELY (!string)) {
    return NULL;
  }

  if (G_UNLIKELY (!gst_byte_reader_get_data (reader, string_size, &str))) {
    g_free (string);
    return NULL;
  }

  memcpy (string, str, string_size);
  if (!g_utf8_validate (string, string_size, NULL)) {
    g_free (string);
    return NULL;
  }

  return string;
}

static void
gst_flv_demux_check_seekability (GstFlvDemux * demux)
{
  GstQuery *query;
  gint64 start = -1, stop = -1;

  demux->upstream_seekable = FALSE;

  query = gst_query_new_seeking (GST_FORMAT_BYTES);
  if (!gst_pad_peer_query (demux->sinkpad, query)) {
    GST_DEBUG_OBJECT (demux, "seeking query failed");
    gst_query_unref (query);
    return;
  }

  gst_query_parse_seeking (query, NULL, &demux->upstream_seekable,
      &start, &stop);

  gst_query_unref (query);

  /* try harder to query upstream size if we didn't get it the first time */
  if (demux->upstream_seekable && stop == -1) {
    GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
    gst_pad_peer_query_duration (demux->sinkpad, GST_FORMAT_BYTES, &stop);
  }

  /* if upstream doesn't know the size, it's likely that it's not seekable in
   * practice even if it technically may be seekable */
  if (demux->upstream_seekable && (start != 0 || stop <= start)) {
    GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
    demux->upstream_seekable = FALSE;
  }

  GST_DEBUG_OBJECT (demux, "upstream seekable: %d", demux->upstream_seekable);
}

static void
parse_flv_demux_parse_date_string (GDate * date, const gchar * s)
{
  g_date_set_parse (date, s);
  if (g_date_valid (date))
    return;

  /* "Fri Oct 15 15:13:16 2004" needs to be parsed */
  {
    static const gchar *months[] = {
      "Jan", "Feb", "Mar", "Apr",
      "May", "Jun", "Jul", "Aug",
      "Sep", "Oct", "Nov", "Dec"
    };
    gchar **tokens = g_strsplit (s, " ", -1);
    guint64 d;
    gchar *endptr;
    gint i;

    if (g_strv_length (tokens) != 5)
      goto out;

    if (strlen (tokens[1]) != 3)
      goto out;
    for (i = 0; i < 12; i++) {
      if (!strcmp (tokens[1], months[i])) {
        break;
      }
    }
    if (i == 12)
      goto out;
    g_date_set_month (date, i + 1);

    d = g_ascii_strtoull (tokens[2], &endptr, 10);
    if (d == 0 && *endptr != '\0')
      goto out;

    g_date_set_day (date, d);

    d = g_ascii_strtoull (tokens[4], &endptr, 10);
    if (d == 0 && *endptr != '\0')
      goto out;

    g_date_set_year (date, d);

  out:
    if (tokens)
      g_strfreev (tokens);
  }
}

static gboolean
gst_flv_demux_parse_metadata_item (GstFlvDemux * demux, GstByteReader * reader,
    gboolean * end_marker)
{
  gchar *tag_name = NULL;
  guint8 tag_type = 0;

  /* Initialize the end_marker flag to FALSE */
  *end_marker = FALSE;

  /* Name of the tag */
  tag_name = FLV_GET_STRING (reader);
  if (G_UNLIKELY (!tag_name)) {
    GST_WARNING_OBJECT (demux, "failed reading tag name");
    return FALSE;
  }

  /* What kind of object is that */
  if (!gst_byte_reader_get_uint8 (reader, &tag_type))
    goto error;

  GST_DEBUG_OBJECT (demux, "tag name %s, tag type %d", tag_name, tag_type);

  switch (tag_type) {
    case 0:                    /* Double */
    {                           /* Use a union to read the uint64 and then as a double */
      gdouble d = 0;

      if (!gst_byte_reader_get_float64_be (reader, &d))
        goto error;

      GST_DEBUG_OBJECT (demux, "%s => (double) %f", tag_name, d);

      if (!strcmp (tag_name, "duration")) {
        demux->duration = d * GST_SECOND;

        gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
            GST_TAG_DURATION, demux->duration, NULL);
      } else if (!strcmp (tag_name, "AspectRatioX")) {
        demux->par_x = d;
        demux->got_par = TRUE;
      } else if (!strcmp (tag_name, "AspectRatioY")) {
        demux->par_y = d;
        demux->got_par = TRUE;
      } else if (!strcmp (tag_name, "width")) {
        demux->w = d;
      } else if (!strcmp (tag_name, "height")) {
        demux->h = d;
      } else if (!strcmp (tag_name, "framerate")) {
        demux->framerate = d;
      } else {
        GST_INFO_OBJECT (demux, "Tag \'%s\' not handled", tag_name);
      }

      break;
    }
    case 1:                    /* Boolean */
    {
      guint8 b = 0;

      if (!gst_byte_reader_get_uint8 (reader, &b))
        goto error;

      GST_DEBUG_OBJECT (demux, "%s => (boolean) %d", tag_name, b);

      GST_INFO_OBJECT (demux, "Tag \'%s\' not handled", tag_name);

      break;
    }
    case 2:                    /* String */
    {
      gchar *s = NULL;

      s = FLV_GET_STRING (reader);
      if (s == NULL)
        goto error;

      GST_DEBUG_OBJECT (demux, "%s => (string) %s", tag_name, s);

      if (!strcmp (tag_name, "creationdate")) {
        GDate *date = g_date_new ();

        parse_flv_demux_parse_date_string (date, s);
        if (!g_date_valid (date)) {
          GST_DEBUG_OBJECT (demux, "Failed to parse string as date");
        } else {
          gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
              GST_TAG_DATE, date, NULL);
        }
        g_date_free (date);
      } else if (!strcmp (tag_name, "creator")) {
        gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
            GST_TAG_ARTIST, s, NULL);
      } else if (!strcmp (tag_name, "title")) {
        gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
            GST_TAG_TITLE, s, NULL);
      } else if (!strcmp (tag_name, "metadatacreator")) {
        gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
            GST_TAG_ENCODER, s, NULL);
      } else {
        GST_INFO_OBJECT (demux, "Tag \'%s\' not handled", tag_name);
      }

      g_free (s);

      break;
    }
    case 3:                    /* Object */
    {
      gboolean end_of_object_marker = FALSE;

      while (!end_of_object_marker) {
        gboolean ok = gst_flv_demux_parse_metadata_item (demux, reader,
            &end_of_object_marker);

        if (G_UNLIKELY (!ok)) {
          GST_WARNING_OBJECT (demux, "failed reading a tag, skipping");
          goto error;
        }
      }

      break;
    }
    case 8:                    /* ECMA array */
    {
      guint32 nb_elems = 0;
      gboolean end_of_object_marker = FALSE;

      if (!gst_byte_reader_get_uint32_be (reader, &nb_elems))
        goto error;

      GST_DEBUG_OBJECT (demux, "there are approx. %d elements in the array",
          nb_elems);

      while (!end_of_object_marker) {
        gboolean ok = gst_flv_demux_parse_metadata_item (demux, reader,
            &end_of_object_marker);

        if (G_UNLIKELY (!ok)) {
          GST_WARNING_OBJECT (demux, "failed reading a tag, skipping");
          goto error;
        }
      }

      break;
    }
    case 9:                    /* End marker */
    {
      GST_DEBUG_OBJECT (demux, "end marker ?");
      if (tag_name[0] == '\0') {

        GST_DEBUG_OBJECT (demux, "end marker detected");

        *end_marker = TRUE;
      }

      break;
    }
    case 10:                   /* Array */
    {
      guint32 nb_elems = 0;

      if (!gst_byte_reader_get_uint32_be (reader, &nb_elems))
        goto error;

      GST_DEBUG_OBJECT (demux, "array has %d elements", nb_elems);

      if (!strcmp (tag_name, "times")) {
        if (demux->times) {
          g_array_free (demux->times, TRUE);
        }
        demux->times = g_array_new (FALSE, TRUE, sizeof (gdouble));
      } else if (!strcmp (tag_name, "filepositions")) {
        if (demux->filepositions) {
          g_array_free (demux->filepositions, TRUE);
        }
        demux->filepositions = g_array_new (FALSE, TRUE, sizeof (gdouble));
      }

      while (nb_elems--) {
        guint8 elem_type = 0;

        if (!gst_byte_reader_get_uint8 (reader, &elem_type))
          goto error;

        switch (elem_type) {
          case 0:
          {
            gdouble d;

            if (!gst_byte_reader_get_float64_be (reader, &d))
              goto error;

            GST_DEBUG_OBJECT (demux, "element is a double %f", d);

            if (!strcmp (tag_name, "times") && demux->times) {
              g_array_append_val (demux->times, d);
            } else if (!strcmp (tag_name, "filepositions") &&
                demux->filepositions) {
              g_array_append_val (demux->filepositions, d);
            }
            break;
          }
          default:
            GST_WARNING_OBJECT (demux, "unsupported array element type %d",
                elem_type);
        }
      }

      break;
    }
    case 11:                   /* Date */
    {
      gdouble d = 0;
      gint16 i = 0;

      if (!gst_byte_reader_get_float64_be (reader, &d))
        goto error;

      if (!gst_byte_reader_get_int16_be (reader, &i))
        goto error;

      GST_DEBUG_OBJECT (demux,
          "%s => (date as a double) %f, timezone offset %d", tag_name, d, i);

      GST_INFO_OBJECT (demux, "Tag \'%s\' not handled", tag_name);

      break;
    }
    default:
      GST_WARNING_OBJECT (demux, "unsupported tag type %d", tag_type);
  }

  g_free (tag_name);

  return TRUE;

error:
  g_free (tag_name);

  return FALSE;
}

static GstFlowReturn
gst_flv_demux_parse_tag_script (GstFlvDemux * demux, GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstByteReader reader;
  guint8 type = 0;
  GstMapInfo map;

  g_return_val_if_fail (gst_buffer_get_size (buffer) >= 7, GST_FLOW_ERROR);

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  gst_byte_reader_init (&reader, map.data, map.size);

  gst_byte_reader_skip_unchecked (&reader, 7);

  GST_LOG_OBJECT (demux, "parsing a script tag");

  if (!gst_byte_reader_get_uint8 (&reader, &type))
    goto cleanup;

  /* Must be string */
  if (type == 2) {
    gchar *function_name;
    guint i;

    function_name = FLV_GET_STRING (&reader);

    GST_LOG_OBJECT (demux, "function name is %s", GST_STR_NULL (function_name));

    if (function_name != NULL && strcmp (function_name, "onMetaData") == 0) {
      gboolean end_marker = FALSE;
      GST_DEBUG_OBJECT (demux, "we have a metadata script object");

      if (!gst_byte_reader_get_uint8 (&reader, &type)) {
        g_free (function_name);
        goto cleanup;
      }

      switch (type) {
        case 8:
        {
          guint32 nb_elems = 0;

          /* ECMA array */
          if (!gst_byte_reader_get_uint32_be (&reader, &nb_elems)) {
            g_free (function_name);
            goto cleanup;
          }

          /* The number of elements is just a hint, some files have
             nb_elements == 0 and actually contain items. */
          GST_DEBUG_OBJECT (demux, "there are approx. %d elements in the array",
              nb_elems);
        }
          /* fallthrough to read data */
        case 3:
        {
          /* Object */
          while (!end_marker) {
            gboolean ok =
                gst_flv_demux_parse_metadata_item (demux, &reader, &end_marker);

            if (G_UNLIKELY (!ok)) {
              GST_WARNING_OBJECT (demux, "failed reading a tag, skipping");
              break;
            }
          }
        }
          break;
        default:
          GST_DEBUG_OBJECT (demux, "Unhandled script data type : %d", type);
          g_free (function_name);
          goto cleanup;
      }

      demux->push_tags = TRUE;
    }

    g_free (function_name);

    if (demux->times && demux->filepositions) {
      guint num;

      /* If an index was found, insert associations */
      num = MIN (demux->times->len, demux->filepositions->len);
      for (i = 0; i < num; i++) {
        guint64 time, fileposition;

        time = g_array_index (demux->times, gdouble, i) * GST_SECOND;
        fileposition = g_array_index (demux->filepositions, gdouble, i);
        gst_flv_demux_parse_and_add_index_entry (demux, time, fileposition,
            TRUE);
      }
      demux->indexed = TRUE;
    }
  }

cleanup:
  gst_buffer_unmap (buffer, &map);

  return ret;
}

static gboolean
have_group_id (GstFlvDemux * demux)
{
  GstEvent *event;

  event = gst_pad_get_sticky_event (demux->sinkpad, GST_EVENT_STREAM_START, 0);
  if (event) {
    if (gst_event_parse_group_id (event, &demux->group_id))
      demux->have_group_id = TRUE;
    else
      demux->have_group_id = FALSE;
    gst_event_unref (event);
  } else if (!demux->have_group_id) {
    demux->have_group_id = TRUE;
    demux->group_id = gst_util_group_id_next ();
  }

  return demux->have_group_id;
}

static gboolean
gst_flv_demux_audio_negotiate (GstFlvDemux * demux, guint32 codec_tag,
    guint32 rate, guint32 channels, guint32 width)
{
  GstCaps *caps = NULL;
  gchar *codec_name = NULL;
  gboolean ret = FALSE;
  guint adjusted_rate = rate;
  GstEvent *event;
  gchar *stream_id;

  switch (codec_tag) {
    case 1:
      caps = gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING,
          "swf", NULL);
      break;
    case 2:
    case 14:
      caps = gst_caps_new_simple ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3,
          "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
      break;
    case 0:
    case 3:
    {
      GstAudioFormat format;

      /* Assuming little endian for 0 (aka endianness of the
       * system on which the file was created) as most people
       * are probably using little endian machines */
      format = gst_audio_format_build_integer ((width == 8) ? FALSE : TRUE,
          G_LITTLE_ENDIAN, width, width);

      caps = gst_caps_new_simple ("audio/x-raw",
          "format", G_TYPE_STRING, gst_audio_format_to_string (format),
          "layout", G_TYPE_STRING, "interleaved", NULL);
      break;
    }
    case 4:
    case 5:
    case 6:
      caps = gst_caps_new_empty_simple ("audio/x-nellymoser");
      break;
    case 10:
    {
      if (demux->audio_codec_data) {
        GstMapInfo map;

        gst_buffer_map (demux->audio_codec_data, &map, GST_MAP_READ);

        /* use codec-data to extract and verify samplerate */
        if (map.size >= 2) {
          gint freq_index;

          freq_index = GST_READ_UINT16_BE (map.data);
          freq_index = (freq_index & 0x0780) >> 7;
          adjusted_rate =
              gst_codec_utils_aac_get_sample_rate_from_index (freq_index);

          if (adjusted_rate && (rate != adjusted_rate)) {
            GST_LOG_OBJECT (demux, "Ajusting AAC sample rate %d -> %d", rate,
                adjusted_rate);
          } else {
            adjusted_rate = rate;
          }
        }
        gst_buffer_unmap (demux->audio_codec_data, &map);
      }

      caps = gst_caps_new_simple ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 4, "framed", G_TYPE_BOOLEAN, TRUE,
          "stream-format", G_TYPE_STRING, "raw", NULL);
      break;
    }
    case 7:
      caps = gst_caps_new_empty_simple ("audio/x-alaw");
      break;
    case 8:
      caps = gst_caps_new_empty_simple ("audio/x-mulaw");
      break;
    case 11:
    {
      GValue streamheader = G_VALUE_INIT;
      GValue value = G_VALUE_INIT;
      GstByteWriter w;
      GstStructure *structure;
      GstBuffer *buf;

      caps = gst_caps_new_empty_simple ("audio/x-speex");
      structure = gst_caps_get_structure (caps, 0);

      GST_DEBUG_OBJECT (demux, "generating speex header");

      /* Speex decoder expects streamheader to be { [header], [comment] } */
      g_value_init (&streamheader, GST_TYPE_ARRAY);

      /* header part */
      gst_byte_writer_init_with_size (&w, 80, TRUE);
      gst_byte_writer_put_data (&w, (guint8 *) "Speex   ", 8);
      gst_byte_writer_put_data (&w, (guint8 *) "1.1.12", 7);
      gst_byte_writer_fill (&w, 0, 13);
      gst_byte_writer_put_uint32_le (&w, 1);    /* version */
      gst_byte_writer_put_uint32_le (&w, 80);   /* header_size */
      gst_byte_writer_put_uint32_le (&w, 16000);        /* rate */
      gst_byte_writer_put_uint32_le (&w, 1);    /* mode: Wideband */
      gst_byte_writer_put_uint32_le (&w, 4);    /* mode_bitstream_version */
      gst_byte_writer_put_uint32_le (&w, 1);    /* nb_channels: 1 */
      gst_byte_writer_put_uint32_le (&w, -1);   /* bitrate */
      gst_byte_writer_put_uint32_le (&w, 0x50); /* frame_size */
      gst_byte_writer_put_uint32_le (&w, 0);    /* VBR */
      gst_byte_writer_put_uint32_le (&w, 1);    /* frames_per_packet */
      gst_byte_writer_put_uint32_le (&w, 0);    /* extra_headers */
      gst_byte_writer_put_uint32_le (&w, 0);    /* reserved1 */
      gst_byte_writer_put_uint32_le (&w, 0);    /* reserved2 */
      g_assert (gst_byte_writer_get_size (&w) == 80);

      g_value_init (&value, GST_TYPE_BUFFER);
      g_value_take_boxed (&value, gst_byte_writer_reset_and_get_buffer (&w));
      gst_value_array_append_value (&streamheader, &value);
      g_value_unset (&value);

      /* comment part */
      g_value_init (&value, GST_TYPE_BUFFER);
      buf = gst_buffer_new_wrapped (g_memdup ("No comments", 12), 12);
      g_value_take_boxed (&value, buf);
      gst_value_array_append_value (&streamheader, &value);
      g_value_unset (&value);

      gst_structure_take_value (structure, "streamheader", &streamheader);
      break;
    }
    default:
      GST_WARNING_OBJECT (demux, "unsupported audio codec tag %u", codec_tag);
      break;
  }

  if (G_UNLIKELY (!caps)) {
    GST_WARNING_OBJECT (demux, "failed creating caps for audio pad");
    goto beach;
  }

  gst_caps_set_simple (caps, "rate", G_TYPE_INT, adjusted_rate,
      "channels", G_TYPE_INT, channels, NULL);

  if (demux->audio_codec_data) {
    gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
        demux->audio_codec_data, NULL);
  }

  stream_id =
      gst_pad_create_stream_id (demux->audio_pad, GST_ELEMENT_CAST (demux),
      "audio");

  event = gst_event_new_stream_start (stream_id);
  if (have_group_id (demux))
    gst_event_set_group_id (event, demux->group_id);
  gst_pad_push_event (demux->audio_pad, event);
  g_free (stream_id);

  ret = gst_pad_set_caps (demux->audio_pad, caps);

  if (G_LIKELY (ret)) {
    /* Store the caps we got from tags */
    demux->audio_codec_tag = codec_tag;
    demux->rate = rate;
    demux->channels = channels;
    demux->width = width;

    codec_name = gst_pb_utils_get_codec_description (caps);

    if (codec_name) {
      if (demux->taglist == NULL)
        demux->taglist = gst_tag_list_new_empty ();
      gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
          GST_TAG_AUDIO_CODEC, codec_name, NULL);
      g_free (codec_name);
    }

    GST_DEBUG_OBJECT (demux->audio_pad, "successfully negotiated caps %"
        GST_PTR_FORMAT, caps);
  } else {
    GST_WARNING_OBJECT (demux->audio_pad, "failed negotiating caps %"
        GST_PTR_FORMAT, caps);
  }

  gst_caps_unref (caps);

beach:
  return ret;
}

static gboolean
gst_flv_demux_push_src_event (GstFlvDemux * demux, GstEvent * event)
{
  gboolean ret = TRUE;

  if (demux->audio_pad)
    ret |= gst_pad_push_event (demux->audio_pad, gst_event_ref (event));

  if (demux->video_pad)
    ret |= gst_pad_push_event (demux->video_pad, gst_event_ref (event));

  gst_event_unref (event);

  return ret;
}

static void
gst_flv_demux_push_tags (GstFlvDemux * demux)
{
  if (demux->has_audio && !demux->audio_pad) {
    GST_DEBUG_OBJECT (demux,
        "Waiting for audio stream pad to come up before we can push tags");
    return;
  }
  if (demux->has_video && !demux->video_pad) {
    GST_DEBUG_OBJECT (demux,
        "Waiting for video stream pad to come up before we can push tags");
    return;
  }
  if (demux->taglist) {
    GST_DEBUG_OBJECT (demux, "pushing tags out %" GST_PTR_FORMAT,
        demux->taglist);
    gst_tag_list_set_scope (demux->taglist, GST_TAG_SCOPE_GLOBAL);
    gst_flv_demux_push_src_event (demux, gst_event_new_tag (demux->taglist));
    demux->taglist = gst_tag_list_new_empty ();
    demux->push_tags = FALSE;
  }
}

static void
gst_flv_demux_update_resync (GstFlvDemux * demux, guint32 pts, gboolean discont,
    guint32 * last, GstClockTime * offset)
{
  gint32 dpts = pts - *last;
  if (!discont && ABS (dpts) >= RESYNC_THRESHOLD) {
    /* Theoretically, we should use substract the duration of the last buffer,
       but this demuxer sends no durations on buffers, not sure if it cannot
       know, or just does not care to calculate. */
    *offset -= dpts * GST_MSECOND;
    GST_WARNING_OBJECT (demux,
        "Large pts gap (%" G_GINT32_FORMAT " ms), assuming resync, offset now %"
        GST_TIME_FORMAT "", dpts, GST_TIME_ARGS (*offset));
  }
  *last = pts;
}

static GstFlowReturn
gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint32 pts = 0, codec_tag = 0, rate = 5512, width = 8, channels = 1;
  guint32 codec_data = 0, pts_ext = 0;
  guint8 flags = 0;
  GstMapInfo map;
  GstBuffer *outbuf;
  guint8 *data;

  GST_LOG_OBJECT (demux, "parsing an audio tag");

  if (demux->no_more_pads && !demux->audio_pad) {
    GST_WARNING_OBJECT (demux,
        "Signaled no-more-pads already but had no audio pad -- ignoring");
    return GST_FLOW_OK;
  }

  g_return_val_if_fail (gst_buffer_get_size (buffer) == demux->tag_size,
      GST_FLOW_ERROR);

  /* Error out on tags with too small headers */
  if (gst_buffer_get_size (buffer) < 11) {
    GST_ERROR_OBJECT (demux, "Too small tag size (%" G_GSIZE_FORMAT ")",
        gst_buffer_get_size (buffer));
    return GST_FLOW_ERROR;
  }

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

  /* Grab information about audio tag */
  pts = GST_READ_UINT24_BE (data);
  /* read the pts extension to 32 bits integer */
  pts_ext = GST_READ_UINT8 (data + 3);
  /* Combine them */
  pts |= pts_ext << 24;

  GST_LOG_OBJECT (demux, "pts bytes %02X %02X %02X %02X (%d)", data[0], data[1],
      data[2], data[3], pts);

  /* Skip the stream id and go directly to the flags */
  flags = GST_READ_UINT8 (data + 7);

  /* Silently skip buffers with no data */
  if (map.size == 11)
    goto beach;

  /* Channels */
  if (flags & 0x01) {
    channels = 2;
  }
  /* Width */
  if (flags & 0x02) {
    width = 16;
  }
  /* Sampling rate */
  if ((flags & 0x0C) == 0x0C) {
    rate = 44100;
  } else if ((flags & 0x0C) == 0x08) {
    rate = 22050;
  } else if ((flags & 0x0C) == 0x04) {
    rate = 11025;
  }
  /* Codec tag */
  codec_tag = flags >> 4;
  if (codec_tag == 10) {        /* AAC has an extra byte for packet type */
    codec_data = 2;
  } else {
    codec_data = 1;
  }

  /* codec tags with special rates */
  if (codec_tag == 5 || codec_tag == 14)
    rate = 8000;
  else if (codec_tag == 4)
    rate = 16000;

  GST_LOG_OBJECT (demux, "audio tag with %d channels, %dHz sampling rate, "
      "%d bits width, codec tag %u (flags %02X)", channels, rate, width,
      codec_tag, flags);

  /* If we don't have our audio pad created, then create it. */
  if (G_UNLIKELY (!demux->audio_pad)) {

    demux->audio_pad =
        gst_pad_new_from_template (gst_element_class_get_pad_template
        (GST_ELEMENT_GET_CLASS (demux), "audio"), "audio");
    if (G_UNLIKELY (!demux->audio_pad)) {
      GST_WARNING_OBJECT (demux, "failed creating audio pad");
      ret = GST_FLOW_ERROR;
      goto beach;
    }

    /* Set functions on the pad */
    gst_pad_set_query_function (demux->audio_pad,
        GST_DEBUG_FUNCPTR (gst_flv_demux_query));
    gst_pad_set_event_function (demux->audio_pad,
        GST_DEBUG_FUNCPTR (gst_flv_demux_src_event));

    gst_pad_use_fixed_caps (demux->audio_pad);

    /* Make it active */
    gst_pad_set_active (demux->audio_pad, TRUE);

    /* Negotiate caps */
    if (!gst_flv_demux_audio_negotiate (demux, codec_tag, rate, channels,
            width)) {
      gst_object_unref (demux->audio_pad);
      demux->audio_pad = NULL;
      ret = GST_FLOW_ERROR;
      goto beach;
    }
#ifndef GST_DISABLE_GST_DEBUG
    {
      GstCaps *caps;

      caps = gst_pad_get_current_caps (demux->audio_pad);
      GST_DEBUG_OBJECT (demux, "created audio pad with caps %" GST_PTR_FORMAT,
          caps);
      if (caps)
        gst_caps_unref (caps);
    }
#endif

    /* We need to set caps before adding */
    gst_element_add_pad (GST_ELEMENT (demux),
        gst_object_ref (demux->audio_pad));

    /* We only emit no more pads when we have audio and video. Indeed we can
     * not trust the FLV header to tell us if there will be only audio or
     * only video and we would just break discovery of some files */
    if (demux->audio_pad && demux->video_pad) {
      GST_DEBUG_OBJECT (demux, "emitting no more pads");
      gst_element_no_more_pads (GST_ELEMENT (demux));
      demux->no_more_pads = TRUE;
      demux->push_tags = TRUE;
    }
  }

  /* Check if caps have changed */
  if (G_UNLIKELY (rate != demux->rate || channels != demux->channels ||
          codec_tag != demux->audio_codec_tag || width != demux->width)) {
    GST_DEBUG_OBJECT (demux, "audio settings have changed, changing caps");

    /* Negotiate caps */
    if (!gst_flv_demux_audio_negotiate (demux, codec_tag, rate, channels,
            width)) {
      ret = GST_FLOW_ERROR;
      goto beach;
    }
  }

  /* Push taglist if present */
  if (G_UNLIKELY (demux->push_tags))
    gst_flv_demux_push_tags (demux);

  /* Check if we have anything to push */
  if (demux->tag_data_size <= codec_data) {
    GST_LOG_OBJECT (demux, "Nothing left in this tag, returning");
    goto beach;
  }

  /* Create buffer from pad */
  outbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_MEMORY,
      7 + codec_data, demux->tag_data_size - codec_data);

  if (demux->audio_codec_tag == 10) {
    guint8 aac_packet_type = GST_READ_UINT8 (data + 8);

    switch (aac_packet_type) {
      case 0:
      {
        /* AudioSpecificConfig data */
        GST_LOG_OBJECT (demux, "got an AAC codec data packet");
        if (demux->audio_codec_data) {
          gst_buffer_unref (demux->audio_codec_data);
        }
        demux->audio_codec_data = outbuf;
        /* Use that buffer data in the caps */
        gst_flv_demux_audio_negotiate (demux, codec_tag, rate, channels, width);
        goto beach;
        break;
      }
      case 1:
        /* AAC raw packet */
        GST_LOG_OBJECT (demux, "got a raw AAC audio packet");
        break;
      default:
        GST_WARNING_OBJECT (demux, "invalid AAC packet type %u",
            aac_packet_type);
    }
  }

  /* detect (and deem to be resyncs)  large pts gaps */
  gst_flv_demux_update_resync (demux, pts, demux->audio_need_discont,
      &demux->last_audio_pts, &demux->audio_time_offset);

  /* Fill buffer with data */
  GST_BUFFER_TIMESTAMP (outbuf) = pts * GST_MSECOND + demux->audio_time_offset;
  GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
  GST_BUFFER_OFFSET (outbuf) = demux->audio_offset++;
  GST_BUFFER_OFFSET_END (outbuf) = demux->audio_offset;

  if (demux->duration == GST_CLOCK_TIME_NONE ||
      demux->duration < GST_BUFFER_TIMESTAMP (outbuf))
    demux->duration = GST_BUFFER_TIMESTAMP (outbuf);

  /* Only add audio frames to the index if we have no video,
   * and if the index is not yet complete */
  if (!demux->has_video && !demux->indexed) {
    gst_flv_demux_parse_and_add_index_entry (demux,
        GST_BUFFER_TIMESTAMP (outbuf), demux->cur_tag_offset, TRUE);
  }

  if (G_UNLIKELY (demux->audio_need_discont)) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
    demux->audio_need_discont = FALSE;
  }

  demux->segment.position = GST_BUFFER_TIMESTAMP (outbuf);

  /* Do we need a newsegment event ? */
  if (G_UNLIKELY (demux->audio_need_segment)) {
    if (!demux->new_seg_event) {
      GST_DEBUG_OBJECT (demux, "pushing newsegment from %"
          GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (demux->segment.position),
          GST_TIME_ARGS (demux->segment.stop));
      demux->segment.start = demux->segment.time = demux->segment.position;
      demux->new_seg_event = gst_event_new_segment (&demux->segment);
    } else {
      GST_DEBUG_OBJECT (demux, "pushing pre-generated newsegment event");
    }

    gst_pad_push_event (demux->audio_pad, gst_event_ref (demux->new_seg_event));

    demux->audio_need_segment = FALSE;
  }

  GST_LOG_OBJECT (demux,
      "pushing %" G_GSIZE_FORMAT " bytes buffer at pts %" GST_TIME_FORMAT
      " with duration %" GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT,
      gst_buffer_get_size (outbuf),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf));

  if (!GST_CLOCK_TIME_IS_VALID (demux->audio_start)) {
    demux->audio_start = GST_BUFFER_TIMESTAMP (outbuf);
  }
  if (!GST_CLOCK_TIME_IS_VALID (demux->audio_first_ts)) {
    demux->audio_first_ts = GST_BUFFER_TIMESTAMP (outbuf);
  }

  if (G_UNLIKELY (!demux->no_more_pads
          && (GST_CLOCK_DIFF (demux->audio_start,
                  GST_BUFFER_TIMESTAMP (outbuf)) > 6 * GST_SECOND))) {
    GST_DEBUG_OBJECT (demux,
        "Signalling no-more-pads because no video stream was found"
        " after 6 seconds of audio");
    gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
    demux->no_more_pads = TRUE;
    demux->push_tags = TRUE;
  }

  /* Push downstream */
  ret = gst_pad_push (demux->audio_pad, outbuf);
  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    if (demux->segment.rate < 0.0 && ret == GST_FLOW_EOS &&
        demux->segment.position > demux->segment.stop) {
      /* In reverse playback we can get a GST_FLOW_EOS when
       * we are at the end of the segment, so we just need to jump
       * back to the previous section. */
      GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
      demux->audio_done = TRUE;
      ret = GST_FLOW_OK;
    } else {
      GST_WARNING_OBJECT (demux, "failed pushing a %" G_GUINT64_FORMAT
          " bytes audio buffer: %s", demux->tag_data_size,
          gst_flow_get_name (ret));
      if (ret == GST_FLOW_NOT_LINKED) {
        demux->audio_linked = FALSE;
      }
      goto beach;
    }
  }

  demux->audio_linked = TRUE;

beach:
  gst_buffer_unmap (buffer, &map);

  return ret;
}

static gboolean
gst_flv_demux_video_negotiate (GstFlvDemux * demux, guint32 codec_tag)
{
  gboolean ret = FALSE;
  GstCaps *caps = NULL;
  gchar *codec_name = NULL;
  GstEvent *event;
  gchar *stream_id;

  /* Generate caps for that pad */
  switch (codec_tag) {
    case 2:
      caps =
          gst_caps_new_simple ("video/x-flash-video", "flvversion", G_TYPE_INT,
          1, NULL);
      break;
    case 3:
      caps = gst_caps_new_empty_simple ("video/x-flash-screen");
      break;
    case 4:
      caps = gst_caps_new_empty_simple ("video/x-vp6-flash");
      break;
    case 5:
      caps = gst_caps_new_empty_simple ("video/x-vp6-alpha");
      break;
    case 7:
      caps =
          gst_caps_new_simple ("video/x-h264", "stream-format", G_TYPE_STRING,
          "avc", NULL);
      break;
    default:
      GST_WARNING_OBJECT (demux, "unsupported video codec tag %u", codec_tag);
  }

  if (G_UNLIKELY (!caps)) {
    GST_WARNING_OBJECT (demux, "failed creating caps for video pad");
    goto beach;
  }

  gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
      demux->par_x, demux->par_y, NULL);

  if (G_LIKELY (demux->w)) {
    gst_caps_set_simple (caps, "width", G_TYPE_INT, demux->w, NULL);
  }

  if (G_LIKELY (demux->h)) {
    gst_caps_set_simple (caps, "height", G_TYPE_INT, demux->h, NULL);
  }

  if (G_LIKELY (demux->framerate)) {
    gint num = 0, den = 0;

    gst_util_double_to_fraction (demux->framerate, &num, &den);
    GST_DEBUG_OBJECT (demux->video_pad,
        "fps to be used on caps %f (as a fraction = %d/%d)", demux->framerate,
        num, den);

    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, num, den, NULL);
  }

  if (demux->video_codec_data) {
    gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
        demux->video_codec_data, NULL);
  }

  stream_id =
      gst_pad_create_stream_id (demux->video_pad, GST_ELEMENT_CAST (demux),
      "video");
  event = gst_event_new_stream_start (stream_id);
  g_free (stream_id);

  if (have_group_id (demux))
    gst_event_set_group_id (event, demux->group_id);
  gst_pad_push_event (demux->video_pad, event);
  ret = gst_pad_set_caps (demux->video_pad, caps);

  if (G_LIKELY (ret)) {
    /* Store the caps we have set */
    demux->video_codec_tag = codec_tag;

    codec_name = gst_pb_utils_get_codec_description (caps);

    if (codec_name) {
      if (demux->taglist == NULL)
        demux->taglist = gst_tag_list_new_empty ();
      gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
          GST_TAG_VIDEO_CODEC, codec_name, NULL);
      g_free (codec_name);
    }

    GST_DEBUG_OBJECT (demux->video_pad, "successfully negotiated caps %"
        GST_PTR_FORMAT, caps);
  } else {
    GST_WARNING_OBJECT (demux->video_pad, "failed negotiating caps %"
        GST_PTR_FORMAT, caps);
  }

  gst_caps_unref (caps);

beach:
  return ret;
}

static GstFlowReturn
gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint32 pts = 0, codec_data = 1, pts_ext = 0;
  gboolean keyframe = FALSE;
  guint8 flags = 0, codec_tag = 0;
  GstBuffer *outbuf;
  GstMapInfo map;
  guint8 *data;

  g_return_val_if_fail (gst_buffer_get_size (buffer) == demux->tag_size,
      GST_FLOW_ERROR);

  GST_LOG_OBJECT (demux, "parsing a video tag");

  if (demux->no_more_pads && !demux->video_pad) {
    GST_WARNING_OBJECT (demux,
        "Signaled no-more-pads already but had no audio pad -- ignoring");
    return GST_FLOW_OK;
  }

  if (gst_buffer_get_size (buffer) < 12) {
    GST_ERROR_OBJECT (demux, "Too small tag size");
    return GST_FLOW_ERROR;
  }

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

  /* Grab information about video tag */
  pts = GST_READ_UINT24_BE (data);
  /* read the pts extension to 32 bits integer */
  pts_ext = GST_READ_UINT8 (data + 3);
  /* Combine them */
  pts |= pts_ext << 24;

  GST_LOG_OBJECT (demux, "pts bytes %02X %02X %02X %02X (%d)", data[0], data[1],
      data[2], data[3], pts);

  /* Skip the stream id and go directly to the flags */
  flags = GST_READ_UINT8 (data + 7);

  /* Keyframe */
  if ((flags >> 4) == 1) {
    keyframe = TRUE;
  }
  /* Codec tag */
  codec_tag = flags & 0x0F;
  if (codec_tag == 4 || codec_tag == 5) {
    codec_data = 2;
  } else if (codec_tag == 7) {
    gint32 cts;

    codec_data = 5;

    cts = GST_READ_UINT24_BE (data + 9);
    cts = (cts + 0xff800000) ^ 0xff800000;

    GST_LOG_OBJECT (demux, "got cts %d", cts);

    /* avoid negative overflow */
    if (cts >= 0 || pts >= -cts)
      pts += cts;
  }

  GST_LOG_OBJECT (demux, "video tag with codec tag %u, keyframe (%d) "
      "(flags %02X)", codec_tag, keyframe, flags);

  /* If we don't have our video pad created, then create it. */
  if (G_UNLIKELY (!demux->video_pad)) {
    demux->video_pad =
        gst_pad_new_from_template (gst_element_class_get_pad_template
        (GST_ELEMENT_GET_CLASS (demux), "video"), "video");
    if (G_UNLIKELY (!demux->video_pad)) {
      GST_WARNING_OBJECT (demux, "failed creating video pad");
      ret = GST_FLOW_ERROR;
      goto beach;
    }

    /* Set functions on the pad */
    gst_pad_set_query_function (demux->video_pad,
        GST_DEBUG_FUNCPTR (gst_flv_demux_query));
    gst_pad_set_event_function (demux->video_pad,
        GST_DEBUG_FUNCPTR (gst_flv_demux_src_event));

    gst_pad_use_fixed_caps (demux->video_pad);

    /* Make it active */
    gst_pad_set_active (demux->video_pad, TRUE);

    /* Needs to be active before setting caps */
    if (!gst_flv_demux_video_negotiate (demux, codec_tag)) {
      gst_object_unref (demux->video_pad);
      demux->video_pad = NULL;
      ret = GST_FLOW_ERROR;
      goto beach;
    }

    /* When we ve set pixel-aspect-ratio we use that boolean to detect a
     * metadata tag that would come later and trigger a caps change */
    demux->got_par = FALSE;

#ifndef GST_DISABLE_GST_DEBUG
    {
      GstCaps *caps;

      caps = gst_pad_get_current_caps (demux->video_pad);
      GST_DEBUG_OBJECT (demux, "created video pad with caps %" GST_PTR_FORMAT,
          caps);
      if (caps)
        gst_caps_unref (caps);
    }
#endif

    /* We need to set caps before adding */
    gst_element_add_pad (GST_ELEMENT (demux),
        gst_object_ref (demux->video_pad));

    /* We only emit no more pads when we have audio and video. Indeed we can
     * not trust the FLV header to tell us if there will be only audio or
     * only video and we would just break discovery of some files */
    if (demux->audio_pad && demux->video_pad) {
      GST_DEBUG_OBJECT (demux, "emitting no more pads");
      gst_element_no_more_pads (GST_ELEMENT (demux));
      demux->no_more_pads = TRUE;
      demux->push_tags = TRUE;
    }
  }

  /* Check if caps have changed */
  if (G_UNLIKELY (codec_tag != demux->video_codec_tag || demux->got_par)) {

    GST_DEBUG_OBJECT (demux, "video settings have changed, changing caps");

    if (!gst_flv_demux_video_negotiate (demux, codec_tag)) {
      ret = GST_FLOW_ERROR;
      goto beach;
    }

    /* When we ve set pixel-aspect-ratio we use that boolean to detect a
     * metadata tag that would come later and trigger a caps change */
    demux->got_par = FALSE;
  }

  /* Push taglist if present */
  if (G_UNLIKELY (demux->push_tags))
    gst_flv_demux_push_tags (demux);

  /* Check if we have anything to push */
  if (demux->tag_data_size <= codec_data) {
    GST_LOG_OBJECT (demux, "Nothing left in this tag, returning");
    goto beach;
  }

  /* Create buffer from pad */
  outbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_MEMORY,
      7 + codec_data, demux->tag_data_size - codec_data);

  if (demux->video_codec_tag == 7) {
    guint8 avc_packet_type = GST_READ_UINT8 (data + 8);

    switch (avc_packet_type) {
      case 0:
      {
        /* AVCDecoderConfigurationRecord data */
        GST_LOG_OBJECT (demux, "got an H.264 codec data packet");
        if (demux->video_codec_data) {
          gst_buffer_unref (demux->video_codec_data);
        }
        demux->video_codec_data = outbuf;
        /* Use that buffer data in the caps */
        gst_flv_demux_video_negotiate (demux, codec_tag);
        goto beach;
        break;
      }
      case 1:
        /* H.264 NALU packet */
        GST_LOG_OBJECT (demux, "got a H.264 NALU video packet");
        break;
      default:
        GST_WARNING_OBJECT (demux, "invalid video packet type %u",
            avc_packet_type);
    }
  }

  /* detect (and deem to be resyncs)  large pts gaps */
  gst_flv_demux_update_resync (demux, pts, demux->video_need_discont,
      &demux->last_video_pts, &demux->video_time_offset);

  /* Fill buffer with data */
  GST_BUFFER_TIMESTAMP (outbuf) = pts * GST_MSECOND + demux->video_time_offset;
  GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
  GST_BUFFER_OFFSET (outbuf) = demux->video_offset++;
  GST_BUFFER_OFFSET_END (outbuf) = demux->video_offset;

  if (demux->duration == GST_CLOCK_TIME_NONE ||
      demux->duration < GST_BUFFER_TIMESTAMP (outbuf))
    demux->duration = GST_BUFFER_TIMESTAMP (outbuf);

  if (!keyframe)
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);

  if (!demux->indexed) {
    gst_flv_demux_parse_and_add_index_entry (demux,
        GST_BUFFER_TIMESTAMP (outbuf), demux->cur_tag_offset, keyframe);
  }

  if (G_UNLIKELY (demux->video_need_discont)) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
    demux->video_need_discont = FALSE;
  }

  demux->segment.position = GST_BUFFER_TIMESTAMP (outbuf);

  /* Do we need a newsegment event ? */
  if (G_UNLIKELY (demux->video_need_segment)) {
    if (!demux->new_seg_event) {
      GST_DEBUG_OBJECT (demux, "pushing newsegment from %"
          GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (demux->segment.position),
          GST_TIME_ARGS (demux->segment.stop));
      demux->segment.start = demux->segment.time = demux->segment.position;
      demux->new_seg_event = gst_event_new_segment (&demux->segment);
    } else {
      GST_DEBUG_OBJECT (demux, "pushing pre-generated newsegment event");
    }

    gst_pad_push_event (demux->video_pad, gst_event_ref (demux->new_seg_event));

    demux->video_need_segment = FALSE;
  }

  GST_LOG_OBJECT (demux,
      "pushing %" G_GSIZE_FORMAT " bytes buffer at pts %" GST_TIME_FORMAT
      " with duration %" GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT
      ", keyframe (%d)", gst_buffer_get_size (outbuf),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf),
      keyframe);

  if (!GST_CLOCK_TIME_IS_VALID (demux->video_start)) {
    demux->video_start = GST_BUFFER_TIMESTAMP (outbuf);
  }
  if (!GST_CLOCK_TIME_IS_VALID (demux->audio_first_ts)) {
    demux->video_first_ts = GST_BUFFER_TIMESTAMP (outbuf);
  }

  if (G_UNLIKELY (!demux->no_more_pads
          && (GST_CLOCK_DIFF (demux->video_start,
                  GST_BUFFER_TIMESTAMP (outbuf)) > 6 * GST_SECOND))) {
    GST_DEBUG_OBJECT (demux,
        "Signalling no-more-pads because no audio stream was found"
        " after 6 seconds of video");
    gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
    demux->no_more_pads = TRUE;
    demux->push_tags = TRUE;
  }

  /* Push downstream */
  ret = gst_pad_push (demux->video_pad, outbuf);

  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    if (demux->segment.rate < 0.0 && ret == GST_FLOW_EOS &&
        demux->segment.position > demux->segment.stop) {
      /* In reverse playback we can get a GST_FLOW_EOS when
       * we are at the end of the segment, so we just need to jump
       * back to the previous section. */
      GST_DEBUG_OBJECT (demux, "downstream has reached end of segment");
      demux->video_done = TRUE;
      ret = GST_FLOW_OK;
    } else {
      GST_WARNING_OBJECT (demux, "failed pushing a %" G_GUINT64_FORMAT
          " bytes video buffer: %s", demux->tag_data_size,
          gst_flow_get_name (ret));
      if (ret == GST_FLOW_NOT_LINKED) {
        demux->video_linked = FALSE;
      }
      goto beach;
    }
  }

  demux->video_linked = TRUE;

beach:
  gst_buffer_unmap (buffer, &map);
  return ret;
}

static GstClockTime
gst_flv_demux_parse_tag_timestamp (GstFlvDemux * demux, gboolean index,
    GstBuffer * buffer, size_t * tag_size)
{
  guint32 pts = 0, pts_ext = 0;
  guint32 tag_data_size;
  guint8 type;
  gboolean keyframe = TRUE;
  GstClockTime ret = GST_CLOCK_TIME_NONE;
  GstMapInfo map;
  guint8 *data;
  gsize size;

  g_return_val_if_fail (gst_buffer_get_size (buffer) >= 12,
      GST_CLOCK_TIME_NONE);

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

  type = data[0];

  if (type != 9 && type != 8 && type != 18) {
    GST_WARNING_OBJECT (demux, "Unsupported tag type %u", data[0]);
    goto exit;
  }

  if (type == 9)
    demux->has_video = TRUE;
  else if (type == 8)
    demux->has_audio = TRUE;

  tag_data_size = GST_READ_UINT24_BE (data + 1);

  if (size >= tag_data_size + 11 + 4) {
    if (GST_READ_UINT32_BE (data + tag_data_size + 11) != tag_data_size + 11) {
      GST_WARNING_OBJECT (demux, "Invalid tag size");
      goto exit;
    }
  }

  if (tag_size)
    *tag_size = tag_data_size + 11 + 4;

  data += 4;

  GST_LOG_OBJECT (demux, "pts bytes %02X %02X %02X %02X", data[0], data[1],
      data[2], data[3]);

  /* Grab timestamp of tag tag */
  pts = GST_READ_UINT24_BE (data);
  /* read the pts extension to 32 bits integer */
  pts_ext = GST_READ_UINT8 (data + 3);
  /* Combine them */
  pts |= pts_ext << 24;

  if (type == 9) {
    data += 7;

    keyframe = ((data[0] >> 4) == 1);
  }

  ret = pts * GST_MSECOND;
  GST_LOG_OBJECT (demux, "pts: %" GST_TIME_FORMAT, GST_TIME_ARGS (ret));

  if (index && !demux->indexed && (type == 9 || (type == 8
              && !demux->has_video))) {
    gst_flv_demux_parse_and_add_index_entry (demux, ret, demux->offset,
        keyframe);
  }

  if (demux->duration == GST_CLOCK_TIME_NONE || demux->duration < ret)
    demux->duration = ret;

exit:
  gst_buffer_unmap (buffer, &map);
  return ret;
}

static GstFlowReturn
gst_flv_demux_parse_tag_type (GstFlvDemux * demux, GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint8 tag_type = 0;
  GstMapInfo map;

  g_return_val_if_fail (gst_buffer_get_size (buffer) >= 4, GST_FLOW_ERROR);

  gst_buffer_map (buffer, &map, GST_MAP_READ);

  tag_type = map.data[0];

  switch (tag_type) {
    case 9:
      demux->state = FLV_STATE_TAG_VIDEO;
      demux->has_video = TRUE;
      break;
    case 8:
      demux->state = FLV_STATE_TAG_AUDIO;
      demux->has_audio = TRUE;
      break;
    case 18:
      demux->state = FLV_STATE_TAG_SCRIPT;
      break;
    default:
      GST_WARNING_OBJECT (demux, "unsupported tag type %u", tag_type);
  }

  /* Tag size is 1 byte of type + 3 bytes of size + 7 bytes + tag data size +
   * 4 bytes of previous tag size */
  demux->tag_data_size = GST_READ_UINT24_BE (map.data + 1);
  demux->tag_size = demux->tag_data_size + 11;

  GST_LOG_OBJECT (demux, "tag data size is %" G_GUINT64_FORMAT,
      demux->tag_data_size);

  gst_buffer_unmap (buffer, &map);

  return ret;
}

static GstFlowReturn
gst_flv_demux_parse_header (GstFlvDemux * demux, GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstMapInfo map;

  g_return_val_if_fail (gst_buffer_get_size (buffer) >= 9, GST_FLOW_ERROR);

  gst_buffer_map (buffer, &map, GST_MAP_READ);

  /* Check for the FLV tag */
  if (map.data[0] == 'F' && map.data[1] == 'L' && map.data[2] == 'V') {
    GST_DEBUG_OBJECT (demux, "FLV header detected");
  } else {
    if (G_UNLIKELY (demux->strict)) {
      GST_WARNING_OBJECT (demux, "invalid header tag detected");
      ret = GST_FLOW_EOS;
      goto beach;
    }
  }

  if (map.data[3] == '1') {
    GST_DEBUG_OBJECT (demux, "FLV version 1 detected");
  } else {
    if (G_UNLIKELY (demux->strict)) {
      GST_WARNING_OBJECT (demux, "invalid header version detected");
      ret = GST_FLOW_EOS;
      goto beach;
    }

  }

  /* Now look at audio/video flags */
  {
    guint8 flags = map.data[4];

    demux->has_video = demux->has_audio = FALSE;

    if (flags & 1) {
      GST_DEBUG_OBJECT (demux, "there is a video stream");
      demux->has_video = TRUE;
    }
    if (flags & 4) {
      GST_DEBUG_OBJECT (demux, "there is an audio stream");
      demux->has_audio = TRUE;
    }
  }

  /* do a one-time seekability check */
  gst_flv_demux_check_seekability (demux);

  /* We don't care about the rest */
  demux->need_header = FALSE;

beach:
  gst_buffer_unmap (buffer, &map);
  return ret;
}


static void
gst_flv_demux_flush (GstFlvDemux * demux, gboolean discont)
{
  GST_DEBUG_OBJECT (demux, "flushing queued data in the FLV demuxer");

  gst_adapter_clear (demux->adapter);

  demux->audio_need_discont = TRUE;
  demux->video_need_discont = TRUE;

  demux->flushing = FALSE;

  /* Only in push mode and if we're not during a seek */
  if (!demux->random_access && demux->state != FLV_STATE_SEEK) {
    /* After a flush we expect a tag_type */
    demux->state = FLV_STATE_TAG_TYPE;
    /* We reset the offset and will get one from first push */
    demux->offset = 0;
  }
}

static void
gst_flv_demux_cleanup (GstFlvDemux * demux)
{
  GST_DEBUG_OBJECT (demux, "cleaning up FLV demuxer");

  demux->state = FLV_STATE_HEADER;

  demux->have_group_id = FALSE;
  demux->group_id = G_MAXUINT;

  demux->flushing = FALSE;
  demux->need_header = TRUE;
  demux->audio_need_segment = TRUE;
  demux->video_need_segment = TRUE;
  demux->audio_need_discont = TRUE;
  demux->video_need_discont = TRUE;

  /* By default we consider them as linked */
  demux->audio_linked = TRUE;
  demux->video_linked = TRUE;

  demux->has_audio = FALSE;
  demux->has_video = FALSE;
  demux->push_tags = FALSE;
  demux->got_par = FALSE;

  demux->indexed = FALSE;
  demux->upstream_seekable = FALSE;
  demux->file_size = 0;

  demux->index_max_pos = 0;
  demux->index_max_time = 0;

  demux->audio_start = demux->video_start = GST_CLOCK_TIME_NONE;
  demux->last_audio_pts = demux->last_video_pts = 0;
  demux->audio_time_offset = demux->video_time_offset = 0;

  demux->no_more_pads = FALSE;

  gst_segment_init (&demux->segment, GST_FORMAT_TIME);

  demux->w = demux->h = 0;
  demux->framerate = 0.0;
  demux->par_x = demux->par_y = 1;
  demux->video_offset = 0;
  demux->audio_offset = 0;
  demux->offset = demux->cur_tag_offset = 0;
  demux->tag_size = demux->tag_data_size = 0;
  demux->duration = GST_CLOCK_TIME_NONE;

  if (demux->new_seg_event) {
    gst_event_unref (demux->new_seg_event);
    demux->new_seg_event = NULL;
  }

  gst_adapter_clear (demux->adapter);

  if (demux->audio_codec_data) {
    gst_buffer_unref (demux->audio_codec_data);
    demux->audio_codec_data = NULL;
  }

  if (demux->video_codec_data) {
    gst_buffer_unref (demux->video_codec_data);
    demux->video_codec_data = NULL;
  }

  if (demux->audio_pad) {
    gst_element_remove_pad (GST_ELEMENT (demux), demux->audio_pad);
    gst_object_unref (demux->audio_pad);
    demux->audio_pad = NULL;
  }

  if (demux->video_pad) {
    gst_element_remove_pad (GST_ELEMENT (demux), demux->video_pad);
    gst_object_unref (demux->video_pad);
    demux->video_pad = NULL;
  }

  if (demux->times) {
    g_array_free (demux->times, TRUE);
    demux->times = NULL;
  }

  if (demux->filepositions) {
    g_array_free (demux->filepositions, TRUE);
    demux->filepositions = NULL;
  }
}

/*
 * Create and push a flushing seek event upstream
 */
static gboolean
flv_demux_seek_to_offset (GstFlvDemux * demux, guint64 offset)
{
  GstEvent *event;
  gboolean res = 0;

  GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset);

  event =
      gst_event_new_seek (1.0, GST_FORMAT_BYTES,
      GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
      GST_SEEK_TYPE_NONE, -1);

  res = gst_pad_push_event (demux->sinkpad, event);

  if (res)
    demux->offset = offset;
  return res;
}

static GstFlowReturn
gst_flv_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstFlvDemux *demux = NULL;

  demux = GST_FLV_DEMUX (parent);

  GST_LOG_OBJECT (demux,
      "received buffer of %" G_GSIZE_FORMAT " bytes at offset %"
      G_GUINT64_FORMAT, gst_buffer_get_size (buffer),
      GST_BUFFER_OFFSET (buffer));

  if (G_UNLIKELY (GST_BUFFER_OFFSET (buffer) == 0)) {
    GST_DEBUG_OBJECT (demux, "beginning of file, expect header");
    demux->state = FLV_STATE_HEADER;
    demux->offset = 0;
  }

  if (G_UNLIKELY (demux->offset == 0 && GST_BUFFER_OFFSET (buffer) != 0)) {
    GST_DEBUG_OBJECT (demux, "offset was zero, synchronizing with buffer's");
    demux->offset = GST_BUFFER_OFFSET (buffer);
  }

  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
    GST_DEBUG_OBJECT (demux, "Discontinuity");
    gst_adapter_clear (demux->adapter);
  }

  gst_adapter_push (demux->adapter, buffer);

  if (demux->seeking) {
    demux->state = FLV_STATE_SEEK;
    GST_OBJECT_LOCK (demux);
    demux->seeking = FALSE;
    GST_OBJECT_UNLOCK (demux);
  }

parse:
  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    if (ret == GST_FLOW_NOT_LINKED && (demux->audio_linked
            || demux->video_linked)) {
      ret = GST_FLOW_OK;
    } else {
      GST_DEBUG_OBJECT (demux, "got flow return %s", gst_flow_get_name (ret));
      goto beach;
    }
  }

  if (G_UNLIKELY (demux->flushing)) {
    GST_DEBUG_OBJECT (demux, "we are now flushing, exiting parser loop");
    ret = GST_FLOW_FLUSHING;
    goto beach;
  }

  switch (demux->state) {
    case FLV_STATE_HEADER:
    {
      if (gst_adapter_available (demux->adapter) >= FLV_HEADER_SIZE) {
        GstBuffer *buffer;

        buffer = gst_adapter_take_buffer (demux->adapter, FLV_HEADER_SIZE);

        ret = gst_flv_demux_parse_header (demux, buffer);

        gst_buffer_unref (buffer);
        demux->offset += FLV_HEADER_SIZE;

        demux->state = FLV_STATE_TAG_TYPE;
        goto parse;
      } else {
        goto beach;
      }
    }
    case FLV_STATE_TAG_TYPE:
    {
      if (gst_adapter_available (demux->adapter) >= FLV_TAG_TYPE_SIZE) {
        GstBuffer *buffer;

        /* Remember the tag offset in bytes */
        demux->cur_tag_offset = demux->offset;

        buffer = gst_adapter_take_buffer (demux->adapter, FLV_TAG_TYPE_SIZE);

        ret = gst_flv_demux_parse_tag_type (demux, buffer);

        gst_buffer_unref (buffer);
        demux->offset += FLV_TAG_TYPE_SIZE;

        /* last tag is not an index => no index/don't know where the index is
         * seek back to the beginning */
        if (demux->seek_event && demux->state != FLV_STATE_TAG_SCRIPT)
          goto no_index;

        goto parse;
      } else {
        goto beach;
      }
    }
    case FLV_STATE_TAG_VIDEO:
    {
      if (gst_adapter_available (demux->adapter) >= demux->tag_size) {
        GstBuffer *buffer;

        buffer = gst_adapter_take_buffer (demux->adapter, demux->tag_size);

        ret = gst_flv_demux_parse_tag_video (demux, buffer);

        gst_buffer_unref (buffer);
        demux->offset += demux->tag_size;

        demux->state = FLV_STATE_TAG_TYPE;
        goto parse;
      } else {
        goto beach;
      }
    }
    case FLV_STATE_TAG_AUDIO:
    {
      if (gst_adapter_available (demux->adapter) >= demux->tag_size) {
        GstBuffer *buffer;

        buffer = gst_adapter_take_buffer (demux->adapter, demux->tag_size);

        ret = gst_flv_demux_parse_tag_audio (demux, buffer);

        gst_buffer_unref (buffer);
        demux->offset += demux->tag_size;

        demux->state = FLV_STATE_TAG_TYPE;
        goto parse;
      } else {
        goto beach;
      }
    }
    case FLV_STATE_TAG_SCRIPT:
    {
      if (gst_adapter_available (demux->adapter) >= demux->tag_size) {
        GstBuffer *buffer;

        buffer = gst_adapter_take_buffer (demux->adapter, demux->tag_size);

        ret = gst_flv_demux_parse_tag_script (demux, buffer);

        gst_buffer_unref (buffer);
        demux->offset += demux->tag_size;

        demux->state = FLV_STATE_TAG_TYPE;

        /* if there's a seek event we're here for the index so if we don't have it
         * we seek back to the beginning */
        if (demux->seek_event) {
          if (demux->indexed)
            demux->state = FLV_STATE_SEEK;
          else
            goto no_index;
        }

        goto parse;
      } else {
        goto beach;
      }
    }
    case FLV_STATE_SEEK:
    {
      GstEvent *event;

      ret = GST_FLOW_OK;

      if (!demux->indexed) {
        if (demux->offset == demux->file_size - sizeof (guint32)) {
          guint64 seek_offset;
          guint8 *data;

          data = gst_adapter_take (demux->adapter, 4);
          if (!data)
            goto no_index;

          seek_offset = demux->file_size - sizeof (guint32) -
              GST_READ_UINT32_BE (data);
          g_free (data);

          GST_INFO_OBJECT (demux,
              "Seeking to beginning of last tag at %" G_GUINT64_FORMAT,
              seek_offset);
          demux->state = FLV_STATE_TAG_TYPE;
          flv_demux_seek_to_offset (demux, seek_offset);
          goto beach;
        } else
          goto no_index;
      }

      GST_OBJECT_LOCK (demux);
      event = demux->seek_event;
      demux->seek_event = NULL;
      GST_OBJECT_UNLOCK (demux);

      /* calculate and perform seek */
      if (!flv_demux_handle_seek_push (demux, event))
        goto seek_failed;

      gst_event_unref (event);
      demux->state = FLV_STATE_TAG_TYPE;
      goto beach;
    }
    default:
      GST_DEBUG_OBJECT (demux, "unexpected demuxer state");
  }

beach:
  if (G_UNLIKELY (ret == GST_FLOW_NOT_LINKED)) {
    /* If either audio or video is linked we return GST_FLOW_OK */
    if (demux->audio_linked || demux->video_linked) {
      ret = GST_FLOW_OK;
    }
  }

  return ret;

/* ERRORS */
no_index:
  {
    GST_OBJECT_LOCK (demux);
    demux->seeking = FALSE;
    gst_event_unref (demux->seek_event);
    demux->seek_event = NULL;
    GST_OBJECT_UNLOCK (demux);
    GST_WARNING_OBJECT (demux,
        "failed to find an index, seeking back to beginning");
    flv_demux_seek_to_offset (demux, 0);
    return GST_FLOW_OK;
  }
seek_failed:
  {
    GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("seek failed"));
    return GST_FLOW_ERROR;
  }

}

static GstFlowReturn
gst_flv_demux_pull_range (GstFlvDemux * demux, GstPad * pad, guint64 offset,
    guint size, GstBuffer ** buffer)
{
  GstFlowReturn ret;

  ret = gst_pad_pull_range (pad, offset, size, buffer);
  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    GST_WARNING_OBJECT (demux,
        "failed when pulling %d bytes from offset %" G_GUINT64_FORMAT ": %s",
        size, offset, gst_flow_get_name (ret));
    *buffer = NULL;
    return ret;
  }

  if (G_UNLIKELY (*buffer && gst_buffer_get_size (*buffer) != size)) {
    GST_WARNING_OBJECT (demux,
        "partial pull got %" G_GSIZE_FORMAT " when expecting %d from offset %"
        G_GUINT64_FORMAT, gst_buffer_get_size (*buffer), size, offset);
    gst_buffer_unref (*buffer);
    ret = GST_FLOW_EOS;
    *buffer = NULL;
    return ret;
  }

  return ret;
}

static GstFlowReturn
gst_flv_demux_pull_tag (GstPad * pad, GstFlvDemux * demux)
{
  GstBuffer *buffer = NULL;
  GstFlowReturn ret = GST_FLOW_OK;

  /* Store tag offset */
  demux->cur_tag_offset = demux->offset;

  /* Get the first 4 bytes to identify tag type and size */
  if (G_UNLIKELY ((ret = gst_flv_demux_pull_range (demux, pad, demux->offset,
                  FLV_TAG_TYPE_SIZE, &buffer)) != GST_FLOW_OK))
    goto beach;

  /* Identify tag type */
  ret = gst_flv_demux_parse_tag_type (demux, buffer);

  gst_buffer_unref (buffer);

  if (G_UNLIKELY (ret != GST_FLOW_OK))
    goto beach;

  /* Jump over tag type + size */
  demux->offset += FLV_TAG_TYPE_SIZE;

  /* Pull the whole tag */
  buffer = NULL;
  if (G_UNLIKELY ((ret = gst_flv_demux_pull_range (demux, pad, demux->offset,
                  demux->tag_size, &buffer)) != GST_FLOW_OK))
    goto beach;

  switch (demux->state) {
    case FLV_STATE_TAG_VIDEO:
      ret = gst_flv_demux_parse_tag_video (demux, buffer);
      break;
    case FLV_STATE_TAG_AUDIO:
      ret = gst_flv_demux_parse_tag_audio (demux, buffer);
      break;
    case FLV_STATE_TAG_SCRIPT:
      ret = gst_flv_demux_parse_tag_script (demux, buffer);
      break;
    default:
      GST_WARNING_OBJECT (demux, "unexpected state %d", demux->state);
  }

  gst_buffer_unref (buffer);

  /* Jump over that part we've just parsed */
  demux->offset += demux->tag_size;

  /* Make sure we reinitialize the tag size */
  demux->tag_size = 0;

  /* Ready for the next tag */
  demux->state = FLV_STATE_TAG_TYPE;

  if (G_UNLIKELY (ret == GST_FLOW_NOT_LINKED)) {
    /* If either audio or video is linked we return GST_FLOW_OK */
    if (demux->audio_linked || demux->video_linked) {
      ret = GST_FLOW_OK;
    } else {
      GST_WARNING_OBJECT (demux, "parsing this tag returned not-linked and "
          "neither video nor audio are linked");
    }
  }

beach:
  return ret;
}

static GstFlowReturn
gst_flv_demux_pull_header (GstPad * pad, GstFlvDemux * demux)
{
  GstBuffer *buffer = NULL;
  GstFlowReturn ret = GST_FLOW_OK;

  /* Get the first 9 bytes */
  if (G_UNLIKELY ((ret = gst_flv_demux_pull_range (demux, pad, demux->offset,
                  FLV_HEADER_SIZE, &buffer)) != GST_FLOW_OK))
    goto beach;

  ret = gst_flv_demux_parse_header (demux, buffer);

  gst_buffer_unref (buffer);

  /* Jump over the header now */
  demux->offset += FLV_HEADER_SIZE;
  demux->state = FLV_STATE_TAG_TYPE;

beach:
  return ret;
}

static void
gst_flv_demux_move_to_offset (GstFlvDemux * demux, gint64 offset,
    gboolean reset)
{
  demux->offset = offset;

  /* Tell all the stream we moved to a different position (discont) */
  demux->audio_need_discont = TRUE;
  demux->video_need_discont = TRUE;

  /* next section setup */
  demux->from_offset = -1;
  demux->audio_done = demux->video_done = FALSE;
  demux->audio_first_ts = demux->video_first_ts = GST_CLOCK_TIME_NONE;

  if (reset) {
    demux->from_offset = -1;
    demux->to_offset = G_MAXINT64;
  }

  /* If we seeked at the beginning of the file parse the header again */
  if (G_UNLIKELY (!demux->offset)) {
    demux->state = FLV_STATE_HEADER;
  } else {                      /* or parse a tag */
    demux->state = FLV_STATE_TAG_TYPE;
  }
}

static GstFlowReturn
gst_flv_demux_seek_to_prev_keyframe (GstFlvDemux * demux)
{
  GstFlowReturn ret = GST_FLOW_EOS;
  GstIndex *index;
  GstIndexEntry *entry = NULL;

  GST_DEBUG_OBJECT (demux,
      "terminated section started at offset %" G_GINT64_FORMAT,
      demux->from_offset);

  /* we are done if we got all audio and video */
  if ((!GST_CLOCK_TIME_IS_VALID (demux->audio_first_ts) ||
          demux->audio_first_ts < demux->segment.start) &&
      (!GST_CLOCK_TIME_IS_VALID (demux->video_first_ts) ||
          demux->video_first_ts < demux->segment.start))
    goto done;

  if (demux->from_offset <= 0)
    goto done;

  GST_DEBUG_OBJECT (demux, "locating previous position");

  index = gst_flv_demux_get_index (GST_ELEMENT (demux));

  /* locate index entry before previous start position */
  if (index) {
    entry = gst_index_get_assoc_entry (index, demux->index_id,
        GST_INDEX_LOOKUP_BEFORE, GST_ASSOCIATION_FLAG_KEY_UNIT,
        GST_FORMAT_BYTES, demux->from_offset - 1);

    if (entry) {
      gint64 bytes = 0, time = 0;

      gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &bytes);
      gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time);

      GST_DEBUG_OBJECT (demux, "found index entry for %" G_GINT64_FORMAT
          " at %" GST_TIME_FORMAT ", seeking to %" G_GINT64_FORMAT,
          demux->offset - 1, GST_TIME_ARGS (time), bytes);

      /* setup for next section */
      demux->to_offset = demux->from_offset;
      gst_flv_demux_move_to_offset (demux, bytes, FALSE);
      ret = GST_FLOW_OK;
    }

    gst_object_unref (index);
  }


done:
  return ret;
}

static GstFlowReturn
gst_flv_demux_create_index (GstFlvDemux * demux, gint64 pos, GstClockTime ts)
{
  gint64 size;
  size_t tag_size;
  guint64 old_offset;
  GstBuffer *buffer;
  GstClockTime tag_time;
  GstFlowReturn ret = GST_FLOW_OK;

  if (!gst_pad_peer_query_duration (demux->sinkpad, GST_FORMAT_BYTES, &size))
    return GST_FLOW_OK;

  GST_DEBUG_OBJECT (demux, "building index at %" G_GINT64_FORMAT
      " looking for time %" GST_TIME_FORMAT, pos, GST_TIME_ARGS (ts));

  old_offset = demux->offset;
  demux->offset = pos;

  buffer = NULL;
  while ((ret = gst_flv_demux_pull_range (demux, demux->sinkpad, demux->offset,
              12, &buffer)) == GST_FLOW_OK) {
    tag_time =
        gst_flv_demux_parse_tag_timestamp (demux, TRUE, buffer, &tag_size);

    gst_buffer_unref (buffer);
    buffer = NULL;

    if (G_UNLIKELY (tag_time == GST_CLOCK_TIME_NONE || tag_time > ts))
      goto exit;

    demux->offset += tag_size;
  }

  if (ret == GST_FLOW_EOS) {
    /* file ran out, so mark we have complete index */
    demux->indexed = TRUE;
    ret = GST_FLOW_OK;
  }

exit:
  demux->offset = old_offset;

  return ret;
}

static gint64
gst_flv_demux_get_metadata (GstFlvDemux * demux)
{
  gint64 ret = 0, offset;
  size_t tag_size, size;
  GstBuffer *buffer = NULL;
  GstMapInfo map;

  if (!gst_pad_peer_query_duration (demux->sinkpad, GST_FORMAT_BYTES, &offset))
    goto exit;

  ret = offset;
  GST_DEBUG_OBJECT (demux, "upstream size: %" G_GINT64_FORMAT, offset);
  if (G_UNLIKELY (offset < 4))
    goto exit;

  offset -= 4;
  if (GST_FLOW_OK != gst_flv_demux_pull_range (demux, demux->sinkpad, offset,
          4, &buffer))
    goto exit;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  tag_size = GST_READ_UINT32_BE (map.data);
  gst_buffer_unmap (buffer, &map);
  GST_DEBUG_OBJECT (demux, "last tag size: %" G_GSIZE_FORMAT, tag_size);
  gst_buffer_unref (buffer);
  buffer = NULL;

  offset -= tag_size;
  if (GST_FLOW_OK != gst_flv_demux_pull_range (demux, demux->sinkpad, offset,
          12, &buffer))
    goto exit;

  /* a consistency check */
  gst_buffer_map (buffer, &map, GST_MAP_READ);
  size = GST_READ_UINT24_BE (map.data + 1);
  if (size != tag_size - 11) {
    gst_buffer_unmap (buffer, &map);
    GST_DEBUG_OBJECT (demux,
        "tag size %" G_GSIZE_FORMAT ", expected %" G_GSIZE_FORMAT
        ", corrupt or truncated file", size, tag_size - 11);
    goto exit;
  }

  /* try to update duration with timestamp in any case */
  gst_flv_demux_parse_tag_timestamp (demux, FALSE, buffer, &size);

  /* maybe get some more metadata */
  if (map.data[0] == 18) {
    gst_buffer_unmap (buffer, &map);
    gst_buffer_unref (buffer);
    buffer = NULL;
    GST_DEBUG_OBJECT (demux, "script tag, pulling it to parse");
    offset += 4;
    if (GST_FLOW_OK == gst_flv_demux_pull_range (demux, demux->sinkpad, offset,
            tag_size, &buffer))
      gst_flv_demux_parse_tag_script (demux, buffer);
  } else {
    gst_buffer_unmap (buffer, &map);
  }

exit:
  if (buffer)
    gst_buffer_unref (buffer);

  return ret;
}

static void
gst_flv_demux_loop (GstPad * pad)
{
  GstFlvDemux *demux = NULL;
  GstFlowReturn ret = GST_FLOW_OK;

  demux = GST_FLV_DEMUX (gst_pad_get_parent (pad));

  /* pull in data */
  switch (demux->state) {
    case FLV_STATE_TAG_TYPE:
      if (demux->from_offset == -1)
        demux->from_offset = demux->offset;
      ret = gst_flv_demux_pull_tag (pad, demux);
      /* if we have seen real data, we probably passed a possible metadata
       * header located at start.  So if we do not yet have an index,
       * try to pick up metadata (index, duration) at the end */
      if (G_UNLIKELY (!demux->file_size && !demux->indexed &&
              (demux->has_video || demux->has_audio)))
        demux->file_size = gst_flv_demux_get_metadata (demux);
      break;
    case FLV_STATE_DONE:
      ret = GST_FLOW_EOS;
      break;
    case FLV_STATE_SEEK:
      /* seek issued with insufficient index;
       * scan for index in task thread from current maximum offset to
       * desired time and then perform seek */
      /* TODO maybe some buffering message or so to indicate scan progress */
      ret = gst_flv_demux_create_index (demux, demux->index_max_pos,
          demux->seek_time);
      if (ret != GST_FLOW_OK)
        goto pause;
      /* position and state arranged by seek,
       * also unrefs event */
      gst_flv_demux_handle_seek_pull (demux, demux->seek_event, FALSE);
      demux->seek_event = NULL;
      break;
    default:
      ret = gst_flv_demux_pull_header (pad, demux);
      /* index scans start after header */
      demux->index_max_pos = demux->offset;
      break;
  }

  if (demux->segment.rate < 0.0) {
    /* check end of section */
    if ((gint64) demux->offset >= demux->to_offset ||
        demux->segment.position >= demux->segment.stop + 2 * GST_SECOND ||
        (demux->audio_done && demux->video_done))
      ret = gst_flv_demux_seek_to_prev_keyframe (demux);
  } else {
    /* check EOS condition */
    if ((demux->segment.stop != -1) &&
        (demux->segment.position >= demux->segment.stop)) {
      ret = GST_FLOW_EOS;
    }
  }

  /* pause if something went wrong or at end */
  if (G_UNLIKELY (ret != GST_FLOW_OK))
    goto pause;

  gst_object_unref (demux);

  return;

pause:
  {
    const gchar *reason = gst_flow_get_name (ret);

    GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
    gst_pad_pause_task (pad);

    if (ret == GST_FLOW_EOS) {
      /* handle end-of-stream/segment */
      /* so align our position with the end of it, if there is one
       * this ensures a subsequent will arrive at correct base/acc time */
      if (demux->segment.rate > 0.0 &&
          GST_CLOCK_TIME_IS_VALID (demux->segment.stop))
        demux->segment.position = demux->segment.stop;
      else if (demux->segment.rate < 0.0)
        demux->segment.position = demux->segment.start;

      /* perform EOS logic */
      if (!demux->no_more_pads) {
        gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
        demux->no_more_pads = TRUE;
      }

      if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
        gint64 stop;

        /* for segment playback we need to post when (in stream time)
         * we stopped, this is either stop (when set) or the duration. */
        if ((stop = demux->segment.stop) == -1)
          stop = demux->segment.duration;

        if (demux->segment.rate >= 0) {
          GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
          gst_element_post_message (GST_ELEMENT_CAST (demux),
              gst_message_new_segment_done (GST_OBJECT_CAST (demux),
                  GST_FORMAT_TIME, stop));
          gst_flv_demux_push_src_event (demux,
              gst_event_new_segment_done (GST_FORMAT_TIME, stop));
        } else {                /* Reverse playback */
          GST_LOG_OBJECT (demux, "Sending segment done, at beginning of "
              "segment");
          gst_element_post_message (GST_ELEMENT_CAST (demux),
              gst_message_new_segment_done (GST_OBJECT_CAST (demux),
                  GST_FORMAT_TIME, demux->segment.start));
          gst_flv_demux_push_src_event (demux,
              gst_event_new_segment_done (GST_FORMAT_TIME,
                  demux->segment.start));
        }
      } else {
        /* normal playback, send EOS to all linked pads */
        if (!demux->no_more_pads) {
          gst_element_no_more_pads (GST_ELEMENT (demux));
          demux->no_more_pads = TRUE;
        }

        GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
        if (!demux->audio_pad && !demux->video_pad)
          GST_ELEMENT_ERROR (demux, STREAM, FAILED,
              ("Internal data stream error."), ("Got EOS before any data"));
        else if (!gst_flv_demux_push_src_event (demux, gst_event_new_eos ()))
          GST_WARNING_OBJECT (demux, "failed pushing EOS on streams");
      }
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
      GST_ELEMENT_ERROR (demux, STREAM, FAILED,
          ("Internal data stream error."),
          ("stream stopped, reason %s", reason));
      gst_flv_demux_push_src_event (demux, gst_event_new_eos ());
    }
    gst_object_unref (demux);
    return;
  }
}

static guint64
gst_flv_demux_find_offset (GstFlvDemux * demux, GstSegment * segment)
{
  gint64 bytes = 0;
  gint64 time = 0;
  GstIndex *index;
  GstIndexEntry *entry;

  g_return_val_if_fail (segment != NULL, 0);

  time = segment->position;

  index = gst_flv_demux_get_index (GST_ELEMENT (demux));

  if (index) {
    /* Let's check if we have an index entry for that seek time */
    entry = gst_index_get_assoc_entry (index, demux->index_id,
        GST_INDEX_LOOKUP_BEFORE, GST_ASSOCIATION_FLAG_KEY_UNIT,
        GST_FORMAT_TIME, time);

    if (entry) {
      gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &bytes);
      gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time);

      GST_DEBUG_OBJECT (demux, "found index entry for %" GST_TIME_FORMAT
          " at %" GST_TIME_FORMAT ", seeking to %" G_GINT64_FORMAT,
          GST_TIME_ARGS (segment->position), GST_TIME_ARGS (time), bytes);

      /* Key frame seeking */
      if (segment->flags & GST_SEEK_FLAG_KEY_UNIT) {
        /* Adjust the segment so that the keyframe fits in */
        if (time < segment->start) {
          segment->start = segment->time = time;
        }
        segment->position = time;
      }
    } else {
      GST_DEBUG_OBJECT (demux, "no index entry found for %" GST_TIME_FORMAT,
          GST_TIME_ARGS (segment->start));
    }

    gst_object_unref (index);
  }

  return bytes;
}

static gboolean
flv_demux_handle_seek_push (GstFlvDemux * demux, GstEvent * event)
{
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  gdouble rate;
  gboolean update, flush, ret;
  GstSegment seeksegment;

  gst_event_parse_seek (event, &rate, &format, &flags,
      &start_type, &start, &stop_type, &stop);

  if (format != GST_FORMAT_TIME)
    goto wrong_format;

  flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
  /* FIXME : the keyframe flag is never used ! */

  /* Work on a copy until we are sure the seek succeeded. */
  memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));

  GST_DEBUG_OBJECT (demux, "segment before configure %" GST_SEGMENT_FORMAT,
      &demux->segment);

  /* Apply the seek to our segment */
  gst_segment_do_seek (&seeksegment, rate, format, flags,
      start_type, start, stop_type, stop, &update);

  GST_DEBUG_OBJECT (demux, "segment configured %" GST_SEGMENT_FORMAT,
      &seeksegment);

  if (flush || seeksegment.position != demux->segment.position) {
    /* Do the actual seeking */
    guint64 offset = gst_flv_demux_find_offset (demux, &seeksegment);

    GST_DEBUG_OBJECT (demux, "generating an upstream seek at position %"
        G_GUINT64_FORMAT, offset);
    ret = gst_pad_push_event (demux->sinkpad,
        gst_event_new_seek (seeksegment.rate, GST_FORMAT_BYTES,
            seeksegment.flags | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET,
            offset, GST_SEEK_TYPE_NONE, 0));
    if (G_UNLIKELY (!ret)) {
      GST_WARNING_OBJECT (demux, "upstream seek failed");
    }

    /* Tell all the stream we moved to a different position (discont) */
    demux->audio_need_discont = TRUE;
    demux->video_need_discont = TRUE;
  } else {
    ret = TRUE;
  }

  if (ret) {
    /* Ok seek succeeded, take the newly configured segment */
    memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));

    /* Tell all the stream a new segment is needed */
    demux->audio_need_segment = TRUE;
    demux->video_need_segment = TRUE;
    /* Clean any potential newsegment event kept for the streams. The first
     * stream needing a new segment will create a new one. */
    if (G_UNLIKELY (demux->new_seg_event)) {
      gst_event_unref (demux->new_seg_event);
      demux->new_seg_event = NULL;
    }
    gst_event_unref (event);
  } else {
    ret = gst_pad_push_event (demux->sinkpad, event);
  }

  return ret;

/* ERRORS */
wrong_format:
  {
    GST_WARNING_OBJECT (demux, "we only support seeking in TIME format");
    gst_event_unref (event);
    return FALSE;
  }
}

static gboolean
gst_flv_demux_handle_seek_push (GstFlvDemux * demux, GstEvent * event)
{
  GstFormat format;

  gst_event_parse_seek (event, NULL, &format, NULL, NULL, NULL, NULL, NULL);

  if (format != GST_FORMAT_TIME) {
    GST_WARNING_OBJECT (demux, "we only support seeking in TIME format");
    gst_event_unref (event);
    return FALSE;
  }

  /* First try upstream */
  if (gst_pad_push_event (demux->sinkpad, gst_event_ref (event))) {
    GST_DEBUG_OBJECT (demux, "Upstream successfully seeked");
    gst_event_unref (event);
    return TRUE;
  }

  if (!demux->indexed) {
    guint64 seek_offset = 0;
    gboolean building_index;

    GST_OBJECT_LOCK (demux);
    /* handle the seek in the chain function */
    demux->seeking = TRUE;
    demux->state = FLV_STATE_SEEK;

    /* copy the event */
    if (demux->seek_event)
      gst_event_unref (demux->seek_event);
    demux->seek_event = gst_event_ref (event);

    /* set the building_index flag so that only one thread can setup the
     * structures for index seeking. */
    building_index = demux->building_index;
    if (!building_index) {
      demux->building_index = TRUE;
      if (!demux->file_size
          && !gst_pad_peer_query_duration (demux->sinkpad, GST_FORMAT_BYTES,
              &demux->file_size)) {
        GST_WARNING_OBJECT (demux, "Failed to query upstream file size");
        GST_OBJECT_UNLOCK (demux);
        return FALSE;
      }

      /* we hope the last tag is a scriptdataobject containing an index
       * the size of the last tag is given in the last guint32 bits
       * then we seek to the beginning of the tag, parse it and hopefully obtain an index */
      seek_offset = demux->file_size - sizeof (guint32);
      GST_DEBUG_OBJECT (demux,
          "File size obtained, seeking to %" G_GUINT64_FORMAT, seek_offset);
    }
    GST_OBJECT_UNLOCK (demux);

    if (!building_index) {
      GST_INFO_OBJECT (demux, "Seeking to last 4 bytes at %" G_GUINT64_FORMAT,
          seek_offset);
      return flv_demux_seek_to_offset (demux, seek_offset);
    }

    /* FIXME: we have to always return true so that we don't block the seek
     * thread.
     * Note: maybe it is OK to return true if we're still building the index */
    return TRUE;
  }

  return flv_demux_handle_seek_push (demux, event);
}

static gboolean
gst_flv_demux_handle_seek_pull (GstFlvDemux * demux, GstEvent * event,
    gboolean seeking)
{
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  gdouble rate;
  gboolean update, flush, ret = FALSE;
  GstSegment seeksegment;

  gst_event_parse_seek (event, &rate, &format, &flags,
      &start_type, &start, &stop_type, &stop);

  if (format != GST_FORMAT_TIME)
    goto wrong_format;

  /* mark seeking thread entering flushing/pausing */
  GST_OBJECT_LOCK (demux);
  if (seeking)
    demux->seeking = seeking;
  GST_OBJECT_UNLOCK (demux);

  flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
  /* FIXME : the keyframe flag is never used */

  if (flush) {
    /* Flush start up and downstream to make sure data flow and loops are
       idle */
    gst_flv_demux_push_src_event (demux, gst_event_new_flush_start ());
    gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
  } else {
    /* Pause the pulling task */
    gst_pad_pause_task (demux->sinkpad);
  }

  /* Take the stream lock */
  GST_PAD_STREAM_LOCK (demux->sinkpad);

  if (flush) {
    /* Stop flushing upstream we need to pull */
    gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop (TRUE));
  }

  /* Work on a copy until we are sure the seek succeeded. */
  memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));

  GST_DEBUG_OBJECT (demux, "segment before configure %" GST_SEGMENT_FORMAT,
      &demux->segment);

  /* Apply the seek to our segment */
  gst_segment_do_seek (&seeksegment, rate, format, flags,
      start_type, start, stop_type, stop, &update);

  GST_DEBUG_OBJECT (demux, "segment configured %" GST_SEGMENT_FORMAT,
      &seeksegment);

  if (flush || seeksegment.position != demux->segment.position) {
    /* Do the actual seeking */
    /* index is reliable if it is complete or we do not go to far ahead */
    if (seeking && !demux->indexed &&
        seeksegment.position > demux->index_max_time + 10 * GST_SECOND) {
      GST_DEBUG_OBJECT (demux, "delaying seek to post-scan; "
          " index only up to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (demux->index_max_time));
      /* stop flushing for now */
      if (flush)
        gst_flv_demux_push_src_event (demux, gst_event_new_flush_stop (TRUE));
      /* delegate scanning and index building to task thread to avoid
       * occupying main (UI) loop */
      if (demux->seek_event)
        gst_event_unref (demux->seek_event);
      demux->seek_event = gst_event_ref (event);
      demux->seek_time = seeksegment.position;
      demux->state = FLV_STATE_SEEK;
      /* do not know about succes yet, but we did care and handled it */
      ret = TRUE;
      goto exit;
    }
    /* now index should be as reliable as it can be for current purpose */
    gst_flv_demux_move_to_offset (demux,
        gst_flv_demux_find_offset (demux, &seeksegment), TRUE);
    ret = TRUE;
  } else {
    ret = TRUE;
  }

  if (flush) {
    /* Stop flushing, the sinks are at time 0 now */
    gst_flv_demux_push_src_event (demux, gst_event_new_flush_stop (TRUE));
  }

  if (ret) {
    /* Ok seek succeeded, take the newly configured segment */
    memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));

    /* Notify about the start of a new segment */
    if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
      gst_element_post_message (GST_ELEMENT (demux),
          gst_message_new_segment_start (GST_OBJECT (demux),
              demux->segment.format, demux->segment.position));
    }

    /* Tell all the stream a new segment is needed */
    demux->audio_need_segment = TRUE;
    demux->video_need_segment = TRUE;
    /* Clean any potential newsegment event kept for the streams. The first
     * stream needing a new segment will create a new one. */
    if (G_UNLIKELY (demux->new_seg_event)) {
      gst_event_unref (demux->new_seg_event);
      demux->new_seg_event = NULL;
    }
    if (demux->segment.rate < 0.0) {
      /* we can't generate a segment by locking on
       * to the first timestamp we see */
      GST_DEBUG_OBJECT (demux, "preparing newsegment from %"
          GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (demux->segment.start),
          GST_TIME_ARGS (demux->segment.stop));
      demux->new_seg_event = gst_event_new_segment (&demux->segment);
    }
  }

exit:
  GST_OBJECT_LOCK (demux);
  seeking = demux->seeking && !seeking;
  demux->seeking = FALSE;
  GST_OBJECT_UNLOCK (demux);

  /* if we detect an external seek having started (and possibly already having
   * flushed), do not restart task to give it a chance.
   * Otherwise external one's flushing will take care to pause task */
  if (seeking) {
    gst_pad_pause_task (demux->sinkpad);
  } else {
    gst_pad_start_task (demux->sinkpad,
        (GstTaskFunction) gst_flv_demux_loop, demux->sinkpad, NULL);
  }

  GST_PAD_STREAM_UNLOCK (demux->sinkpad);

  gst_event_unref (event);
  return ret;

  /* ERRORS */
wrong_format:
  {
    GST_WARNING_OBJECT (demux, "we only support seeking in TIME format");
    gst_event_unref (event);
    return ret;
  }
}

/* If we can pull that's prefered */
static gboolean
gst_flv_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
{
  GstQuery *query;
  gboolean pull_mode;

  query = gst_query_new_scheduling ();

  if (!gst_pad_peer_query (sinkpad, query)) {
    gst_query_unref (query);
    goto activate_push;
  }

  pull_mode = gst_query_has_scheduling_mode_with_flags (query,
      GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
  gst_query_unref (query);

  if (!pull_mode)
    goto activate_push;

  GST_DEBUG_OBJECT (sinkpad, "activating pull");
  return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);

activate_push:
  {
    GST_DEBUG_OBJECT (sinkpad, "activating push");
    return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
  }
}

static gboolean
gst_flv_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;
  GstFlvDemux *demux;

  demux = GST_FLV_DEMUX (parent);

  switch (mode) {
    case GST_PAD_MODE_PUSH:
      demux->random_access = FALSE;
      res = TRUE;
      break;
    case GST_PAD_MODE_PULL:
      if (active) {
        demux->random_access = TRUE;
        res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flv_demux_loop,
            sinkpad, NULL);
      } else {
        demux->random_access = FALSE;
        res = gst_pad_stop_task (sinkpad);
      }
      break;
    default:
      res = FALSE;
      break;
  }
  return res;
}

static gboolean
gst_flv_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstFlvDemux *demux;
  gboolean ret = FALSE;

  demux = GST_FLV_DEMUX (parent);

  GST_DEBUG_OBJECT (demux, "handling event %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      GST_DEBUG_OBJECT (demux, "trying to force chain function to exit");
      demux->flushing = TRUE;
      ret = gst_flv_demux_push_src_event (demux, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      GST_DEBUG_OBJECT (demux, "flushing FLV demuxer");
      gst_flv_demux_flush (demux, TRUE);
      ret = gst_flv_demux_push_src_event (demux, event);
      break;
    case GST_EVENT_EOS:
    {
      GstIndex *index;

      GST_DEBUG_OBJECT (demux, "received EOS");

      index = gst_flv_demux_get_index (GST_ELEMENT (demux));

      if (index) {
        GST_DEBUG_OBJECT (demux, "committing index");
        gst_index_commit (index, demux->index_id);
        gst_object_unref (index);
      }

      if (!demux->audio_pad && !demux->video_pad)
        GST_ELEMENT_ERROR (demux, STREAM, FAILED,
            ("Internal data stream error."), ("Got EOS before any data"));
      else {
        if (!demux->no_more_pads) {
          gst_element_no_more_pads (GST_ELEMENT (demux));
          demux->no_more_pads = TRUE;
        }

        if (!gst_flv_demux_push_src_event (demux, event))
          GST_WARNING_OBJECT (demux, "failed pushing EOS on streams");
      }
      ret = TRUE;
      break;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment in_segment;

      GST_DEBUG_OBJECT (demux, "received new segment");

      gst_event_copy_segment (event, &in_segment);

      if (in_segment.format == GST_FORMAT_TIME) {
        /* time segment, this is perfect, copy over the values. */
        memcpy (&demux->segment, &in_segment, sizeof (in_segment));

        GST_DEBUG_OBJECT (demux, "NEWSEGMENT: %" GST_SEGMENT_FORMAT,
            &demux->segment);

        /* and forward */
        ret = gst_flv_demux_push_src_event (demux, event);
      } else {
        /* non-time format */
        demux->audio_need_segment = TRUE;
        demux->video_need_segment = TRUE;
        ret = TRUE;
        gst_event_unref (event);
        if (demux->new_seg_event) {
          gst_event_unref (demux->new_seg_event);
          demux->new_seg_event = NULL;
        }
      }
      break;
    }
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

static gboolean
gst_flv_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstFlvDemux *demux;
  gboolean ret = FALSE;

  demux = GST_FLV_DEMUX (parent);

  GST_DEBUG_OBJECT (demux, "handling event %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      if (demux->random_access) {
        ret = gst_flv_demux_handle_seek_pull (demux, event, TRUE);
      } else {
        ret = gst_flv_demux_handle_seek_push (demux, event);
      }
      break;
    default:
      ret = gst_pad_push_event (demux->sinkpad, event);
      break;
  }

  return ret;
}

static gboolean
gst_flv_demux_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res = TRUE;
  GstFlvDemux *demux;

  demux = GST_FLV_DEMUX (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
    {
      GstFormat format;

      gst_query_parse_duration (query, &format, NULL);

      /* duration is time only */
      if (format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (demux, "duration query only supported for time "
            "format");
        res = FALSE;
        goto beach;
      }

      GST_DEBUG_OBJECT (pad, "duration query, replying %" GST_TIME_FORMAT,
          GST_TIME_ARGS (demux->duration));

      gst_query_set_duration (query, GST_FORMAT_TIME, demux->duration);

      break;
    }
    case GST_QUERY_POSITION:
    {
      GstFormat format;

      gst_query_parse_position (query, &format, NULL);

      /* position is time only */
      if (format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (demux, "position query only supported for time "
            "format");
        res = FALSE;
        goto beach;
      }

      GST_DEBUG_OBJECT (pad, "position query, replying %" GST_TIME_FORMAT,
          GST_TIME_ARGS (demux->segment.position));

      gst_query_set_position (query, GST_FORMAT_TIME, demux->segment.position);

      break;
    }

    case GST_QUERY_SEEKING:{
      GstFormat fmt;

      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);

      /* First ask upstream */
      if (fmt == GST_FORMAT_TIME && gst_pad_peer_query (demux->sinkpad, query)) {
        gboolean seekable;

        gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
        if (seekable) {
          res = TRUE;
          break;
        }
      }
      res = TRUE;
      /* FIXME, check index this way is not thread safe */
      if (fmt != GST_FORMAT_TIME || !demux->index) {
        gst_query_set_seeking (query, fmt, FALSE, -1, -1);
      } else if (demux->random_access) {
        gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0,
            demux->duration);
      } else {
        GstQuery *peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
        gboolean seekable = gst_pad_peer_query (demux->sinkpad, peerquery);

        if (seekable)
          gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);
        gst_query_unref (peerquery);

        if (seekable)
          gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0,
              demux->duration);
        else
          gst_query_set_seeking (query, GST_FORMAT_TIME, FALSE, -1, -1);
      }
      break;
    }
    case GST_QUERY_SEGMENT:
    {
      GstFormat format;
      gint64 start, stop;

      format = demux->segment.format;

      start =
          gst_segment_to_stream_time (&demux->segment, format,
          demux->segment.start);
      if ((stop = demux->segment.stop) == -1)
        stop = demux->segment.duration;
      else
        stop = gst_segment_to_stream_time (&demux->segment, format, stop);

      gst_query_set_segment (query, demux->segment.rate, format, start, stop);
      res = TRUE;
      break;
    }
    case GST_QUERY_LATENCY:
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

beach:

  return res;
}

static GstStateChangeReturn
gst_flv_demux_change_state (GstElement * element, GstStateChange transition)
{
  GstFlvDemux *demux;
  GstStateChangeReturn ret;

  demux = GST_FLV_DEMUX (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* If this is our own index destroy it as the
       * old entries might be wrong for the new stream */
      if (demux->own_index) {
        gst_object_unref (demux->index);
        demux->index = NULL;
        demux->own_index = FALSE;
      }

      /* If no index was created, generate one */
      if (G_UNLIKELY (!demux->index)) {
        GST_DEBUG_OBJECT (demux, "no index provided creating our own");

        demux->index = g_object_new (gst_mem_index_get_type (), NULL);

        gst_index_get_writer_id (demux->index, GST_OBJECT (demux),
            &demux->index_id);
        demux->own_index = TRUE;
      }
      gst_flv_demux_cleanup (demux);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_flv_demux_cleanup (demux);
      break;
    default:
      break;
  }

  return ret;
}

#if 0
static void
gst_flv_demux_set_index (GstElement * element, GstIndex * index)
{
  GstFlvDemux *demux = GST_FLV_DEMUX (element);
  GstIndex *old_index;

  GST_OBJECT_LOCK (demux);

  old_index = demux->index;

  if (index) {
    demux->index = gst_object_ref (index);
    demux->own_index = FALSE;
  } else
    demux->index = NULL;

  if (old_index)
    gst_object_unref (demux->index);

  gst_object_ref (index);

  GST_OBJECT_UNLOCK (demux);

  /* object lock might be taken again */
  if (index)
    gst_index_get_writer_id (index, GST_OBJECT (element), &demux->index_id);

  GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->index);

  gst_object_unref (index);
}
#endif

static GstIndex *
gst_flv_demux_get_index (GstElement * element)
{
  GstIndex *result = NULL;

  GstFlvDemux *demux = GST_FLV_DEMUX (element);

  GST_OBJECT_LOCK (demux);
  if (demux->index)
    result = gst_object_ref (demux->index);
  GST_OBJECT_UNLOCK (demux);

  return result;
}

static void
gst_flv_demux_dispose (GObject * object)
{
  GstFlvDemux *demux = GST_FLV_DEMUX (object);

  GST_DEBUG_OBJECT (demux, "disposing FLV demuxer");

  if (demux->adapter) {
    gst_adapter_clear (demux->adapter);
    g_object_unref (demux->adapter);
    demux->adapter = NULL;
  }

  if (demux->taglist) {
    gst_tag_list_unref (demux->taglist);
    demux->taglist = NULL;
  }

  if (demux->new_seg_event) {
    gst_event_unref (demux->new_seg_event);
    demux->new_seg_event = NULL;
  }

  if (demux->audio_codec_data) {
    gst_buffer_unref (demux->audio_codec_data);
    demux->audio_codec_data = NULL;
  }

  if (demux->video_codec_data) {
    gst_buffer_unref (demux->video_codec_data);
    demux->video_codec_data = NULL;
  }

  if (demux->audio_pad) {
    gst_object_unref (demux->audio_pad);
    demux->audio_pad = NULL;
  }

  if (demux->video_pad) {
    gst_object_unref (demux->video_pad);
    demux->video_pad = NULL;
  }

  if (demux->index) {
    gst_object_unref (demux->index);
    demux->index = NULL;
  }

  if (demux->times) {
    g_array_free (demux->times, TRUE);
    demux->times = NULL;
  }

  if (demux->filepositions) {
    g_array_free (demux->filepositions, TRUE);
    demux->filepositions = NULL;
  }

  GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
}

static void
gst_flv_demux_class_init (GstFlvDemuxClass * klass)
{
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->dispose = gst_flv_demux_dispose;

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_flv_demux_change_state);

#if 0
  gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_flv_demux_set_index);
  gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_flv_demux_get_index);
#endif

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&flv_sink_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&audio_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&video_src_template));
  gst_element_class_set_static_metadata (gstelement_class, "FLV Demuxer",
      "Codec/Demuxer",
      "Demux FLV feeds into digital streams",
      "Julien Moutte <julien@moutte.net>");
}

static void
gst_flv_demux_init (GstFlvDemux * demux)
{
  demux->sinkpad =
      gst_pad_new_from_static_template (&flv_sink_template, "sink");

  gst_pad_set_event_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_flv_demux_sink_event));
  gst_pad_set_chain_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_flv_demux_chain));
  gst_pad_set_activate_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_flv_demux_sink_activate));
  gst_pad_set_activatemode_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_flv_demux_sink_activate_mode));

  gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);

  demux->adapter = gst_adapter_new ();
  demux->taglist = gst_tag_list_new_empty ();
  gst_segment_init (&demux->segment, GST_FORMAT_TIME);

  demux->own_index = FALSE;

  GST_OBJECT_FLAG_SET (demux, GST_ELEMENT_FLAG_INDEXABLE);

  gst_flv_demux_cleanup (demux);
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (flvdemux_debug, "flvdemux", 0, "FLV demuxer");

  if (!gst_element_register (plugin, "flvdemux", GST_RANK_PRIMARY,
          gst_flv_demux_get_type ()) ||
      !gst_element_register (plugin, "flvmux", GST_RANK_PRIMARY,
          gst_flv_mux_get_type ()))
    return FALSE;

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR,
    flv, "FLV muxing and demuxing plugin",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
