/* GStreamer
 * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
 *
 * gsttypefindelement.c: element that detects type of stream
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/**
 * SECTION:element-typefind
 *
 * Determines the media-type of a stream. It applies typefind functions in the
 * order of their rank. Once the type has been detected it sets its src pad caps
 * to the found media type.
 *
 * Whenever a type is found the #GstTypeFindElement::have-type signal is
 * emitted, either from the streaming thread or the application thread
 * (the latter may happen when typefinding is done pull-based from the
 * state change function).
 *
 * Plugins can register custom typefinders by using #GstTypeFindFactory.
 */

/* FIXME: need a better solution for non-seekable streams */

/* way of operation:
 * 1) get a list of all typefind functions sorted best to worst
 * 2) if all elements have been called with all requested data goto 8
 * 3) call all functions once with all available data
 * 4) if a function returns a value >= PROP_MAXIMUM goto 8 (never implemented))
 * 5) all functions with a result > PROP_MINIMUM or functions that did not get
 *    all requested data (where peek returned NULL) stay in list
 * 6) seek to requested offset of best function that still has open data
 *    requests
 * 7) goto 2
 * 8) take best available result and use its caps
 *
 * The element has two scheduling modes:
 *
 * 1) chain based, it will collect buffers and run the typefind function on
 *    the buffer until something is found.
 * 2) getrange based, it will proxy the getrange function to the sinkpad. It
 *    is assumed that the peer element is happy with whatever format we
 *    eventually read.
 *
 * By default it tries to do pull based typefinding (this avoids joining
 * received buffers and holding them back in store.)
 *
 * When the element has no connected srcpad, and the sinkpad can operate in
 * getrange based mode, the element starts its own task to figure out the
 * type of the stream.
 *
 * Most of the actual implementation is in libs/gst/base/gsttypefindhelper.c.
 */

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

#include "gst/gst_private.h"

#include "gsttypefindelement.h"
#include "gst/gst-i18n-lib.h"
#include "gst/base/gsttypefindhelper.h"

#include <gst/gsttypefind.h>
#include <gst/gstutils.h>
#include <gst/gsterror.h>

GST_DEBUG_CATEGORY_STATIC (gst_type_find_element_debug);
#define GST_CAT_DEFAULT gst_type_find_element_debug

/* generic templates */
static GstStaticPadTemplate type_find_element_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate type_find_element_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

/* Require at least 2kB of data before we attempt typefinding in chain-mode.
 * 128kB is massive overkill for the maximum, but doesn't do any harm */
#define TYPE_FIND_MIN_SIZE   (2*1024)
#define TYPE_FIND_MAX_SIZE (128*1024)

/* TypeFind signals and args */
enum
{
  HAVE_TYPE,
  LAST_SIGNAL
};
enum
{
  PROP_0,
  PROP_CAPS,
  PROP_MINIMUM,
  PROP_FORCE_CAPS,
  PROP_LAST
};
enum
{
  MODE_NORMAL,                  /* act as identity */
  MODE_TYPEFIND,                /* do typefinding  */
  MODE_ERROR                    /* had fatal error */
};


#define _do_init \
    GST_DEBUG_CATEGORY_INIT (gst_type_find_element_debug, "typefind",           \
        GST_DEBUG_BG_YELLOW | GST_DEBUG_FG_GREEN, "type finding element");
#define gst_type_find_element_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstTypeFindElement, gst_type_find_element,
    GST_TYPE_ELEMENT, _do_init);

static void gst_type_find_element_dispose (GObject * object);
static void gst_type_find_element_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_type_find_element_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

static gboolean gst_type_find_element_src_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_type_find_handle_src_query (GstPad * pad,
    GstObject * parent, GstQuery * query);

static gboolean gst_type_find_element_sink_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_type_find_element_setcaps (GstTypeFindElement * typefind,
    GstCaps * caps);
static GstFlowReturn gst_type_find_element_chain (GstPad * sinkpad,
    GstObject * parent, GstBuffer * buffer);
static GstFlowReturn gst_type_find_element_getrange (GstPad * srcpad,
    GstObject * parent, guint64 offset, guint length, GstBuffer ** buffer);

static GstStateChangeReturn
gst_type_find_element_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_type_find_element_activate_sink (GstPad * pad,
    GstObject * parent);
static gboolean gst_type_find_element_activate_sink_mode (GstPad * pad,
    GstObject * parent, GstPadMode mode, gboolean active);
static gboolean gst_type_find_element_activate_src_mode (GstPad * pad,
    GstObject * parent, GstPadMode mode, gboolean active);
static GstFlowReturn
gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
    gboolean check_avail);
static void gst_type_find_element_send_cached_events (GstTypeFindElement *
    typefind);

static void gst_type_find_element_loop (GstPad * pad);

static guint gst_type_find_element_signals[LAST_SIGNAL] = { 0 };

static void
gst_type_find_element_have_type (GstTypeFindElement * typefind,
    guint probability, GstCaps * caps)
{
  g_assert (caps != NULL);

  GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT ", probability=%u",
      caps, probability);

  GST_OBJECT_LOCK (typefind);
  if (typefind->caps)
    gst_caps_unref (typefind->caps);
  typefind->caps = gst_caps_ref (caps);
  GST_OBJECT_UNLOCK (typefind);

  gst_pad_set_caps (typefind->src, caps);
}

static void
gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (typefind_class);
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (typefind_class);

  gobject_class->set_property = gst_type_find_element_set_property;
  gobject_class->get_property = gst_type_find_element_get_property;
  gobject_class->dispose = gst_type_find_element_dispose;

  g_object_class_install_property (gobject_class, PROP_CAPS,
      g_param_spec_boxed ("caps", _("caps"),
          _("detected capabilities in stream"), GST_TYPE_CAPS,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MINIMUM,
      g_param_spec_uint ("minimum", _("minimum"),
          "minimum probability required to accept caps", GST_TYPE_FIND_MINIMUM,
          GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MINIMUM,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_FORCE_CAPS,
      g_param_spec_boxed ("force-caps", _("force caps"),
          _("force caps without doing a typefind"), GST_TYPE_CAPS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstTypeFindElement::have-type:
   * @typefind: the typefind instance
   * @probability: the probability of the type found
   * @caps: the caps of the type found
   *
   * This signal gets emitted when the type and its probability has
   * been found.
   */
  gst_type_find_element_signals[HAVE_TYPE] = g_signal_new ("have-type",
      G_TYPE_FROM_CLASS (typefind_class), G_SIGNAL_RUN_FIRST,
      G_STRUCT_OFFSET (GstTypeFindElementClass, have_type), NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 2,
      G_TYPE_UINT, GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE);

  typefind_class->have_type =
      GST_DEBUG_FUNCPTR (gst_type_find_element_have_type);

  gst_element_class_set_static_metadata (gstelement_class,
      "TypeFind",
      "Generic",
      "Finds the media type of a stream",
      "Benjamin Otte <in7y118@public.uni-hamburg.de>");
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&type_find_element_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&type_find_element_sink_template));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_type_find_element_change_state);
}

static void
gst_type_find_element_init (GstTypeFindElement * typefind)
{
  /* sinkpad */
  typefind->sink =
      gst_pad_new_from_static_template (&type_find_element_sink_template,
      "sink");

  gst_pad_set_activate_function (typefind->sink,
      GST_DEBUG_FUNCPTR (gst_type_find_element_activate_sink));
  gst_pad_set_activatemode_function (typefind->sink,
      GST_DEBUG_FUNCPTR (gst_type_find_element_activate_sink_mode));
  gst_pad_set_chain_function (typefind->sink,
      GST_DEBUG_FUNCPTR (gst_type_find_element_chain));
  gst_pad_set_event_function (typefind->sink,
      GST_DEBUG_FUNCPTR (gst_type_find_element_sink_event));
  GST_PAD_SET_PROXY_ALLOCATION (typefind->sink);
  gst_element_add_pad (GST_ELEMENT (typefind), typefind->sink);

  /* srcpad */
  typefind->src =
      gst_pad_new_from_static_template (&type_find_element_src_template, "src");

  gst_pad_set_activatemode_function (typefind->src,
      GST_DEBUG_FUNCPTR (gst_type_find_element_activate_src_mode));
  gst_pad_set_getrange_function (typefind->src,
      GST_DEBUG_FUNCPTR (gst_type_find_element_getrange));
  gst_pad_set_event_function (typefind->src,
      GST_DEBUG_FUNCPTR (gst_type_find_element_src_event));
  gst_pad_set_query_function (typefind->src,
      GST_DEBUG_FUNCPTR (gst_type_find_handle_src_query));
  gst_pad_use_fixed_caps (typefind->src);
  gst_element_add_pad (GST_ELEMENT (typefind), typefind->src);

  typefind->mode = MODE_TYPEFIND;
  typefind->caps = NULL;
  typefind->min_probability = 1;

  typefind->adapter = gst_adapter_new ();
}

static void
gst_type_find_element_dispose (GObject * object)
{
  GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (object);

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

  if (typefind->force_caps) {
    gst_caps_unref (typefind->force_caps);
    typefind->force_caps = NULL;
  }

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

static void
gst_type_find_element_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstTypeFindElement *typefind;

  typefind = GST_TYPE_FIND_ELEMENT (object);

  switch (prop_id) {
    case PROP_MINIMUM:
      typefind->min_probability = g_value_get_uint (value);
      break;
    case PROP_FORCE_CAPS:
      GST_OBJECT_LOCK (typefind);
      if (typefind->force_caps)
        gst_caps_unref (typefind->force_caps);
      typefind->force_caps = g_value_dup_boxed (value);
      GST_OBJECT_UNLOCK (typefind);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_type_find_element_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstTypeFindElement *typefind;

  typefind = GST_TYPE_FIND_ELEMENT (object);

  switch (prop_id) {
    case PROP_CAPS:
      GST_OBJECT_LOCK (typefind);
      g_value_set_boxed (value, typefind->caps);
      GST_OBJECT_UNLOCK (typefind);
      break;
    case PROP_MINIMUM:
      g_value_set_uint (value, typefind->min_probability);
      break;
    case PROP_FORCE_CAPS:
      GST_OBJECT_LOCK (typefind);
      g_value_set_boxed (value, typefind->force_caps);
      GST_OBJECT_UNLOCK (typefind);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_type_find_handle_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstTypeFindElement *typefind;
  gboolean res = FALSE;

  typefind = GST_TYPE_FIND_ELEMENT (parent);
  GST_DEBUG_OBJECT (typefind, "Handling src query %s",
      GST_QUERY_TYPE_NAME (query));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_SCHEDULING:
      /* FIXME, filter out the scheduling modes that we understand */
      res = gst_pad_peer_query (typefind->sink, query);
      break;
    case GST_QUERY_CAPS:
    {
      GST_DEBUG_OBJECT (typefind,
          "Got caps query, our caps are %" GST_PTR_FORMAT, typefind->caps);

      /* We can hijack caps query if we typefind already */
      if (typefind->caps) {
        gst_query_set_caps_result (query, typefind->caps);
        res = TRUE;
      } else {
        res = gst_pad_peer_query (typefind->sink, query);
      }
      break;
    }
    case GST_QUERY_POSITION:
    {
      gint64 peer_pos;
      GstFormat format;

      if (!(res = gst_pad_peer_query (typefind->sink, query)))
        goto out;

      gst_query_parse_position (query, &format, &peer_pos);

      GST_OBJECT_LOCK (typefind);
      /* FIXME: this code assumes that there's no discont in the queue */
      switch (format) {
        case GST_FORMAT_BYTES:
          peer_pos -= gst_adapter_available (typefind->adapter);
          break;
        default:
          /* FIXME */
          break;
      }
      GST_OBJECT_UNLOCK (typefind);
      gst_query_set_position (query, format, peer_pos);
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
out:
  return res;
}

static gboolean
gst_type_find_element_seek (GstTypeFindElement * typefind, GstEvent * event)
{
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  GstFormat format;
  gboolean flush;
  gdouble rate;
  gint64 start, stop;
  GstSegment seeksegment = { 0, };

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

  /* we can only seek on bytes */
  if (format != GST_FORMAT_BYTES) {
    GST_DEBUG_OBJECT (typefind, "Can only seek on BYTES");
    return FALSE;
  }

  /* copy segment, we need this because we still need the old
   * segment when we close the current segment. */
  memcpy (&seeksegment, &typefind->segment, sizeof (GstSegment));

  GST_DEBUG_OBJECT (typefind, "configuring seek");
  gst_segment_do_seek (&seeksegment, rate, format, flags,
      start_type, start, stop_type, stop, NULL);

  flush = ! !(flags & GST_SEEK_FLAG_FLUSH);

  GST_DEBUG_OBJECT (typefind, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);

  if (flush) {
    GST_DEBUG_OBJECT (typefind, "Starting flush");
    gst_pad_push_event (typefind->sink, gst_event_new_flush_start ());
    gst_pad_push_event (typefind->src, gst_event_new_flush_start ());
  } else {
    GST_DEBUG_OBJECT (typefind, "Non-flushing seek, pausing task");
    gst_pad_pause_task (typefind->sink);
  }

  /* now grab the stream lock so that streaming cannot continue, for
   * non flushing seeks when the element is in PAUSED this could block
   * forever. */
  GST_DEBUG_OBJECT (typefind, "Waiting for streaming to stop");
  GST_PAD_STREAM_LOCK (typefind->sink);

  if (flush) {
    GST_DEBUG_OBJECT (typefind, "Stopping flush");
    gst_pad_push_event (typefind->sink, gst_event_new_flush_stop (TRUE));
    gst_pad_push_event (typefind->src, gst_event_new_flush_stop (TRUE));
  }

  /* now update the real segment info */
  GST_DEBUG_OBJECT (typefind, "Committing new seek segment");
  memcpy (&typefind->segment, &seeksegment, sizeof (GstSegment));
  typefind->offset = typefind->segment.start;

  /* notify start of new segment */
  if (typefind->segment.flags & GST_SEGMENT_FLAG_SEGMENT) {
    GstMessage *msg;

    msg = gst_message_new_segment_start (GST_OBJECT (typefind),
        GST_FORMAT_BYTES, typefind->segment.start);
    gst_element_post_message (GST_ELEMENT (typefind), msg);
  }

  typefind->need_segment = TRUE;

  /* restart our task since it might have been stopped when we did the
   * flush. */
  gst_pad_start_task (typefind->sink,
      (GstTaskFunction) gst_type_find_element_loop, typefind->sink, NULL);

  /* streaming can continue now */
  GST_PAD_STREAM_UNLOCK (typefind->sink);

  return TRUE;
}

static gboolean
gst_type_find_element_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (parent);

  if (typefind->mode != MODE_NORMAL) {
    /* need to do more? */
    gst_mini_object_unref (GST_MINI_OBJECT_CAST (event));
    return FALSE;
  }

  /* Only handle seeks here if driving the pipeline */
  if (typefind->segment.format != GST_FORMAT_UNDEFINED &&
      GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
    return gst_type_find_element_seek (typefind, event);
  } else {
    return gst_pad_push_event (typefind->sink, event);
  }
}

static void
start_typefinding (GstTypeFindElement * typefind)
{
  GST_DEBUG_OBJECT (typefind, "starting typefinding");

  GST_OBJECT_LOCK (typefind);
  if (typefind->caps)
    gst_caps_replace (&typefind->caps, NULL);
  typefind->initial_offset = GST_BUFFER_OFFSET_NONE;
  GST_OBJECT_UNLOCK (typefind);

  typefind->mode = MODE_TYPEFIND;
}

static void
stop_typefinding (GstTypeFindElement * typefind)
{
  GstState state;
  gboolean push_cached_buffers;
  gsize avail;
  GstBuffer *buffer;
  GstClockTime pts, dts;

  gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, 0);

  push_cached_buffers = (state >= GST_STATE_PAUSED && typefind->caps);

  GST_DEBUG_OBJECT (typefind, "stopping typefinding%s",
      push_cached_buffers ? " and pushing cached events and buffers" : "");

  typefind->mode = MODE_NORMAL;
  if (push_cached_buffers)
    gst_type_find_element_send_cached_events (typefind);

  GST_OBJECT_LOCK (typefind);
  avail = gst_adapter_available (typefind->adapter);
  if (avail == 0)
    goto no_data;

  pts = gst_adapter_prev_pts (typefind->adapter, NULL);
  dts = gst_adapter_prev_dts (typefind->adapter, NULL);
  buffer = gst_adapter_take_buffer (typefind->adapter, avail);
  GST_BUFFER_PTS (buffer) = pts;
  GST_BUFFER_DTS (buffer) = dts;
  GST_BUFFER_OFFSET (buffer) = typefind->initial_offset;
  GST_OBJECT_UNLOCK (typefind);

  if (!push_cached_buffers) {
    gst_buffer_unref (buffer);
  } else {
    GstPad *peer = gst_pad_get_peer (typefind->src);

    /* make sure the user gets a meaningful error message in this case,
     * which is not a core bug or bug of any kind (as the default error
     * message emitted by gstpad.c otherwise would make you think) */
    if (peer && GST_PAD_CHAINFUNC (peer) == NULL) {
      GST_DEBUG_OBJECT (typefind, "upstream only supports push mode, while "
          "downstream element only works in pull mode, erroring out");
      GST_ELEMENT_ERROR (typefind, STREAM, FAILED,
          ("%s cannot work in push mode. The operation is not supported "
              "with this source element or protocol.",
              G_OBJECT_TYPE_NAME (GST_PAD_PARENT (peer))),
          ("Downstream pad %s:%s has no chainfunction, and the upstream "
              "element does not support pull mode", GST_DEBUG_PAD_NAME (peer)));
      typefind->mode = MODE_ERROR;      /* make the chain function error out */
      gst_buffer_unref (buffer);
    } else {
      gst_pad_push (typefind->src, buffer);
    }
    if (peer)
      gst_object_unref (peer);
  }
  return;

  /* ERRORS */
no_data:
  {
    GST_DEBUG_OBJECT (typefind, "we have no data to typefind");
    GST_OBJECT_UNLOCK (typefind);
    return;
  }
}

static gboolean
gst_type_find_element_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean res = FALSE;
  GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (parent);

  GST_DEBUG_OBJECT (typefind, "got %s event in mode %d",
      GST_EVENT_TYPE_NAME (event), typefind->mode);

  switch (typefind->mode) {
    case MODE_TYPEFIND:
      switch (GST_EVENT_TYPE (event)) {
        case GST_EVENT_CAPS:
        {
          GstCaps *caps;

          /* Parse and push out our caps and data */
          gst_event_parse_caps (event, &caps);
          res = gst_type_find_element_setcaps (typefind, caps);

          gst_event_unref (event);
          break;
        }
        case GST_EVENT_GAP:
        {
          GST_FIXME_OBJECT (typefind,
              "GAP events during typefinding not handled properly");

          /* FIXME: These would need to be inserted in the stream at
           * the right position between buffers, but we combine all
           * buffers with a GstAdapter. Drop the GAP event for now,
           * which will only cause an implicit GAP between buffers.
           */
          gst_event_unref (event);
          res = TRUE;
          break;
        }
        case GST_EVENT_EOS:
        {
          GST_INFO_OBJECT (typefind, "Got EOS and no type found yet");
          gst_type_find_element_chain_do_typefinding (typefind, FALSE);

          res = gst_pad_push_event (typefind->src, event);
          break;
        }
        case GST_EVENT_FLUSH_STOP:{
          GList *l;

          GST_OBJECT_LOCK (typefind);

          for (l = typefind->cached_events; l; l = l->next) {
            if (GST_EVENT_IS_STICKY (l->data) &&
                GST_EVENT_TYPE (l->data) != GST_EVENT_SEGMENT &&
                GST_EVENT_TYPE (l->data) != GST_EVENT_EOS) {
              gst_pad_store_sticky_event (typefind->src, l->data);
            }
            gst_event_unref (l->data);
          }

          g_list_free (typefind->cached_events);
          typefind->cached_events = NULL;
          gst_adapter_clear (typefind->adapter);
          GST_OBJECT_UNLOCK (typefind);
          /* fall through */
        }
        case GST_EVENT_FLUSH_START:
          res = gst_pad_push_event (typefind->src, event);
          break;
        default:
          /* Forward events that would happen before the caps event
           * directly instead of storing them. There's no reason not
           * to send them directly and we should only store events
           * for later sending that would need to come after the caps
           * event */
          if (GST_EVENT_TYPE (event) < GST_EVENT_CAPS) {
            res = gst_pad_push_event (typefind->src, event);
          } else {
            GST_DEBUG_OBJECT (typefind, "Saving %s event to send later",
                GST_EVENT_TYPE_NAME (event));
            GST_OBJECT_LOCK (typefind);
            typefind->cached_events =
                g_list_append (typefind->cached_events, event);
            GST_OBJECT_UNLOCK (typefind);
            res = TRUE;
          }
          break;
      }
      break;
    case MODE_NORMAL:
      res = gst_pad_push_event (typefind->src, event);
      break;
    case MODE_ERROR:
      break;
    default:
      g_assert_not_reached ();
  }
  return res;
}

static void
gst_type_find_element_send_cached_events (GstTypeFindElement * typefind)
{
  GList *l, *cached_events;

  GST_OBJECT_LOCK (typefind);
  cached_events = typefind->cached_events;
  typefind->cached_events = NULL;
  GST_OBJECT_UNLOCK (typefind);

  for (l = cached_events; l != NULL; l = l->next) {
    GstEvent *event = GST_EVENT (l->data);

    GST_DEBUG_OBJECT (typefind, "sending cached %s event",
        GST_EVENT_TYPE_NAME (event));
    gst_pad_push_event (typefind->src, event);
  }
  g_list_free (cached_events);
}

static gboolean
gst_type_find_element_setcaps (GstTypeFindElement * typefind, GstCaps * caps)
{
  /* don't operate on ANY caps */
  if (gst_caps_is_any (caps))
    return TRUE;

  g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
      GST_TYPE_FIND_MAXIMUM, caps);

  /* Shortcircuit typefinding if we get caps */
  GST_DEBUG_OBJECT (typefind, "Skipping typefinding, using caps from "
      "upstream: %" GST_PTR_FORMAT, caps);

  stop_typefinding (typefind);

  return TRUE;
}

static gchar *
gst_type_find_get_extension (GstTypeFindElement * typefind, GstPad * pad)
{
  GstQuery *query;
  gchar *uri, *result;
  size_t len;
  gint find;

  query = gst_query_new_uri ();

  /* try getting the caps with an uri query and from the extension */
  if (!gst_pad_peer_query (pad, query))
    goto peer_query_failed;

  gst_query_parse_uri (query, &uri);
  if (uri == NULL)
    goto no_uri;

  GST_DEBUG_OBJECT (typefind, "finding extension of %s", uri);

  /* find the extension on the uri, this is everything after a '.' */
  len = strlen (uri);
  find = len - 1;

  while (find >= 0) {
    if (uri[find] == '.')
      break;
    find--;
  }
  if (find < 0)
    goto no_extension;

  result = g_strdup (&uri[find + 1]);

  GST_DEBUG_OBJECT (typefind, "found extension %s", result);
  gst_query_unref (query);
  g_free (uri);

  return result;

  /* ERRORS */
peer_query_failed:
  {
    GST_WARNING_OBJECT (typefind, "failed to query peer uri");
    gst_query_unref (query);
    return NULL;
  }
no_uri:
  {
    GST_WARNING_OBJECT (typefind, "could not parse the peer uri");
    gst_query_unref (query);
    return NULL;
  }
no_extension:
  {
    GST_WARNING_OBJECT (typefind, "could not find uri extension in %s", uri);
    gst_query_unref (query);
    g_free (uri);
    return NULL;
  }
}

static GstCaps *
gst_type_find_guess_by_extension (GstTypeFindElement * typefind, GstPad * pad,
    GstTypeFindProbability * probability)
{
  gchar *ext;
  GstCaps *caps;

  ext = gst_type_find_get_extension (typefind, pad);
  if (!ext)
    return NULL;

  caps = gst_type_find_helper_for_extension (GST_OBJECT_CAST (typefind), ext);
  if (caps)
    *probability = GST_TYPE_FIND_MAXIMUM;

  g_free (ext);

  return caps;
}

static GstFlowReturn
gst_type_find_element_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstTypeFindElement *typefind;
  GstFlowReturn res = GST_FLOW_OK;

  typefind = GST_TYPE_FIND_ELEMENT (parent);

  GST_LOG_OBJECT (typefind, "handling buffer in mode %d", typefind->mode);

  switch (typefind->mode) {
    case MODE_ERROR:
      /* we should already have called GST_ELEMENT_ERROR */
      return GST_FLOW_ERROR;
    case MODE_NORMAL:
      /* don't take object lock as typefind->caps should not change anymore */
      return gst_pad_push (typefind->src, buffer);
    case MODE_TYPEFIND:
    {
      GST_OBJECT_LOCK (typefind);
      if (typefind->initial_offset == GST_BUFFER_OFFSET_NONE)
        typefind->initial_offset = GST_BUFFER_OFFSET (buffer);
      gst_adapter_push (typefind->adapter, buffer);
      GST_OBJECT_UNLOCK (typefind);

      res = gst_type_find_element_chain_do_typefinding (typefind, TRUE);

      if (typefind->mode == MODE_ERROR)
        res = GST_FLOW_ERROR;

      break;
    }
    default:
      g_assert_not_reached ();
      return GST_FLOW_ERROR;
  }

  return res;
}

static GstFlowReturn
gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
    gboolean check_avail)
{
  GstTypeFindProbability probability;
  GstCaps *caps = NULL;
  gsize avail;
  const guint8 *data;
  gboolean have_min, have_max;

  GST_OBJECT_LOCK (typefind);
  if (typefind->force_caps) {
    caps = gst_caps_ref (typefind->force_caps);
    probability = GST_TYPE_FIND_MAXIMUM;
  }

  if (!caps) {
    avail = gst_adapter_available (typefind->adapter);

    if (check_avail) {
      have_min = avail >= TYPE_FIND_MIN_SIZE;
      have_max = avail >= TYPE_FIND_MAX_SIZE;
    } else {
      have_min = avail > 0;
      have_max = TRUE;
    }

    if (!have_min)
      goto not_enough_data;

    /* map all available data */
    data = gst_adapter_map (typefind->adapter, avail);
    caps = gst_type_find_helper_for_data (GST_OBJECT (typefind),
        data, avail, &probability);
    gst_adapter_unmap (typefind->adapter);

    if (caps == NULL && have_max)
      goto no_type_found;
    else if (caps == NULL)
      goto wait_for_data;

    /* found a type */
    if (probability < typefind->min_probability)
      goto low_probability;
  }

  GST_OBJECT_UNLOCK (typefind);

  /* probability is good enough too, so let's make it known ... emiting this
   * signal calls our object handler which sets the caps. */
  g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
      probability, caps);

  /* .. and send out the accumulated data */
  stop_typefinding (typefind);
  gst_caps_unref (caps);

  return GST_FLOW_OK;

not_enough_data:
  {
    GST_DEBUG_OBJECT (typefind, "not enough data for typefinding yet "
        "(%" G_GSIZE_FORMAT " bytes)", avail);
    GST_OBJECT_UNLOCK (typefind);
    return GST_FLOW_OK;
  }
no_type_found:
  {
    GST_OBJECT_UNLOCK (typefind);
    GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
    stop_typefinding (typefind);
    return GST_FLOW_ERROR;
  }
wait_for_data:
  {
    GST_DEBUG_OBJECT (typefind,
        "no caps found with %" G_GSIZE_FORMAT " bytes of data, "
        "waiting for more data", avail);
    GST_OBJECT_UNLOCK (typefind);
    return GST_FLOW_OK;
  }
low_probability:
  {
    GST_DEBUG_OBJECT (typefind, "found caps %" GST_PTR_FORMAT ", but "
        "probability is %u which is lower than the required minimum of %u",
        caps, probability, typefind->min_probability);

    gst_caps_unref (caps);

    if (have_max)
      goto no_type_found;

    GST_OBJECT_UNLOCK (typefind);
    GST_DEBUG_OBJECT (typefind, "waiting for more data to try again");
    return GST_FLOW_OK;
  }
}

static GstFlowReturn
gst_type_find_element_getrange (GstPad * srcpad, GstObject * parent,
    guint64 offset, guint length, GstBuffer ** buffer)
{
  GstTypeFindElement *typefind;
  GstFlowReturn ret;

  typefind = GST_TYPE_FIND_ELEMENT (parent);

  ret = gst_pad_pull_range (typefind->sink, offset, length, buffer);

  return ret;
}

static gboolean
gst_type_find_element_activate_src_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;
  GstTypeFindElement *typefind;

  typefind = GST_TYPE_FIND_ELEMENT (parent);

  switch (mode) {
    case GST_PAD_MODE_PULL:
      /* make sure our task stops pushing, we can't call _stop here because this
       * activation might happen from the streaming thread. */
      gst_pad_pause_task (typefind->sink);
      res = gst_pad_activate_mode (typefind->sink, mode, active);
      break;
    default:
      res = TRUE;
      break;
  }
  return res;
}

static void
gst_type_find_element_loop (GstPad * pad)
{
  GstTypeFindElement *typefind;
  GstFlowReturn ret = GST_FLOW_OK;

  typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));

  if (typefind->need_stream_start) {
    gchar *stream_id;
    GstEvent *event;

    stream_id = gst_pad_create_stream_id (typefind->src,
        GST_ELEMENT_CAST (typefind), NULL);

    GST_DEBUG_OBJECT (typefind, "Pushing STREAM_START");
    event = gst_event_new_stream_start (stream_id);
    gst_event_set_group_id (event, gst_util_group_id_next ());
    gst_pad_push_event (typefind->src, event);

    typefind->need_stream_start = FALSE;
    g_free (stream_id);
  }

  if (typefind->mode == MODE_TYPEFIND) {
    GstPad *peer = NULL;
    GstCaps *found_caps = NULL;
    GstTypeFindProbability probability = GST_TYPE_FIND_NONE;

    GST_DEBUG_OBJECT (typefind, "find type in pull mode");

    GST_OBJECT_LOCK (typefind);
    if (typefind->force_caps) {
      found_caps = gst_caps_ref (typefind->force_caps);
      probability = GST_TYPE_FIND_MAXIMUM;
    }
    GST_OBJECT_UNLOCK (typefind);

    if (!found_caps) {
      peer = gst_pad_get_peer (pad);
      if (peer) {
        gint64 size;
        gchar *ext;

        if (!gst_pad_query_duration (peer, GST_FORMAT_BYTES, &size)) {
          GST_WARNING_OBJECT (typefind, "Could not query upstream length!");
          gst_object_unref (peer);

          ret = GST_FLOW_ERROR;
          goto pause;
        }

        /* the size if 0, we cannot continue */
        if (size == 0) {
          /* keep message in sync with message in sink event handler */
          GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND,
              (_("Stream contains no data.")), ("Can't typefind empty stream"));
          gst_object_unref (peer);
          ret = GST_FLOW_ERROR;
          goto pause;
        }
        ext = gst_type_find_get_extension (typefind, pad);

        found_caps =
            gst_type_find_helper_get_range (GST_OBJECT_CAST (peer),
            GST_OBJECT_PARENT (peer),
            (GstTypeFindHelperGetRangeFunction) (GST_PAD_GETRANGEFUNC (peer)),
            (guint64) size, ext, &probability);
        g_free (ext);

        GST_DEBUG ("Found caps %" GST_PTR_FORMAT, found_caps);

        gst_object_unref (peer);
      }
    }

    if (!found_caps || probability < typefind->min_probability) {
      GST_DEBUG ("Trying to guess using extension");
      gst_caps_replace (&found_caps, NULL);
      found_caps =
          gst_type_find_guess_by_extension (typefind, pad, &probability);
    }

    if (!found_caps || probability < typefind->min_probability) {
      GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
      gst_caps_replace (&found_caps, NULL);
      ret = GST_FLOW_ERROR;
      goto pause;
    }

    GST_DEBUG ("Emiting found caps %" GST_PTR_FORMAT, found_caps);
    g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
        0, probability, found_caps);
    typefind->mode = MODE_NORMAL;
    gst_caps_unref (found_caps);
  } else if (typefind->mode == MODE_NORMAL) {
    GstBuffer *outbuf = NULL;

    if (typefind->need_segment) {
      typefind->need_segment = FALSE;
      gst_pad_push_event (typefind->src,
          gst_event_new_segment (&typefind->segment));
    }

    /* Pull 4k blocks and send downstream */
    ret = gst_pad_pull_range (typefind->sink, typefind->offset, 4096, &outbuf);
    if (ret != GST_FLOW_OK)
      goto pause;

    typefind->offset += gst_buffer_get_size (outbuf);

    ret = gst_pad_push (typefind->src, outbuf);
    if (ret != GST_FLOW_OK)
      goto pause;
  } else {
    /* Error out */
    ret = GST_FLOW_ERROR;
    goto pause;
  }

  return;

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

    GST_LOG_OBJECT (typefind, "pausing task, reason %s", reason);
    gst_pad_pause_task (typefind->sink);

    if (ret == GST_FLOW_EOS) {
      /* perform EOS logic */

      if (typefind->segment.flags & GST_SEGMENT_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 = typefind->segment.stop) == -1)
          stop = typefind->offset;

        GST_LOG_OBJECT (typefind, "Sending segment done, at end of segment");
        gst_element_post_message (GST_ELEMENT (typefind),
            gst_message_new_segment_done (GST_OBJECT (typefind),
                GST_FORMAT_BYTES, stop));
        gst_pad_push_event (typefind->src,
            gst_event_new_segment_done (GST_FORMAT_BYTES, stop));
      } else {
        push_eos = TRUE;
      }
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
      /* for fatal errors we post an error message */
      GST_ELEMENT_ERROR (typefind, STREAM, FAILED, (NULL),
          ("stream stopped, reason %s", reason));
      push_eos = TRUE;
    }
    if (push_eos) {
      /* send EOS, and prevent hanging if no streams yet */
      GST_LOG_OBJECT (typefind, "Sending EOS, at end of stream");
      gst_pad_push_event (typefind->src, gst_event_new_eos ());
    }
    return;
  }
}

static gboolean
gst_type_find_element_activate_sink_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;
  GstTypeFindElement *typefind;

  typefind = GST_TYPE_FIND_ELEMENT (parent);

  switch (mode) {
    case GST_PAD_MODE_PULL:
      if (active) {
        gst_segment_init (&typefind->segment, GST_FORMAT_BYTES);
        typefind->need_segment = TRUE;
        typefind->need_stream_start = TRUE;
        typefind->offset = 0;
        res = TRUE;
      } else {
        gst_segment_init (&typefind->segment, GST_FORMAT_UNDEFINED);
        res = gst_pad_stop_task (pad);
      }
      break;
    case GST_PAD_MODE_PUSH:
      gst_segment_init (&typefind->segment, GST_FORMAT_UNDEFINED);
      if (active)
        start_typefinding (typefind);
      else
        stop_typefinding (typefind);

      res = TRUE;
      break;
    default:
      res = FALSE;
      break;
  }
  return res;
}

static gboolean
gst_type_find_element_activate_sink (GstPad * pad, GstObject * parent)
{
  GstQuery *query;
  gboolean pull_mode;
  GstSchedulingFlags sched_flags;

  query = gst_query_new_scheduling ();

  if (!gst_pad_peer_query (pad, query)) {
    gst_query_unref (query);
    goto typefind_push;
  }

  gst_query_parse_scheduling (query, &sched_flags, NULL, NULL, NULL);

  pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL)
      && ((sched_flags & GST_SCHEDULING_FLAG_SEEKABLE) != 0);

  gst_query_unref (query);

  if (!pull_mode)
    goto typefind_push;

  if (!gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE))
    goto typefind_push;

  /* only start our task if we ourselves decide to start in pull mode */
  return gst_pad_start_task (pad, (GstTaskFunction) gst_type_find_element_loop,
      pad, NULL);

typefind_push:
  {
    return gst_pad_activate_mode (pad, GST_PAD_MODE_PUSH, TRUE);
  }
}

static GstStateChangeReturn
gst_type_find_element_change_state (GstElement * element,
    GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstTypeFindElement *typefind;

  typefind = GST_TYPE_FIND_ELEMENT (element);


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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
    case GST_STATE_CHANGE_READY_TO_NULL:
      GST_OBJECT_LOCK (typefind);
      gst_caps_replace (&typefind->caps, NULL);

      g_list_foreach (typefind->cached_events,
          (GFunc) gst_mini_object_unref, NULL);
      g_list_free (typefind->cached_events);
      typefind->cached_events = NULL;
      typefind->mode = MODE_TYPEFIND;
      GST_OBJECT_UNLOCK (typefind);
      break;
    default:
      break;
  }

  return ret;
}
