/* GStreamer
 *
 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
 *   Author: Thiago Santos <thiagoss@osg.samsung.com>
 *
 * 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:gstadaptivedemux
 * @short_description: Base class for adaptive demuxers
 * @see_also:
 *
 * What is an adaptive demuxer?
 * Adaptive demuxers are special demuxers in the sense that they don't
 * actually demux data received from upstream but download the data
 * themselves.
 *
 * Adaptive formats (HLS, DASH, MSS) are composed of a manifest file and
 * a set of fragments. The manifest describes the available media and
 * the sequence of fragments to use. Each fragments contains a small
 * part of the media (typically only a few seconds). It is possible for
 * the manifest to have the same media available in different configurations
 * (bitrates for example) so that the client can select the one that
 * best suits its scenario (network fluctuation, hardware requirements...).
 * It is possible to switch from one representation of the media to another
 * during playback. That's why it is called 'adaptive', because it can be
 * adapted to the client's needs.
 *
 * Architectural overview:
 * The manifest is received by the demuxer in its sink pad and, upon receiving
 * EOS, it parses the manifest and exposes the streams available in it. For
 * each stream a source element will be created and will download the list
 * of fragments one by one. Once a fragment is finished downloading, the next
 * URI is set to the source element and it starts fetching it and pushing
 * through the stream's pad. This implies that each stream is independent from
 * each other as it runs on a separate thread.
 *
 * After downloading each fragment, the download rate of it is calculated and
 * the demuxer has a chance to switch to a different bitrate if needed. The
 * switch can be done by simply pushing a new caps before the next fragment
 * when codecs are the same, or by exposing a new pad group if it needs
 * a codec change.
 *
 * Extra features:
 * - Not linked streams: Streams that are not-linked have their download threads
 *                       interrupted to save network bandwidth. When they are
 *                       relinked a reconfigure event is received and the
 *                       stream is restarted.
 *
 * Subclasses:
 * While GstAdaptiveDemux is responsible for the workflow, it knows nothing
 * about the intrinsics of the subclass formats, so the subclasses are
 * resposible for maintaining the manifest data structures and stream
 * information.
 */

/*
MT safety.
The following rules were observed while implementing MT safety in adaptive demux:
1. If a variable is accessed from multiple threads and at least one thread
writes to it, then all the accesses needs to be done from inside a critical section.
2. If thread A wants to join thread B then at the moment it calls gst_task_join
it must not hold any mutexes that thread B might take.

Adaptive demux API can be called from several threads. More, adaptive demux
starts some threads to monitor the download of fragments. In order to protect
accesses to shared variables (demux and streams) all the API functions that
can be run in different threads will need to get a mutex (manifest_lock)
when they start and release it when they end. Because some of those functions
can indirectly call other API functions (eg they can generate events or messages
that are processed in the same thread) the manifest_lock must be recursive.

The manifest_lock will serialize the public API making access to shared
variables safe. But some of these functions will try at some moment to join
threads created by adaptive demux, or to change the state of src elements
(which will block trying to join the src element streaming thread). Because
of rule 2, those functions will need to release the manifest_lock during the
call of gst_task_join. During this time they can be interrupted by other API calls.
For example, during the precessing of a seek event, gst_adaptive_demux_stop_tasks
is called and this will join all threads. In order to prevent interruptions
during such period, all the API functions will also use a second lock: api_lock.
This will be taken at the beginning of the function and released at the end,
but this time this lock will not be temporarily released during join.
This lock will be used only by API calls (not by gst_adaptive_demux_stream_download_loop
or gst_adaptive_demux_updates_loop or _src_chain or _src_event) so it is safe
to hold it while joining the threads or changing the src element state. The
api_lock will serialise all external requests to adaptive demux. In order to
avoid deadlocks, if a function needs to acquire both manifest and api locks,
the api_lock will be taken first and the manifest_lock second.

By using the api_lock a thread is protected against other API calls. But when
temporarily dropping the manifest_lock, it will be vulnerable to changes from
threads that use only the manifest_lock and not the api_lock. These threads run
one of the following functions: gst_adaptive_demux_stream_download_loop,
gst_adaptive_demux_updates_loop, _src_chain, _src_event. In order to guarantee
that all operations during an API call are not impacted by other writes, the
above mentioned functions must check a cancelled flag every time they reacquire
the manifest_lock. If the flag is set, they must exit immediately, without
performing any changes on the shared data. In this way, an API call (eg seek
request) can set the cancel flag before releasing the manifest_lock and be sure
that the demux object and its streams are not changed by anybody else.
*/

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

#include "gstadaptivedemux.h"
#include "gst/gst-i18n-plugin.h"
#include <gst/base/gstadapter.h>

GST_DEBUG_CATEGORY (adaptivedemux_debug);
#define GST_CAT_DEFAULT adaptivedemux_debug

#define GST_ADAPTIVE_DEMUX_GET_PRIVATE(obj)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_ADAPTIVE_DEMUX, \
        GstAdaptiveDemuxPrivate))

#define MAX_DOWNLOAD_ERROR_COUNT 3
#define DEFAULT_FAILED_COUNT 3
#define DEFAULT_CONNECTION_SPEED 0
#define DEFAULT_BITRATE_LIMIT 0.8f
#define SRC_QUEUE_MAX_BYTES 20 * 1024 * 1024    /* For safety. Large enough to hold a segment. */
#define NUM_LOOKBACK_FRAGMENTS 3

#define GST_MANIFEST_GET_LOCK(d) (&(GST_ADAPTIVE_DEMUX_CAST(d)->priv->manifest_lock))
#define GST_MANIFEST_LOCK(d) G_STMT_START { \
    GST_TRACE("Locking from thread %p", g_thread_self()); \
    g_rec_mutex_lock (GST_MANIFEST_GET_LOCK (d)); \
    GST_TRACE("Locked from thread %p", g_thread_self()); \
 } G_STMT_END

#define GST_MANIFEST_UNLOCK(d) G_STMT_START { \
    GST_TRACE("Unlocking from thread %p", g_thread_self()); \
    g_rec_mutex_unlock (GST_MANIFEST_GET_LOCK (d)); \
 } G_STMT_END

#define GST_API_GET_LOCK(d) (&(GST_ADAPTIVE_DEMUX_CAST(d)->priv->api_lock))
#define GST_API_LOCK(d)   g_mutex_lock (GST_API_GET_LOCK (d));
#define GST_API_UNLOCK(d) g_mutex_unlock (GST_API_GET_LOCK (d));

#define GST_ADAPTIVE_DEMUX_SEGMENT_GET_LOCK(d) (&GST_ADAPTIVE_DEMUX_CAST(d)->priv->segment_lock)
#define GST_ADAPTIVE_DEMUX_SEGMENT_LOCK(d) g_mutex_lock (GST_ADAPTIVE_DEMUX_SEGMENT_GET_LOCK (d))
#define GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK(d) g_mutex_unlock (GST_ADAPTIVE_DEMUX_SEGMENT_GET_LOCK (d))

enum
{
  PROP_0,
  PROP_CONNECTION_SPEED,
  PROP_BITRATE_LIMIT,
  PROP_LAST
};

/* Internal, so not using GST_FLOW_CUSTOM_SUCCESS_N */
#define GST_ADAPTIVE_DEMUX_FLOW_SWITCH (GST_FLOW_CUSTOM_SUCCESS_2 + 1)

struct _GstAdaptiveDemuxPrivate
{
  GstAdapter *input_adapter;    /* protected by manifest_lock */
  gboolean have_manifest;       /* protected by manifest_lock */

  GList *old_streams;           /* protected by manifest_lock */

  GstTask *updates_task;        /* MT safe */
  GRecMutex updates_lock;
  GMutex updates_timed_lock;
  GCond updates_timed_cond;     /* protected by updates_timed_lock */
  gboolean stop_updates_task;   /* protected by updates_timed_lock */

  /* used only from updates_task, no need to protect it */
  gint update_failed_count;

  guint32 segment_seqnum;       /* protected by manifest_lock */

  /* main lock used to protect adaptive demux and all its streams.
   * It serializes the adaptive demux public API.
   */
  GRecMutex manifest_lock;

  /* condition to wait for manifest updates on a live stream.
   * In order to signal the manifest_cond, the caller needs to hold both
   * manifest_lock and manifest_update_lock (taken in this order)
   */
  GCond manifest_cond;
  GMutex manifest_update_lock;

  /* Lock and condition for prerolling streams before exposing */
  GMutex preroll_lock;
  GCond preroll_cond;
  gint preroll_pending;

  GMutex api_lock;

  /* Protects demux and stream segment information
   * Needed because seeks can update segment information
   * without needing to stop tasks when they just want to
   * update the segment boundaries */
  GMutex segment_lock;
};

typedef struct _GstAdaptiveDemuxTimer
{
  volatile gint ref_count;
  GCond *cond;
  GMutex *mutex;
  GstClockID clock_id;
  gboolean fired;
} GstAdaptiveDemuxTimer;

static GstBinClass *parent_class = NULL;
static void gst_adaptive_demux_class_init (GstAdaptiveDemuxClass * klass);
static void gst_adaptive_demux_init (GstAdaptiveDemux * dec,
    GstAdaptiveDemuxClass * klass);
static void gst_adaptive_demux_finalize (GObject * object);
static GstStateChangeReturn gst_adaptive_demux_change_state (GstElement *
    element, GstStateChange transition);

static void gst_adaptive_demux_handle_message (GstBin * bin, GstMessage * msg);

static gboolean gst_adaptive_demux_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstFlowReturn gst_adaptive_demux_sink_chain (GstPad * pad,
    GstObject * parent, GstBuffer * buffer);
static gboolean gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_adaptive_demux_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static gboolean
gst_adaptive_demux_push_src_event (GstAdaptiveDemux * demux, GstEvent * event);

static void gst_adaptive_demux_updates_loop (GstAdaptiveDemux * demux);
static void gst_adaptive_demux_stream_download_loop (GstAdaptiveDemuxStream *
    stream);
static void gst_adaptive_demux_reset (GstAdaptiveDemux * demux);
static gboolean gst_adaptive_demux_prepare_streams (GstAdaptiveDemux * demux,
    gboolean first_and_live);
static gboolean gst_adaptive_demux_expose_streams (GstAdaptiveDemux * demux);
static gboolean gst_adaptive_demux_is_live (GstAdaptiveDemux * demux);
static GstFlowReturn gst_adaptive_demux_stream_seek (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, gboolean forward, GstSeekFlags flags,
    GstClockTime ts, GstClockTime * final_ts);
static gboolean gst_adaptive_demux_stream_has_next_fragment (GstAdaptiveDemux *
    demux, GstAdaptiveDemuxStream * stream);
static gboolean gst_adaptive_demux_stream_select_bitrate (GstAdaptiveDemux *
    demux, GstAdaptiveDemuxStream * stream, guint64 bitrate);
static GstFlowReturn
gst_adaptive_demux_stream_update_fragment_info (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream);
static gint64
gst_adaptive_demux_stream_get_fragment_waiting_time (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream);
static GstFlowReturn gst_adaptive_demux_update_manifest (GstAdaptiveDemux *
    demux);
static GstFlowReturn
gst_adaptive_demux_update_manifest_default (GstAdaptiveDemux * demux);
static gboolean gst_adaptive_demux_has_next_period (GstAdaptiveDemux * demux);
static void gst_adaptive_demux_advance_period (GstAdaptiveDemux * demux);

static void gst_adaptive_demux_stream_free (GstAdaptiveDemuxStream * stream);
static GstFlowReturn
gst_adaptive_demux_stream_push_event (GstAdaptiveDemuxStream * stream,
    GstEvent * event);

static void gst_adaptive_demux_start_tasks (GstAdaptiveDemux * demux,
    gboolean start_preroll_streams);
static void gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux);
static GstFlowReturn gst_adaptive_demux_combine_flows (GstAdaptiveDemux *
    demux);
static void
gst_adaptive_demux_stream_fragment_download_finish (GstAdaptiveDemuxStream *
    stream, GstFlowReturn ret, GError * err);
static GstFlowReturn
gst_adaptive_demux_stream_data_received_default (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
static GstFlowReturn
gst_adaptive_demux_stream_finish_fragment_default (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream);
static GstFlowReturn
gst_adaptive_demux_stream_advance_fragment_unlocked (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, GstClockTime duration);
static gboolean
gst_adaptive_demux_wait_until (GstClock * clock, GCond * cond, GMutex * mutex,
    GstClockTime end_time);
static gboolean gst_adaptive_demux_clock_callback (GstClock * clock,
    GstClockTime time, GstClockID id, gpointer user_data);
static gboolean
gst_adaptive_demux_requires_periodical_playlist_update_default (GstAdaptiveDemux
    * demux);

/* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
 * method to get to the padtemplates */
GType
gst_adaptive_demux_get_type (void)
{
  static volatile gsize type = 0;

  if (g_once_init_enter (&type)) {
    GType _type;
    static const GTypeInfo info = {
      sizeof (GstAdaptiveDemuxClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_adaptive_demux_class_init,
      NULL,
      NULL,
      sizeof (GstAdaptiveDemux),
      0,
      (GInstanceInitFunc) gst_adaptive_demux_init,
    };

    _type = g_type_register_static (GST_TYPE_BIN,
        "GstAdaptiveDemux", &info, G_TYPE_FLAG_ABSTRACT);
    g_once_init_leave (&type, _type);
  }
  return type;
}

static void
gst_adaptive_demux_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX (object);

  GST_API_LOCK (demux);
  GST_MANIFEST_LOCK (demux);

  switch (prop_id) {
    case PROP_CONNECTION_SPEED:
      demux->connection_speed = g_value_get_uint (value) * 1000;
      GST_DEBUG_OBJECT (demux, "Connection speed set to %u",
          demux->connection_speed);
      break;
    case PROP_BITRATE_LIMIT:
      demux->bitrate_limit = g_value_get_float (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_MANIFEST_UNLOCK (demux);
  GST_API_UNLOCK (demux);
}

static void
gst_adaptive_demux_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX (object);

  GST_MANIFEST_LOCK (demux);

  switch (prop_id) {
    case PROP_CONNECTION_SPEED:
      g_value_set_uint (value, demux->connection_speed / 1000);
      break;
    case PROP_BITRATE_LIMIT:
      g_value_set_float (value, demux->bitrate_limit);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_MANIFEST_UNLOCK (demux);
}

static void
gst_adaptive_demux_class_init (GstAdaptiveDemuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBinClass *gstbin_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstbin_class = GST_BIN_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (adaptivedemux_debug, "adaptivedemux", 0,
      "Base Adaptive Demux");

  parent_class = g_type_class_peek_parent (klass);
  g_type_class_add_private (klass, sizeof (GstAdaptiveDemuxPrivate));

  gobject_class->set_property = gst_adaptive_demux_set_property;
  gobject_class->get_property = gst_adaptive_demux_get_property;
  gobject_class->finalize = gst_adaptive_demux_finalize;

  g_object_class_install_property (gobject_class, PROP_CONNECTION_SPEED,
      g_param_spec_uint ("connection-speed", "Connection Speed",
          "Network connection speed in kbps (0 = calculate from downloaded"
          " fragments)", 0, G_MAXUINT / 1000, DEFAULT_CONNECTION_SPEED,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* FIXME 2.0: rename this property to bandwidth-usage or any better name */
  g_object_class_install_property (gobject_class, PROP_BITRATE_LIMIT,
      g_param_spec_float ("bitrate-limit",
          "Bitrate limit in %",
          "Limit of the available bitrate to use when switching to alternates.",
          0, 1, DEFAULT_BITRATE_LIMIT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state = gst_adaptive_demux_change_state;

  gstbin_class->handle_message = gst_adaptive_demux_handle_message;

  klass->data_received = gst_adaptive_demux_stream_data_received_default;
  klass->finish_fragment = gst_adaptive_demux_stream_finish_fragment_default;
  klass->update_manifest = gst_adaptive_demux_update_manifest_default;
  klass->requires_periodical_playlist_update =
      gst_adaptive_demux_requires_periodical_playlist_update_default;

}

static void
gst_adaptive_demux_init (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxClass * klass)
{
  GstPadTemplate *pad_template;
  GstClockType clock_type = GST_CLOCK_TYPE_OTHER;
  GObjectClass *gobject_class;

  GST_DEBUG_OBJECT (demux, "gst_adaptive_demux_init");

  demux->priv = GST_ADAPTIVE_DEMUX_GET_PRIVATE (demux);
  demux->priv->input_adapter = gst_adapter_new ();
  demux->downloader = gst_uri_downloader_new ();
  demux->stream_struct_size = sizeof (GstAdaptiveDemuxStream);
  demux->priv->segment_seqnum = gst_util_seqnum_next ();
  demux->have_group_id = FALSE;
  demux->group_id = G_MAXUINT;

  gst_segment_init (&demux->segment, GST_FORMAT_TIME);

  gst_bin_set_suppressed_flags (GST_BIN_CAST (demux),
      GST_ELEMENT_FLAG_SOURCE | GST_ELEMENT_FLAG_SINK);

  demux->realtime_clock = gst_system_clock_obtain ();
  g_assert (demux->realtime_clock != NULL);
  gobject_class = G_OBJECT_GET_CLASS (demux->realtime_clock);
  if (g_object_class_find_property (gobject_class, "clock-type")) {
    g_object_get (demux->realtime_clock, "clock-type", &clock_type, NULL);
  } else {
    GST_WARNING_OBJECT (demux,
        "System clock does not have clock-type property");
  }
  if (clock_type == GST_CLOCK_TYPE_REALTIME) {
    demux->clock_offset = 0;
  } else {
    GDateTime *utc_now;
    GstClockTime rtc_now;
    GTimeVal gtv;

    utc_now = g_date_time_new_now_utc ();
    rtc_now = gst_clock_get_time (demux->realtime_clock);
    g_date_time_to_timeval (utc_now, &gtv);
    demux->clock_offset =
        gtv.tv_sec * G_TIME_SPAN_SECOND + gtv.tv_usec -
        GST_TIME_AS_USECONDS (rtc_now);
    g_date_time_unref (utc_now);
  }
  g_rec_mutex_init (&demux->priv->updates_lock);
  demux->priv->updates_task =
      gst_task_new ((GstTaskFunction) gst_adaptive_demux_updates_loop,
      demux, NULL);
  gst_task_set_lock (demux->priv->updates_task, &demux->priv->updates_lock);

  g_mutex_init (&demux->priv->updates_timed_lock);
  g_cond_init (&demux->priv->updates_timed_cond);

  g_cond_init (&demux->priv->manifest_cond);
  g_mutex_init (&demux->priv->manifest_update_lock);

  g_rec_mutex_init (&demux->priv->manifest_lock);
  g_mutex_init (&demux->priv->api_lock);
  g_mutex_init (&demux->priv->segment_lock);

  g_cond_init (&demux->priv->preroll_cond);
  g_mutex_init (&demux->priv->preroll_lock);

  pad_template =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
  g_return_if_fail (pad_template != NULL);

  demux->sinkpad = gst_pad_new_from_template (pad_template, "sink");
  gst_pad_set_event_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_adaptive_demux_sink_event));
  gst_pad_set_chain_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_adaptive_demux_sink_chain));

  /* Properties */
  demux->bitrate_limit = DEFAULT_BITRATE_LIMIT;
  demux->connection_speed = DEFAULT_CONNECTION_SPEED;

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

static void
gst_adaptive_demux_finalize (GObject * object)
{
  GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (object);
  GstAdaptiveDemuxPrivate *priv = demux->priv;

  GST_DEBUG_OBJECT (object, "finalize");

  g_object_unref (priv->input_adapter);
  g_object_unref (demux->downloader);

  g_mutex_clear (&priv->updates_timed_lock);
  g_cond_clear (&priv->updates_timed_cond);
  g_mutex_clear (&demux->priv->manifest_update_lock);
  g_cond_clear (&demux->priv->manifest_cond);
  g_object_unref (priv->updates_task);
  g_rec_mutex_clear (&priv->updates_lock);
  g_rec_mutex_clear (&demux->priv->manifest_lock);
  g_mutex_clear (&demux->priv->api_lock);
  g_mutex_clear (&demux->priv->segment_lock);
  if (demux->realtime_clock) {
    gst_object_unref (demux->realtime_clock);
    demux->realtime_clock = NULL;
  }

  g_cond_clear (&demux->priv->preroll_cond);
  g_mutex_clear (&demux->priv->preroll_lock);

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

static GstStateChangeReturn
gst_adaptive_demux_change_state (GstElement * element,
    GstStateChange transition)
{
  GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (element);
  GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;

  GST_API_LOCK (demux);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_MANIFEST_LOCK (demux);
      demux->running = FALSE;
      gst_adaptive_demux_reset (demux);
      GST_MANIFEST_UNLOCK (demux);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_MANIFEST_LOCK (demux);
      gst_adaptive_demux_reset (demux);
      demux->running = TRUE;
      GST_MANIFEST_UNLOCK (demux);
      break;
    default:
      break;
  }

  /* this must be run without MANIFEST_LOCK taken.
   * For PLAYING to PLAYING state changes, it will want to take a lock in
   * src element and that lock is held while the streaming thread is running.
   * The streaming thread will take the MANIFEST_LOCK, leading to a deadlock.
   */
  result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  GST_API_UNLOCK (demux);
  return result;
}

static gboolean
gst_adaptive_demux_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (parent);
  GstAdaptiveDemuxClass *demux_class;
  gboolean ret;

  switch (event->type) {
    case GST_EVENT_FLUSH_STOP:
      GST_API_LOCK (demux);
      GST_MANIFEST_LOCK (demux);

      gst_adaptive_demux_reset (demux);

      ret = gst_pad_event_default (pad, parent, event);

      GST_MANIFEST_UNLOCK (demux);
      GST_API_UNLOCK (demux);

      return ret;
    case GST_EVENT_EOS:{
      GstQuery *query;
      gboolean query_res;
      gboolean ret = TRUE;
      gsize available;
      GstBuffer *manifest_buffer;

      GST_API_LOCK (demux);
      GST_MANIFEST_LOCK (demux);

      demux_class = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

      available = gst_adapter_available (demux->priv->input_adapter);

      if (available == 0) {
        GST_WARNING_OBJECT (demux, "Received EOS without a manifest.");
        ret = gst_pad_event_default (pad, parent, event);

        GST_MANIFEST_UNLOCK (demux);
        GST_API_UNLOCK (demux);

        return ret;
      }

      GST_DEBUG_OBJECT (demux, "Got EOS on the sink pad: manifest fetched");

      /* Need to get the URI to use it as a base to generate the fragment's
       * uris */
      query = gst_query_new_uri ();
      query_res = gst_pad_peer_query (pad, query);
      if (query_res) {
        gchar *uri, *redirect_uri;
        gboolean permanent;

        gst_query_parse_uri (query, &uri);
        gst_query_parse_uri_redirection (query, &redirect_uri);
        gst_query_parse_uri_redirection_permanent (query, &permanent);

        if (permanent && redirect_uri) {
          demux->manifest_uri = redirect_uri;
          demux->manifest_base_uri = NULL;
          g_free (uri);
        } else {
          demux->manifest_uri = uri;
          demux->manifest_base_uri = redirect_uri;
        }

        GST_DEBUG_OBJECT (demux, "Fetched manifest at URI: %s (base: %s)",
            demux->manifest_uri, GST_STR_NULL (demux->manifest_base_uri));
      } else {
        GST_WARNING_OBJECT (demux, "Upstream URI query failed.");
      }
      gst_query_unref (query);

      /* Let the subclass parse the manifest */
      manifest_buffer =
          gst_adapter_take_buffer (demux->priv->input_adapter, available);
      if (!demux_class->process_manifest (demux, manifest_buffer)) {
        /* In most cases, this will happen if we set a wrong url in the
         * source element and we have received the 404 HTML response instead of
         * the manifest */
        GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid manifest."),
            (NULL));
        ret = FALSE;
      } else {
        demux->priv->have_manifest = TRUE;
      }
      gst_buffer_unref (manifest_buffer);

      gst_element_post_message (GST_ELEMENT_CAST (demux),
          gst_message_new_element (GST_OBJECT_CAST (demux),
              gst_structure_new (GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME,
                  "manifest-uri", G_TYPE_STRING,
                  demux->manifest_uri, "uri", G_TYPE_STRING,
                  demux->manifest_uri,
                  "manifest-download-start", GST_TYPE_CLOCK_TIME,
                  GST_CLOCK_TIME_NONE,
                  "manifest-download-stop", GST_TYPE_CLOCK_TIME,
                  gst_util_get_timestamp (), NULL)));

      if (ret) {
        /* Send duration message */
        if (!gst_adaptive_demux_is_live (demux)) {
          GstClockTime duration = demux_class->get_duration (demux);

          if (duration != GST_CLOCK_TIME_NONE) {
            GST_DEBUG_OBJECT (demux,
                "Sending duration message : %" GST_TIME_FORMAT,
                GST_TIME_ARGS (duration));
            gst_element_post_message (GST_ELEMENT (demux),
                gst_message_new_duration_changed (GST_OBJECT (demux)));
          } else {
            GST_DEBUG_OBJECT (demux,
                "media duration unknown, can not send the duration message");
          }
        }

        if (demux->next_streams) {
          gst_adaptive_demux_prepare_streams (demux,
              gst_adaptive_demux_is_live (demux));
          gst_adaptive_demux_start_tasks (demux, TRUE);
          if (gst_adaptive_demux_is_live (demux)) {
            g_mutex_lock (&demux->priv->updates_timed_lock);
            demux->priv->stop_updates_task = FALSE;
            g_mutex_unlock (&demux->priv->updates_timed_lock);
            /* Task to periodically update the manifest */
            if (demux_class->requires_periodical_playlist_update (demux)) {
              gst_task_start (demux->priv->updates_task);
            }
          }
        } else {
          /* no streams */
          GST_WARNING_OBJECT (demux, "No streams created from manifest");
          GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
              (_("This file contains no playable streams.")),
              ("No known stream formats found at the Manifest"));
          ret = FALSE;
        }

      }
      GST_MANIFEST_UNLOCK (demux);
      GST_API_UNLOCK (demux);

      gst_event_unref (event);
      return ret;
    }
    case GST_EVENT_SEGMENT:
      /* Swallow newsegments, we'll push our own */
      gst_event_unref (event);
      return TRUE;
    default:
      break;
  }

  return gst_pad_event_default (pad, parent, event);
}

static GstFlowReturn
gst_adaptive_demux_sink_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer)
{
  GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (parent);

  GST_MANIFEST_LOCK (demux);

  gst_adapter_push (demux->priv->input_adapter, buffer);

  GST_INFO_OBJECT (demux, "Received manifest buffer, total size is %i bytes",
      (gint) gst_adapter_available (demux->priv->input_adapter));

  GST_MANIFEST_UNLOCK (demux);
  return GST_FLOW_OK;
}

/* must be called with manifest_lock taken */
static void
gst_adaptive_demux_reset (GstAdaptiveDemux * demux)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  GList *iter;
  GList *old_streams;
  GstEvent *eos;

  /* take ownership of old_streams before releasing the manifest_lock in
   * gst_adaptive_demux_stop_tasks
   */
  old_streams = demux->priv->old_streams;
  demux->priv->old_streams = NULL;

  gst_adaptive_demux_stop_tasks (demux);
  gst_uri_downloader_reset (demux->downloader);

  if (klass->reset)
    klass->reset (demux);

  eos = gst_event_new_eos ();
  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;
    if (stream->pad) {
      gst_pad_push_event (stream->pad, gst_event_ref (eos));
      gst_pad_set_active (stream->pad, FALSE);

      gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
    }
    gst_adaptive_demux_stream_free (stream);
  }
  gst_event_unref (eos);
  g_list_free (demux->streams);
  demux->streams = NULL;
  if (demux->prepared_streams) {
    g_list_free_full (demux->prepared_streams,
        (GDestroyNotify) gst_adaptive_demux_stream_free);
    demux->prepared_streams = NULL;
  }
  if (demux->next_streams) {
    g_list_free_full (demux->next_streams,
        (GDestroyNotify) gst_adaptive_demux_stream_free);
    demux->next_streams = NULL;
  }

  if (old_streams) {
    g_list_free_full (old_streams,
        (GDestroyNotify) gst_adaptive_demux_stream_free);
  }

  g_free (demux->manifest_uri);
  g_free (demux->manifest_base_uri);
  demux->manifest_uri = NULL;
  demux->manifest_base_uri = NULL;

  gst_adapter_clear (demux->priv->input_adapter);
  demux->priv->have_manifest = FALSE;

  gst_segment_init (&demux->segment, GST_FORMAT_TIME);

  demux->have_group_id = FALSE;
  demux->group_id = G_MAXUINT;
  demux->priv->segment_seqnum = gst_util_seqnum_next ();
}

static void
gst_adaptive_demux_handle_message (GstBin * bin, GstMessage * msg)
{
  GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (bin);

  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_ERROR:{
      GList *iter;
      GstAdaptiveDemuxStream *stream = NULL;
      GError *err = NULL;
      gchar *debug = NULL;
      gchar *new_error = NULL;
      const GstStructure *details = NULL;

      GST_MANIFEST_LOCK (demux);

      for (iter = demux->streams; iter; iter = g_list_next (iter)) {
        GstAdaptiveDemuxStream *cur = iter->data;
        if (gst_object_has_as_ancestor (GST_MESSAGE_SRC (msg),
                GST_OBJECT_CAST (cur->src))) {
          stream = cur;
          break;
        }
      }
      if (stream == NULL) {
        for (iter = demux->prepared_streams; iter; iter = g_list_next (iter)) {
          GstAdaptiveDemuxStream *cur = iter->data;
          if (gst_object_has_as_ancestor (GST_MESSAGE_SRC (msg),
                  GST_OBJECT_CAST (cur->src))) {
            stream = cur;
            break;
          }
        }
        if (stream == NULL) {
          GST_WARNING_OBJECT (demux,
              "Failed to locate stream for errored element");
          break;
        }
      }

      gst_message_parse_error (msg, &err, &debug);

      GST_WARNING_OBJECT (GST_ADAPTIVE_DEMUX_STREAM_PAD (stream),
          "Source posted error: %d:%d %s (%s)", err->domain, err->code,
          err->message, debug);

      if (debug)
        new_error = g_strdup_printf ("%s: %s\n", err->message, debug);
      if (new_error) {
        g_free (err->message);
        err->message = new_error;
      }

      gst_message_parse_error_details (msg, &details);
      if (details) {
        gst_structure_get_uint (details, "http-status-code",
            &stream->last_status_code);
      }

      /* error, but ask to retry */
      gst_adaptive_demux_stream_fragment_download_finish (stream,
          GST_FLOW_CUSTOM_ERROR, err);

      g_error_free (err);
      g_free (debug);

      GST_MANIFEST_UNLOCK (demux);

      gst_message_unref (msg);
      msg = NULL;
    }
      break;
    default:
      break;
  }

  if (msg)
    GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
}

void
gst_adaptive_demux_set_stream_struct_size (GstAdaptiveDemux * demux,
    gsize struct_size)
{
  GST_API_LOCK (demux);
  GST_MANIFEST_LOCK (demux);
  demux->stream_struct_size = struct_size;
  GST_MANIFEST_UNLOCK (demux);
  GST_API_UNLOCK (demux);
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_prepare_stream (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstPad *pad = stream->pad;
  gchar *name = gst_pad_get_name (pad);
  GstEvent *event;
  gchar *stream_id;

  gst_pad_set_active (pad, TRUE);
  stream->need_header = TRUE;

  stream_id = gst_pad_create_stream_id (pad, GST_ELEMENT_CAST (demux), name);

  event =
      gst_pad_get_sticky_event (GST_ADAPTIVE_DEMUX_SINK_PAD (demux),
      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 ();
  }
  event = gst_event_new_stream_start (stream_id);
  if (demux->have_group_id)
    gst_event_set_group_id (event, demux->group_id);

  gst_pad_push_event (pad, event);
  g_free (stream_id);
  g_free (name);

  GST_DEBUG_OBJECT (demux, "Preparing srcpad %s:%s", GST_DEBUG_PAD_NAME (pad));

  stream->discont = TRUE;

  return TRUE;
}

static gboolean
gst_adaptive_demux_expose_stream (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  gboolean ret;
  GstPad *pad = stream->pad;
  GstCaps *caps;

  if (stream->pending_caps) {
    gst_pad_set_caps (pad, stream->pending_caps);
    caps = stream->pending_caps;
    stream->pending_caps = NULL;
  } else {
    caps = gst_pad_get_current_caps (pad);
  }

  GST_DEBUG_OBJECT (demux, "Exposing srcpad %s:%s with caps %" GST_PTR_FORMAT,
      GST_DEBUG_PAD_NAME (pad), caps);
  if (caps)
    gst_caps_unref (caps);

  gst_object_ref (pad);

  /* Don't hold the manifest lock while exposing a pad */
  GST_MANIFEST_UNLOCK (demux);
  ret = gst_element_add_pad (GST_ELEMENT_CAST (demux), pad);
  GST_MANIFEST_LOCK (demux);

  return ret;
}

/* must be called with manifest_lock taken */
static GstClockTime
gst_adaptive_demux_stream_get_presentation_offset (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstAdaptiveDemuxClass *klass;

  klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  if (klass->get_presentation_offset == NULL)
    return 0;

  return klass->get_presentation_offset (demux, stream);
}

/* must be called with manifest_lock taken */
static GstClockTime
gst_adaptive_demux_get_period_start_time (GstAdaptiveDemux * demux)
{
  GstAdaptiveDemuxClass *klass;

  klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  if (klass->get_period_start_time == NULL)
    return 0;

  return klass->get_period_start_time (demux);
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_prepare_streams (GstAdaptiveDemux * demux,
    gboolean first_and_live)
{
  GList *iter;
  GstClockTime period_start, min_pts = GST_CLOCK_TIME_NONE;

  g_return_val_if_fail (demux->next_streams != NULL, FALSE);
  if (demux->prepared_streams != NULL) {
    /* Old streams that were never exposed, due to a seek or so */
    GST_FIXME_OBJECT (demux,
        "Preparing new streams without cleaning up old ones!");
    return FALSE;
  }

  demux->prepared_streams = demux->next_streams;
  demux->next_streams = NULL;

  if (!demux->running) {
    GST_DEBUG_OBJECT (demux, "Not exposing pads due to shutdown");
    return TRUE;
  }

  for (iter = demux->prepared_streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;

    stream->do_block = TRUE;

    if (!gst_adaptive_demux_prepare_stream (demux,
            GST_ADAPTIVE_DEMUX_STREAM_CAST (stream))) {
      /* TODO act on error */
    }

    if (first_and_live) {
      /* TODO we only need the first timestamp, maybe create a simple function */
      gst_adaptive_demux_stream_update_fragment_info (demux, stream);

      if (GST_CLOCK_TIME_IS_VALID (min_pts)) {
        min_pts = MIN (min_pts, stream->fragment.timestamp);
      } else {
        min_pts = stream->fragment.timestamp;
      }
    }
  }

  period_start = gst_adaptive_demux_get_period_start_time (demux);

  /* For live streams, the subclass is supposed to seek to the current
   * fragment and then tell us its timestamp in stream->fragment.timestamp.
   * We now also have to seek our demuxer segment to reflect this.
   *
   * FIXME: This needs some refactoring at some point.
   */
  if (first_and_live) {
    gst_segment_do_seek (&demux->segment, demux->segment.rate, GST_FORMAT_TIME,
        GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, min_pts + period_start,
        GST_SEEK_TYPE_NONE, -1, NULL);
  }

  for (iter = demux->prepared_streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;
    GstClockTime offset;

    offset = gst_adaptive_demux_stream_get_presentation_offset (demux, stream);
    stream->segment = demux->segment;

    /* The demuxer segment is just built from seek events, but for each stream
     * we have to adjust segments according to the current period and the
     * stream specific presentation time offset.
     *
     * For each period, buffer timestamps start again from 0. Additionally the
     * buffer timestamps are shifted by the stream specific presentation time
     * offset, so the first buffer timestamp of a period is 0 + presentation
     * time offset. If the stream contains timestamps itself, this is also
     * supposed to be the presentation time stored inside the stream.
     *
     * The stream time over periods is supposed to be continuous, that is the
     * buffer timestamp 0 + presentation time offset should map to the start
     * time of the current period.
     *
     *
     * The adjustment of the stream segments as such works the following.
     *
     * If the demuxer segment start is bigger than the period start, this
     * means that we have to drop some media at the beginning of the current
     * period, e.g. because a seek into the middle of the period has
     * happened. The amount of media to drop is the difference between the
     * period start and the demuxer segment start, and as each period starts
     * again from 0, this difference is going to be the actual stream's
     * segment start. As all timestamps of the stream are shifted by the
     * presentation time offset, we will also have to move the segment start
     * by that offset.
     *
     * Now the running time and stream time at the stream's segment start has to
     * be the one that is stored inside the demuxer's segment, which means
     * that segment.base and segment.time have to be copied over.
     *
     *
     * If the demuxer segment start is smaller than the period start time,
     * this means that the whole period is inside the segment. As each period
     * starts timestamps from 0, and additionally timestamps are shifted by
     * the presentation time offset, the stream's first timestamp (and as such
     * the stream's segment start) has to be the presentation time offset.
     * The stream time at the segment start is supposed to be the stream time
     * of the period start according to the demuxer segment, so the stream
     * segment's time would be set to that. The same goes for the stream
     * segment's base, which is supposed to be the running time of the period
     * start according to the demuxer's segment.
     *
     *
     * For the first case where not the complete period is inside the segment,
     * the segment time and base as calculated by the second case would be
     * equivalent.
     */

    /* If first and live, demuxer did seek to the current position already */
    if (first_and_live) {
      stream->segment.start = demux->segment.start - period_start + offset;
      stream->segment.position = stream->segment.start;
      stream->segment.time = demux->segment.time;
      stream->segment.base = demux->segment.base;
    } else if (demux->segment.start > period_start) {
      stream->segment.start = demux->segment.start - period_start + offset;
      stream->segment.position = offset;
      stream->segment.time = demux->segment.time;
      stream->segment.base = demux->segment.base;
    } else {
      stream->segment.start = offset;
      stream->segment.position = offset;
      stream->segment.time =
          gst_segment_to_stream_time (&demux->segment, GST_FORMAT_TIME,
          period_start);
      stream->segment.base =
          gst_segment_to_running_time (&demux->segment, GST_FORMAT_TIME,
          period_start);
    }

    stream->pending_segment = gst_event_new_segment (&stream->segment);
    gst_event_set_seqnum (stream->pending_segment, demux->priv->segment_seqnum);

    GST_DEBUG ("Prepared segment %" GST_SEGMENT_FORMAT " for stream %p",
        &stream->segment, stream);
  }

  return TRUE;
}

static gboolean
gst_adaptive_demux_expose_streams (GstAdaptiveDemux * demux)
{
  GList *iter;
  GList *old_streams;

  g_return_val_if_fail (demux->prepared_streams != NULL, FALSE);

  old_streams = demux->streams;
  demux->streams = demux->prepared_streams;
  demux->prepared_streams = NULL;

  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;

    if (!gst_adaptive_demux_expose_stream (demux,
            GST_ADAPTIVE_DEMUX_STREAM_CAST (stream))) {
      /* TODO act on error */
    }
  }
  demux->priv->preroll_pending = 0;

  GST_MANIFEST_UNLOCK (demux);
  gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
  GST_MANIFEST_LOCK (demux);

  if (old_streams) {
    GstEvent *eos = gst_event_new_eos ();

    /* before we put streams in the demux->priv->old_streams list,
     * we ask the download task to stop. In this way, it will no longer be
     * allowed to change the demux object.
     */
    for (iter = old_streams; iter; iter = g_list_next (iter)) {
      GstAdaptiveDemuxStream *stream = iter->data;

      GST_LOG_OBJECT (stream->pad, "Removing stream");
      GST_MANIFEST_UNLOCK (demux);

      gst_pad_push_event (stream->pad, gst_event_ref (eos));
      gst_pad_set_active (stream->pad, FALSE);
      gst_element_remove_pad (GST_ELEMENT (demux), stream->pad);
      GST_MANIFEST_LOCK (demux);

      /* ask the download task to stop.
       * We will not join it now, because our thread can be one of these tasks.
       * We will do the joining later, from another stream download task or
       * from gst_adaptive_demux_stop_tasks.
       * We also cannot change the state of the stream->src element, because
       * that will wait on the streaming thread (which could be this thread)
       * to stop first.
       * Because we sent an EOS to the downstream element, the stream->src
       * element should detect this in its streaming task and stop.
       * Even if it doesn't do that, we will change its state later in
       * gst_adaptive_demux_stop_tasks.
       */
      GST_LOG_OBJECT (stream, "Marking stream as cancelled");
      gst_task_stop (stream->download_task);
      g_mutex_lock (&stream->fragment_download_lock);
      stream->cancelled = TRUE;
      g_cond_signal (&stream->fragment_download_cond);
      g_mutex_unlock (&stream->fragment_download_lock);
    }
    gst_event_unref (eos);

    /* The list should be freed from another thread as we can't properly
     * cleanup a GstTask from itself */
    demux->priv->old_streams =
        g_list_concat (demux->priv->old_streams, old_streams);
  }

  /* Unblock after removing oldstreams */
  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;
    stream->do_block = FALSE;
  }

  GST_DEBUG_OBJECT (demux, "All streams are exposed");

  return TRUE;
}

/* must be called with manifest_lock taken */
GstAdaptiveDemuxStream *
gst_adaptive_demux_stream_new (GstAdaptiveDemux * demux, GstPad * pad)
{
  GstAdaptiveDemuxStream *stream;

  stream = g_malloc0 (demux->stream_struct_size);

  /* Downloading task */
  g_rec_mutex_init (&stream->download_lock);
  stream->download_task =
      gst_task_new ((GstTaskFunction) gst_adaptive_demux_stream_download_loop,
      stream, NULL);
  gst_task_set_lock (stream->download_task, &stream->download_lock);

  stream->pad = pad;
  stream->demux = demux;
  stream->fragment_bitrates =
      g_malloc0 (sizeof (guint64) * NUM_LOOKBACK_FRAGMENTS);
  gst_pad_set_element_private (pad, stream);

  g_mutex_lock (&demux->priv->preroll_lock);
  stream->do_block = TRUE;
  demux->priv->preroll_pending++;
  g_mutex_unlock (&demux->priv->preroll_lock);

  gst_pad_set_query_function (pad,
      GST_DEBUG_FUNCPTR (gst_adaptive_demux_src_query));
  gst_pad_set_event_function (pad,
      GST_DEBUG_FUNCPTR (gst_adaptive_demux_src_event));

  gst_segment_init (&stream->segment, GST_FORMAT_TIME);
  g_cond_init (&stream->fragment_download_cond);
  g_mutex_init (&stream->fragment_download_lock);

  demux->next_streams = g_list_append (demux->next_streams, stream);

  return stream;
}

GstAdaptiveDemuxStream *
gst_adaptive_demux_find_stream_for_pad (GstAdaptiveDemux * demux, GstPad * pad)
{
  GList *iter;

  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;
    if (stream->pad == pad) {
      return stream;
    }
  }

  return NULL;
}

/* must be called with manifest_lock taken.
 * It will temporarily drop the manifest_lock in order to join the task.
 * It will join only the old_streams (the demux->streams are joined by
 * gst_adaptive_demux_stop_tasks before gst_adaptive_demux_stream_free is
 * called)
 */
static void
gst_adaptive_demux_stream_free (GstAdaptiveDemuxStream * stream)
{
  GstAdaptiveDemux *demux = stream->demux;
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  if (klass->stream_free)
    klass->stream_free (stream);

  g_clear_error (&stream->last_error);
  if (stream->download_task) {
    if (GST_TASK_STATE (stream->download_task) != GST_TASK_STOPPED) {
      GST_DEBUG_OBJECT (demux, "Leaving streaming task %s:%s",
          GST_DEBUG_PAD_NAME (stream->pad));

      gst_task_stop (stream->download_task);

      g_mutex_lock (&stream->fragment_download_lock);
      stream->cancelled = TRUE;
      g_cond_signal (&stream->fragment_download_cond);
      g_mutex_unlock (&stream->fragment_download_lock);
    }
    GST_LOG_OBJECT (demux, "Waiting for task to finish");

    /* temporarily drop the manifest lock to join the task */
    GST_MANIFEST_UNLOCK (demux);

    gst_task_join (stream->download_task);

    GST_MANIFEST_LOCK (demux);

    GST_LOG_OBJECT (demux, "Finished");
    gst_object_unref (stream->download_task);
    g_rec_mutex_clear (&stream->download_lock);
    stream->download_task = NULL;
  }

  gst_adaptive_demux_stream_fragment_clear (&stream->fragment);

  if (stream->pending_segment) {
    gst_event_unref (stream->pending_segment);
    stream->pending_segment = NULL;
  }

  if (stream->pending_events) {
    g_list_free_full (stream->pending_events, (GDestroyNotify) gst_event_unref);
    stream->pending_events = NULL;
  }

  if (stream->internal_pad) {
    gst_object_unparent (GST_OBJECT_CAST (stream->internal_pad));
  }

  if (stream->src_srcpad) {
    gst_object_unref (stream->src_srcpad);
    stream->src_srcpad = NULL;
  }

  if (stream->src) {
    GstElement *src = stream->src;

    stream->src = NULL;

    GST_MANIFEST_UNLOCK (demux);
    gst_element_set_locked_state (src, TRUE);
    gst_element_set_state (src, GST_STATE_NULL);
    gst_bin_remove (GST_BIN_CAST (demux), src);
    GST_MANIFEST_LOCK (demux);
  }

  g_cond_clear (&stream->fragment_download_cond);
  g_mutex_clear (&stream->fragment_download_lock);
  g_free (stream->fragment_bitrates);

  if (stream->pad) {
    gst_object_unref (stream->pad);
    stream->pad = NULL;
  }
  if (stream->pending_caps)
    gst_caps_unref (stream->pending_caps);

  g_clear_pointer (&stream->pending_tags, gst_tag_list_unref);

  g_free (stream);
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_get_live_seek_range (GstAdaptiveDemux * demux,
    gint64 * range_start, gint64 * range_stop)
{
  GstAdaptiveDemuxClass *klass;

  klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  g_return_val_if_fail (klass->get_live_seek_range, FALSE);

  return klass->get_live_seek_range (demux, range_start, range_stop);
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_can_seek (GstAdaptiveDemux * demux)
{
  GstAdaptiveDemuxClass *klass;

  klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  if (gst_adaptive_demux_is_live (demux)) {
    return klass->get_live_seek_range != NULL;
  }

  return klass->seek != NULL;
}

#define IS_SNAP_SEEK(f) (f & (GST_SEEK_FLAG_SNAP_BEFORE |	  \
                              GST_SEEK_FLAG_SNAP_AFTER |	  \
                              GST_SEEK_FLAG_SNAP_NEAREST |	  \
			      GST_SEEK_FLAG_TRICKMODE_KEY_UNITS | \
			      GST_SEEK_FLAG_KEY_UNIT))
#define REMOVE_SNAP_FLAGS(f) (f & ~(GST_SEEK_FLAG_SNAP_BEFORE | \
                              GST_SEEK_FLAG_SNAP_AFTER | \
                              GST_SEEK_FLAG_SNAP_NEAREST))

static gboolean
gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
    GstEvent * event)
{
  GstAdaptiveDemuxClass *demux_class = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  gdouble rate;
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  guint32 seqnum;
  gboolean update;
  gboolean ret;
  GstSegment oldsegment;
  GstAdaptiveDemuxStream *stream = NULL;

  GST_INFO_OBJECT (demux, "Received seek event");

  GST_API_LOCK (demux);
  GST_MANIFEST_LOCK (demux);

  if (!gst_adaptive_demux_can_seek (demux)) {
    GST_MANIFEST_UNLOCK (demux);
    GST_API_UNLOCK (demux);
    gst_event_unref (event);
    return FALSE;
  }

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

  if (format != GST_FORMAT_TIME) {
    GST_MANIFEST_UNLOCK (demux);
    GST_API_UNLOCK (demux);
    gst_event_unref (event);
    return FALSE;
  }

  if (gst_adaptive_demux_is_live (demux)) {
    gint64 range_start, range_stop;
    if (!gst_adaptive_demux_get_live_seek_range (demux, &range_start,
            &range_stop)) {
      GST_MANIFEST_UNLOCK (demux);
      GST_API_UNLOCK (demux);
      gst_event_unref (event);
      return FALSE;
    }

    if (!(flags & GST_SEEK_FLAG_ACCURATE)) {
      /* If the accurate flag is not set, we allow seeking before the start
       * to map to the start for live cases, since those can return a "moving
       * target" based on wall time.
       */
      if (start < range_start) {
        guint64 dt = range_start - start;
        GST_DEBUG_OBJECT (demux,
            "Non accurate seek before live stream start, offsetting by %"
            GST_TIME_FORMAT, GST_TIME_ARGS (dt));
        start = range_start;
        if (stop != GST_CLOCK_TIME_NONE)
          stop += dt;
      }
    }

    if (start < range_start || start >= range_stop) {
      GST_MANIFEST_UNLOCK (demux);
      GST_API_UNLOCK (demux);
      GST_WARNING_OBJECT (demux, "Seek to invalid position");
      gst_event_unref (event);
      return FALSE;
    }
  }

  seqnum = gst_event_get_seqnum (event);

  GST_DEBUG_OBJECT (demux, "seek event, %" GST_PTR_FORMAT, event);

  /* have a backup in case seek fails */
  gst_segment_copy_into (&demux->segment, &oldsegment);

  if (flags & GST_SEEK_FLAG_FLUSH) {
    GstEvent *fevent;

    GST_DEBUG_OBJECT (demux, "sending flush start");
    fevent = gst_event_new_flush_start ();
    gst_event_set_seqnum (fevent, seqnum);
    gst_adaptive_demux_push_src_event (demux, fevent);

    gst_adaptive_demux_stop_tasks (demux);
  } else if ((rate > 0 && start_type != GST_SEEK_TYPE_NONE) ||
      (rate < 0 && stop_type != GST_SEEK_TYPE_NONE)) {

    gst_adaptive_demux_stop_tasks (demux);
  }

  GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux);

  /*
   * Handle snap seeks as follows:
   * 1) do the snap seeking on the stream that received
   *    the event
   * 2) use the final position on this stream to seek
   *    on the other streams to the same position
   *
   * We can't snap at all streams at the same time as
   * they might end in different positions, so just
   * use the one that received the event as the 'leading'
   * one to do the snap seek.
   */
  if (IS_SNAP_SEEK (flags) && demux_class->stream_seek && (stream =
          gst_adaptive_demux_find_stream_for_pad (demux, pad))) {
    GstClockTime ts;
    GstSeekFlags stream_seek_flags = flags;

    /* snap-seek on the stream that received the event and then
     * use the resulting position to seek on all streams */

    if (rate >= 0) {
      if (start_type != GST_SEEK_TYPE_NONE)
        ts = start;
      else {
        ts = stream->segment.position;
        start_type = GST_SEEK_TYPE_SET;
      }
    } else {
      if (stop_type != GST_SEEK_TYPE_NONE)
        ts = stop;
      else {
        stop_type = GST_SEEK_TYPE_SET;
        ts = stream->segment.position;
      }
    }

    if (stream) {
      demux_class->stream_seek (stream, rate >= 0, stream_seek_flags, ts, &ts);
    }

    /* replace event with a new one without snaping to seek on all streams */
    gst_event_unref (event);
    if (rate >= 0) {
      start = ts;
    } else {
      stop = ts;
    }
    event =
        gst_event_new_seek (rate, format, REMOVE_SNAP_FLAGS (flags),
        start_type, start, stop_type, stop);
    GST_DEBUG_OBJECT (demux, "Adapted snap seek to %" GST_PTR_FORMAT, event);
  }
  stream = NULL;

  gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
      start, stop_type, stop, &update);

  /* FIXME - this seems unatural, do_seek() is updating base when we
   * only want the start/stop position to change, maybe do_seek() needs
   * some fixing? */
  if (!(flags & GST_SEEK_FLAG_FLUSH) && ((rate > 0
              && start_type == GST_SEEK_TYPE_NONE) || (rate < 0
              && stop_type == GST_SEEK_TYPE_NONE))) {
    demux->segment.base = oldsegment.base;
  }

  GST_DEBUG_OBJECT (demux, "Calling subclass seek: %" GST_PTR_FORMAT, event);

  ret = demux_class->seek (demux, event);

  if (!ret) {
    /* Is there anything else we can do if it fails? */
    gst_segment_copy_into (&oldsegment, &demux->segment);
  } else {
    demux->priv->segment_seqnum = seqnum;
  }
  GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);

  if (flags & GST_SEEK_FLAG_FLUSH) {
    GstEvent *fevent;

    GST_DEBUG_OBJECT (demux, "Sending flush stop on all pad");
    fevent = gst_event_new_flush_stop (TRUE);
    gst_event_set_seqnum (fevent, seqnum);
    gst_adaptive_demux_push_src_event (demux, fevent);
  }

  if (demux->next_streams) {
    /* If the seek generated new streams, get them
     * to preroll */
    gst_adaptive_demux_prepare_streams (demux, FALSE);
    gst_adaptive_demux_start_tasks (demux, TRUE);
  } else {
    GList *iter;
    GstClockTime period_start =
        gst_adaptive_demux_get_period_start_time (demux);

    GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux);
    for (iter = demux->streams; iter; iter = g_list_next (iter)) {
      GstAdaptiveDemuxStream *stream = iter->data;
      GstEvent *seg_evt;
      GstClockTime offset;

      /* See comments in gst_adaptive_demux_get_period_start_time() for
       * an explanation of the segment modifications */
      stream->segment = demux->segment;
      offset =
          gst_adaptive_demux_stream_get_presentation_offset (demux, stream);
      stream->segment.start += offset - period_start;
      if (demux->segment.rate > 0 && start_type != GST_SEEK_TYPE_NONE)
        stream->segment.position = stream->segment.start;
      else if (demux->segment.rate < 0 && stop_type != GST_SEEK_TYPE_NONE)
        stream->segment.position = stream->segment.stop;
      seg_evt = gst_event_new_segment (&stream->segment);
      gst_event_set_seqnum (seg_evt, demux->priv->segment_seqnum);
      gst_event_replace (&stream->pending_segment, seg_evt);
      gst_event_unref (seg_evt);
      /* Make sure the first buffer after a seek has the discont flag */
      stream->discont = TRUE;
    }

    GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);

    /* Restart the demux */
    gst_adaptive_demux_start_tasks (demux, FALSE);
  }

  if (gst_adaptive_demux_is_live (demux)) {
    g_mutex_lock (&demux->priv->updates_timed_lock);
    demux->priv->stop_updates_task = FALSE;
    g_mutex_unlock (&demux->priv->updates_timed_lock);
    /* Task to periodically update the manifest */
    gst_task_start (demux->priv->updates_task);
  }
  GST_MANIFEST_UNLOCK (demux);
  GST_API_UNLOCK (demux);
  gst_event_unref (event);

  return ret;
}

static gboolean
gst_adaptive_demux_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstAdaptiveDemux *demux;

  demux = GST_ADAPTIVE_DEMUX_CAST (parent);

  /* FIXME handle events received on pads that are to be removed */

  switch (event->type) {
    case GST_EVENT_SEEK:
    {
      guint32 seqnum = gst_event_get_seqnum (event);
      if (seqnum == demux->priv->segment_seqnum) {
        GST_LOG_OBJECT (pad,
            "Drop duplicated SEEK event seqnum %" G_GUINT32_FORMAT, seqnum);
        gst_event_unref (event);
        return TRUE;
      }
      return gst_adaptive_demux_handle_seek_event (demux, pad, event);
    }
    case GST_EVENT_RECONFIGURE:{
      GstAdaptiveDemuxStream *stream;

      GST_MANIFEST_LOCK (demux);
      stream = gst_adaptive_demux_find_stream_for_pad (demux, pad);

      if (stream) {
        if (!stream->cancelled && demux->running &&
            stream->last_ret == GST_FLOW_NOT_LINKED) {
          stream->last_ret = GST_FLOW_OK;
          stream->restart_download = TRUE;
          stream->need_header = TRUE;
          stream->discont = TRUE;
          GST_DEBUG_OBJECT (stream->pad, "Restarting download loop");
          gst_task_start (stream->download_task);
        }
        gst_event_unref (event);
        GST_MANIFEST_UNLOCK (demux);
        return TRUE;
      }
      GST_MANIFEST_UNLOCK (demux);
    }
      break;
    case GST_EVENT_LATENCY:{
      /* Upstream and our internal source are irrelevant
       * for latency, and we should not fail here to
       * configure the latency */
      gst_event_unref (event);
      return TRUE;
    }
    default:
      break;
  }

  return gst_pad_event_default (pad, parent, event);
}

static gboolean
gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstAdaptiveDemux *demux;
  GstAdaptiveDemuxClass *demux_class;
  gboolean ret = FALSE;

  if (query == NULL)
    return FALSE;

  demux = GST_ADAPTIVE_DEMUX_CAST (parent);
  demux_class = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  switch (query->type) {
    case GST_QUERY_DURATION:{
      GstClockTime duration = -1;
      GstFormat fmt;

      gst_query_parse_duration (query, &fmt, NULL);

      GST_MANIFEST_LOCK (demux);

      if (fmt == GST_FORMAT_TIME && demux->priv->have_manifest) {
        duration = demux_class->get_duration (demux);

        if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) {
          gst_query_set_duration (query, GST_FORMAT_TIME, duration);
          ret = TRUE;
        }
      }

      GST_MANIFEST_UNLOCK (demux);

      GST_LOG_OBJECT (demux, "GST_QUERY_DURATION returns %s with duration %"
          GST_TIME_FORMAT, ret ? "TRUE" : "FALSE", GST_TIME_ARGS (duration));
      break;
    }
    case GST_QUERY_LATENCY:{
      gst_query_set_latency (query, FALSE, 0, -1);
      ret = TRUE;
      break;
    }
    case GST_QUERY_SEEKING:{
      GstFormat fmt;
      gint64 stop = -1;
      gint64 start = 0;

      GST_MANIFEST_LOCK (demux);

      if (!demux->priv->have_manifest) {
        GST_MANIFEST_UNLOCK (demux);
        GST_INFO_OBJECT (demux,
            "Don't have manifest yet, can't answer seeking query");
        return FALSE;           /* can't answer without manifest */
      }

      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
      GST_INFO_OBJECT (demux, "Received GST_QUERY_SEEKING with format %d", fmt);
      if (fmt == GST_FORMAT_TIME) {
        GstClockTime duration;
        gboolean can_seek = gst_adaptive_demux_can_seek (demux);

        ret = TRUE;
        if (can_seek) {
          if (gst_adaptive_demux_is_live (demux)) {
            ret = gst_adaptive_demux_get_live_seek_range (demux, &start, &stop);
            if (!ret) {
              GST_MANIFEST_UNLOCK (demux);
              GST_INFO_OBJECT (demux, "can't answer seeking query");
              return FALSE;
            }
          } else {
            duration = demux_class->get_duration (demux);
            if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0)
              stop = duration;
          }
        }
        gst_query_set_seeking (query, fmt, can_seek, start, stop);
        GST_INFO_OBJECT (demux, "GST_QUERY_SEEKING returning with start : %"
            GST_TIME_FORMAT ", stop : %" GST_TIME_FORMAT,
            GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
      }
      GST_MANIFEST_UNLOCK (demux);
      break;
    }
    case GST_QUERY_URI:

      GST_MANIFEST_LOCK (demux);

      /* TODO HLS can answer this differently it seems */
      if (demux->manifest_uri) {
        /* FIXME: (hls) Do we answer with the variant playlist, with the current
         * playlist or the the uri of the last downlowaded fragment? */
        gst_query_set_uri (query, demux->manifest_uri);
        ret = TRUE;
      }

      GST_MANIFEST_UNLOCK (demux);
      break;
    default:
      /* Don't forward queries upstream because of the special nature of this
       *  "demuxer", which relies on the upstream element only to be fed
       *  the Manifest
       */
      break;
  }

  return ret;
}

/* must be called with manifest_lock taken */
static void
gst_adaptive_demux_start_tasks (GstAdaptiveDemux * demux,
    gboolean start_preroll_streams)
{
  GList *iter;

  if (!demux->running) {
    GST_DEBUG_OBJECT (demux, "Not starting tasks due to shutdown");
    return;
  }

  GST_INFO_OBJECT (demux, "Starting streams' tasks");

  iter = start_preroll_streams ? demux->prepared_streams : demux->streams;

  for (; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;

    if (!start_preroll_streams) {
      g_mutex_lock (&stream->fragment_download_lock);
      stream->cancelled = FALSE;
      g_mutex_unlock (&stream->fragment_download_lock);
    }

    stream->last_ret = GST_FLOW_OK;
    gst_task_start (stream->download_task);
  }
}

/* must be called with manifest_lock taken
 * This function will temporarily release manifest_lock in order to join the
 * download threads.
 * The api_lock will still protect it against other threads trying to modify
 * the demux element.
 */
static void
gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux)
{
  GList *iter;

  gst_task_stop (demux->priv->updates_task);

  g_mutex_lock (&demux->priv->updates_timed_lock);
  demux->priv->stop_updates_task = TRUE;
  g_cond_signal (&demux->priv->updates_timed_cond);
  g_mutex_unlock (&demux->priv->updates_timed_lock);

  GST_LOG_OBJECT (demux, "Stopping tasks");

  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;

    g_mutex_lock (&stream->fragment_download_lock);
    stream->cancelled = TRUE;
    gst_task_stop (stream->download_task);
    g_cond_signal (&stream->fragment_download_cond);
    g_mutex_unlock (&stream->fragment_download_lock);
  }

  g_mutex_lock (&demux->priv->preroll_lock);
  g_cond_broadcast (&demux->priv->preroll_cond);
  g_mutex_unlock (&demux->priv->preroll_lock);

  gst_uri_downloader_cancel (demux->downloader);

  g_mutex_lock (&demux->priv->manifest_update_lock);
  g_cond_broadcast (&demux->priv->manifest_cond);
  g_mutex_unlock (&demux->priv->manifest_update_lock);

  /* need to release manifest_lock before stopping the src element.
   * The streams were asked to cancel, so they will not make any writes to demux
   * object. Even if we temporarily release manifest_lock, the demux->streams
   * cannot change and iter cannot be invalidated.
   */
  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;
    GstElement *src = stream->src;

    GST_MANIFEST_UNLOCK (demux);

    if (src) {
      gst_element_set_locked_state (src, TRUE);
      gst_element_set_state (src, GST_STATE_READY);
    }

    /* stream->download_task value never changes, so it is safe to read it
     * outside critical section
     */
    gst_task_join (stream->download_task);

    GST_MANIFEST_LOCK (demux);
  }

  GST_MANIFEST_UNLOCK (demux);

  /* demux->priv->updates_task value never changes, so it is safe to read it
   * outside critical section
   */
  gst_task_join (demux->priv->updates_task);

  GST_MANIFEST_LOCK (demux);

  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;

    stream->download_error_count = 0;
    stream->need_header = TRUE;
  }
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_push_src_event (GstAdaptiveDemux * demux, GstEvent * event)
{
  GList *iter;
  gboolean ret = TRUE;

  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;
    gst_event_ref (event);
    ret = ret & gst_pad_push_event (stream->pad, event);
  }
  gst_event_unref (event);
  return ret;
}

/* must be called with manifest_lock taken */
void
gst_adaptive_demux_stream_set_caps (GstAdaptiveDemuxStream * stream,
    GstCaps * caps)
{
  GST_DEBUG_OBJECT (stream->pad, "setting new caps for stream %" GST_PTR_FORMAT,
      caps);
  gst_caps_replace (&stream->pending_caps, caps);
  gst_caps_unref (caps);
}

/* must be called with manifest_lock taken */
void
gst_adaptive_demux_stream_set_tags (GstAdaptiveDemuxStream * stream,
    GstTagList * tags)
{
  GST_DEBUG_OBJECT (stream->pad, "setting new tags for stream %" GST_PTR_FORMAT,
      tags);
  if (stream->pending_tags) {
    gst_tag_list_unref (stream->pending_tags);
  }
  stream->pending_tags = tags;
}

/* must be called with manifest_lock taken */
void
gst_adaptive_demux_stream_queue_event (GstAdaptiveDemuxStream * stream,
    GstEvent * event)
{
  stream->pending_events = g_list_append (stream->pending_events, event);
}

/* must be called with manifest_lock taken */
static guint64
_update_average_bitrate (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, guint64 new_bitrate)
{
  gint index = stream->moving_index % NUM_LOOKBACK_FRAGMENTS;

  stream->moving_bitrate -= stream->fragment_bitrates[index];
  stream->fragment_bitrates[index] = new_bitrate;
  stream->moving_bitrate += new_bitrate;

  stream->moving_index += 1;

  if (stream->moving_index > NUM_LOOKBACK_FRAGMENTS)
    return stream->moving_bitrate / NUM_LOOKBACK_FRAGMENTS;
  return stream->moving_bitrate / stream->moving_index;
}

/* must be called with manifest_lock taken */
static guint64
gst_adaptive_demux_stream_update_current_bitrate (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  guint64 average_bitrate;
  guint64 fragment_bitrate;

  if (demux->connection_speed) {
    GST_LOG_OBJECT (demux, "Connection-speed is set to %u kbps, using it",
        demux->connection_speed / 1000);
    return demux->connection_speed;
  }

  fragment_bitrate = stream->last_bitrate;
  GST_DEBUG_OBJECT (demux, "Download bitrate is : %" G_GUINT64_FORMAT " bps",
      fragment_bitrate);

  average_bitrate = _update_average_bitrate (demux, stream, fragment_bitrate);

  GST_INFO_OBJECT (stream, "last fragment bitrate was %" G_GUINT64_FORMAT,
      fragment_bitrate);
  GST_INFO_OBJECT (stream,
      "Last %u fragments average bitrate is %" G_GUINT64_FORMAT,
      NUM_LOOKBACK_FRAGMENTS, average_bitrate);

  /* Conservative approach, make sure we don't upgrade too fast */
  stream->current_download_rate = MIN (average_bitrate, fragment_bitrate);

  stream->current_download_rate *= demux->bitrate_limit;
  GST_DEBUG_OBJECT (demux, "Bitrate after bitrate limit (%0.2f): %"
      G_GUINT64_FORMAT, demux->bitrate_limit, stream->current_download_rate);

#if 0
  /* Debugging code, modulate the bitrate every few fragments */
  {
    static guint ctr = 0;
    if (ctr % 3 == 0) {
      GST_INFO_OBJECT (demux, "Halving reported bitrate for debugging");
      stream->current_download_rate /= 2;
    }
    ctr++;
  }
#endif

  return stream->current_download_rate;
}

/* must be called with manifest_lock taken */
static GstFlowReturn
gst_adaptive_demux_combine_flows (GstAdaptiveDemux * demux)
{
  gboolean all_notlinked = TRUE;
  gboolean all_eos = TRUE;
  GList *iter;

  for (iter = demux->streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;

    if (stream->last_ret != GST_FLOW_NOT_LINKED) {
      all_notlinked = FALSE;
      if (stream->last_ret != GST_FLOW_EOS)
        all_eos = FALSE;
    }

    if (stream->last_ret <= GST_FLOW_NOT_NEGOTIATED
        || stream->last_ret == GST_FLOW_FLUSHING) {
      return stream->last_ret;
    }
  }
  if (all_notlinked)
    return GST_FLOW_NOT_LINKED;
  else if (all_eos)
    return GST_FLOW_EOS;
  return GST_FLOW_OK;
}

/* Called with preroll_lock */
static void
gst_adaptive_demux_handle_preroll (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  demux->priv->preroll_pending--;
  if (demux->priv->preroll_pending == 0) {
    /* That was the last one, time to release all streams
     * and expose them */
    GST_DEBUG_OBJECT (demux, "All streams prerolled. exposing");
    gst_adaptive_demux_expose_streams (demux);
    g_cond_broadcast (&demux->priv->preroll_cond);
  }
}

/* must be called with manifest_lock taken.
 * Temporarily releases manifest_lock
 */
GstFlowReturn
gst_adaptive_demux_stream_push_buffer (GstAdaptiveDemuxStream * stream,
    GstBuffer * buffer)
{
  GstAdaptiveDemux *demux = stream->demux;
  GstFlowReturn ret = GST_FLOW_OK;
  gboolean discont = FALSE;
  /* Pending events */
  GstEvent *pending_caps = NULL, *pending_segment = NULL, *pending_tags = NULL;
  GList *pending_events = NULL;

  if (stream->first_fragment_buffer) {
    GstClockTime offset =
        gst_adaptive_demux_stream_get_presentation_offset (demux, stream);
    GstClockTime period_start =
        gst_adaptive_demux_get_period_start_time (demux);

    GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux);
    if (demux->segment.rate < 0)
      /* Set DISCONT flag for every first buffer in reverse playback mode
       * as each fragment for its own has to be reversed */
      discont = TRUE;

    GST_BUFFER_PTS (buffer) = stream->fragment.timestamp;
    if (GST_BUFFER_PTS_IS_VALID (buffer))
      GST_BUFFER_PTS (buffer) += offset;

    if (GST_BUFFER_PTS_IS_VALID (buffer)) {
      stream->segment.position = GST_BUFFER_PTS (buffer);

      /* Convert from position inside the stream's segment to the demuxer's
       * segment, they are not necessarily the same */
      if (stream->segment.position - offset + period_start >
          demux->segment.position)
        demux->segment.position =
            stream->segment.position - offset + period_start;
    }
    GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);

    GST_LOG_OBJECT (stream->pad,
        "Going to push buffer with PTS %" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_BUFFER_PTS (buffer)));
  } else {
    GST_BUFFER_PTS (buffer) = GST_CLOCK_TIME_NONE;
  }

  if (stream->discont) {
    discont = TRUE;
    stream->discont = FALSE;
  }

  if (discont) {
    GST_DEBUG_OBJECT (stream->pad, "Marking fragment as discontinuous");
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
  } else {
    GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT);
  }

  stream->first_fragment_buffer = FALSE;

  GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
  GST_BUFFER_DTS (buffer) = GST_CLOCK_TIME_NONE;
  if (G_UNLIKELY (stream->pending_caps)) {
    pending_caps = gst_event_new_caps (stream->pending_caps);
    gst_caps_unref (stream->pending_caps);
    stream->pending_caps = NULL;
  }

  if (stream->do_block) {

    g_mutex_lock (&demux->priv->preroll_lock);

    /* If we are preroll state, set caps in here */
    if (pending_caps) {
      gst_pad_push_event (stream->pad, pending_caps);
      pending_caps = NULL;
    }

    gst_adaptive_demux_handle_preroll (demux, stream);
    GST_MANIFEST_UNLOCK (demux);

    while (stream->do_block && !stream->cancelled) {
      GST_LOG_OBJECT (demux, "Stream %p sleeping for preroll", stream);
      g_cond_wait (&demux->priv->preroll_cond, &demux->priv->preroll_lock);
    }
    if (stream->cancelled) {
      GST_LOG_OBJECT (demux, "stream %p cancelled", stream);
      gst_buffer_unref (buffer);
      g_mutex_unlock (&demux->priv->preroll_lock);
      return GST_FLOW_FLUSHING;
    }

    g_mutex_unlock (&demux->priv->preroll_lock);
    GST_MANIFEST_LOCK (demux);
  }

  if (G_UNLIKELY (stream->pending_segment)) {
    GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux);
    pending_segment = stream->pending_segment;
    stream->pending_segment = NULL;
    GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);
  }
  if (G_UNLIKELY (stream->pending_tags || stream->bitrate_changed)) {
    GstTagList *tags = stream->pending_tags;

    stream->pending_tags = NULL;
    stream->bitrate_changed = 0;

    if (stream->fragment.bitrate != 0) {
      if (tags)
        tags = gst_tag_list_make_writable (tags);
      else
        tags = gst_tag_list_new_empty ();

      gst_tag_list_add (tags, GST_TAG_MERGE_KEEP,
          GST_TAG_NOMINAL_BITRATE, stream->fragment.bitrate, NULL);
    }
    pending_tags = gst_event_new_tag (tags);
  }
  if (G_UNLIKELY (stream->pending_events)) {
    pending_events = stream->pending_events;
    stream->pending_events = NULL;
  }

  GST_MANIFEST_UNLOCK (demux);

  /* Do not push events or buffers holding the manifest lock */
  if (G_UNLIKELY (pending_caps)) {
    GST_DEBUG_OBJECT (stream->pad, "Setting pending caps: %" GST_PTR_FORMAT,
        pending_caps);
    gst_pad_push_event (stream->pad, pending_caps);
  }
  if (G_UNLIKELY (pending_segment)) {
    GST_DEBUG_OBJECT (stream->pad, "Sending pending seg: %" GST_PTR_FORMAT,
        pending_segment);
    gst_pad_push_event (stream->pad, pending_segment);
  }
  if (G_UNLIKELY (pending_tags)) {
    GST_DEBUG_OBJECT (stream->pad, "Sending pending tags: %" GST_PTR_FORMAT,
        pending_tags);
    gst_pad_push_event (stream->pad, pending_tags);
  }
  while (pending_events != NULL) {
    GstEvent *event = pending_events->data;

    if (!gst_pad_push_event (stream->pad, event))
      GST_ERROR_OBJECT (stream->pad, "Failed to send pending event");

    pending_events = g_list_delete_link (pending_events, pending_events);
  }

  /* Wait for preroll if blocking */

  ret = gst_pad_push (stream->pad, buffer);

  GST_MANIFEST_LOCK (demux);

  g_mutex_lock (&stream->fragment_download_lock);
  if (G_UNLIKELY (stream->cancelled)) {
    GST_LOG_OBJECT (stream, "Stream was cancelled");
    ret = stream->last_ret = GST_FLOW_FLUSHING;
    g_mutex_unlock (&stream->fragment_download_lock);
    return ret;
  }
  g_mutex_unlock (&stream->fragment_download_lock);

  GST_LOG_OBJECT (stream->pad, "Push result: %d %s", ret,
      gst_flow_get_name (ret));

  return ret;
}

/* must be called with manifest_lock taken */
static GstFlowReturn
gst_adaptive_demux_stream_finish_fragment_default (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  /* No need to advance, this isn't a real fragment */
  if (G_UNLIKELY (stream->downloading_header || stream->downloading_index))
    return GST_FLOW_OK;

  return gst_adaptive_demux_stream_advance_fragment (demux, stream,
      stream->fragment.duration);
}

/* must be called with manifest_lock taken.
 * Can temporarily release manifest_lock
 */
static GstFlowReturn
gst_adaptive_demux_stream_data_received_default (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, GstBuffer * buffer)
{
  return gst_adaptive_demux_stream_push_buffer (stream, buffer);
}

static gboolean
gst_adaptive_demux_requires_periodical_playlist_update_default (GstAdaptiveDemux
    * demux)
{
  return TRUE;
}

static GstFlowReturn
_src_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstAdaptiveDemuxStream *stream;
  GstAdaptiveDemux *demux;
  GstAdaptiveDemuxClass *klass;
  GstFlowReturn ret = GST_FLOW_OK;

  demux = GST_ADAPTIVE_DEMUX_CAST (parent);
  stream = gst_pad_get_element_private (pad);
  klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  GST_MANIFEST_LOCK (demux);

  /* do not make any changes if the stream is cancelled */
  g_mutex_lock (&stream->fragment_download_lock);
  if (G_UNLIKELY (stream->cancelled)) {
    g_mutex_unlock (&stream->fragment_download_lock);
    gst_buffer_unref (buffer);
    ret = stream->last_ret = GST_FLOW_FLUSHING;
    GST_MANIFEST_UNLOCK (demux);
    return ret;
  }
  g_mutex_unlock (&stream->fragment_download_lock);

  if (stream->starting_fragment) {
    GstClockTime offset =
        gst_adaptive_demux_stream_get_presentation_offset (demux, stream);
    GstClockTime period_start =
        gst_adaptive_demux_get_period_start_time (demux);

    stream->starting_fragment = FALSE;
    if (klass->start_fragment) {
      if (!klass->start_fragment (demux, stream)) {
        ret = GST_FLOW_ERROR;
        goto error;
      }
    }

    GST_BUFFER_PTS (buffer) = stream->fragment.timestamp;
    if (GST_BUFFER_PTS_IS_VALID (buffer))
      GST_BUFFER_PTS (buffer) += offset;

    GST_LOG_OBJECT (stream->pad, "set fragment pts=%" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_BUFFER_PTS (buffer)));

    if (GST_BUFFER_PTS_IS_VALID (buffer)) {
      GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux);
      stream->segment.position = GST_BUFFER_PTS (buffer);

      /* Convert from position inside the stream's segment to the demuxer's
       * segment, they are not necessarily the same */
      if (stream->segment.position - offset + period_start >
          demux->segment.position)
        demux->segment.position =
            stream->segment.position - offset + period_start;
      GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);
    }

  } else {
    GST_BUFFER_PTS (buffer) = GST_CLOCK_TIME_NONE;
  }
  if (stream->downloading_first_buffer) {
    gint64 chunk_size = 0;

    stream->downloading_first_buffer = FALSE;

    if (!stream->downloading_header && !stream->downloading_index) {
      /* If this is the first buffer of a fragment (not the headers or index)
       * and we don't have a birate from the sub-class, then see if we
       * can work it out from the fragment size and duration */
      if (stream->fragment.bitrate == 0 &&
          stream->fragment.duration != 0 &&
          gst_element_query_duration (stream->uri_handler, GST_FORMAT_BYTES,
              &chunk_size)) {
        guint bitrate = MIN (G_MAXUINT, gst_util_uint64_scale (chunk_size,
                8 * GST_SECOND, stream->fragment.duration));
        GST_LOG_OBJECT (demux,
            "Fragment has size %" G_GUINT64_FORMAT " duration %" GST_TIME_FORMAT
            " = bitrate %u", chunk_size,
            GST_TIME_ARGS (stream->fragment.duration), bitrate);
        stream->fragment.bitrate = bitrate;
      }
      if (stream->fragment.bitrate) {
        stream->bitrate_changed = TRUE;
      } else {
        GST_WARNING_OBJECT (demux, "Bitrate for fragment not available");
      }
    }
  }

  stream->download_total_bytes += gst_buffer_get_size (buffer);

  GST_DEBUG_OBJECT (stream->pad, "Received buffer of size %" G_GSIZE_FORMAT,
      gst_buffer_get_size (buffer));

  ret = klass->data_received (demux, stream, buffer);

  if (ret == GST_FLOW_FLUSHING) {
    /* do not make any changes if the stream is cancelled */
    g_mutex_lock (&stream->fragment_download_lock);
    if (G_UNLIKELY (stream->cancelled)) {
      g_mutex_unlock (&stream->fragment_download_lock);
      GST_MANIFEST_UNLOCK (demux);
      return ret;
    }
    g_mutex_unlock (&stream->fragment_download_lock);
  }

  if (ret != GST_FLOW_OK) {
    gboolean finished = FALSE;

    if (ret < GST_FLOW_EOS) {
      GST_ELEMENT_FLOW_ERROR (demux, ret);

      /* TODO push this on all pads */
      gst_pad_push_event (stream->pad, gst_event_new_eos ());
    } else {
      GST_DEBUG_OBJECT (stream->pad, "stream stopped, reason %s",
          gst_flow_get_name (ret));
    }

    if (ret == (GstFlowReturn) GST_ADAPTIVE_DEMUX_FLOW_SWITCH) {
      ret = GST_FLOW_EOS;       /* return EOS to make the source stop */
    } else if (ret == GST_ADAPTIVE_DEMUX_FLOW_END_OF_FRAGMENT) {
      /* Behaves like an EOS event from upstream */
      stream->fragment.finished = TRUE;
      ret = klass->finish_fragment (demux, stream);
      if (ret == (GstFlowReturn) GST_ADAPTIVE_DEMUX_FLOW_SWITCH) {
        ret = GST_FLOW_EOS;     /* return EOS to make the source stop */
      } else if (ret != GST_FLOW_OK) {
        goto error;
      }
      finished = TRUE;
    }

    gst_adaptive_demux_stream_fragment_download_finish (stream, ret, NULL);
    if (finished)
      ret = GST_FLOW_EOS;
  }

error:

  GST_MANIFEST_UNLOCK (demux);

  return ret;
}

/* must be called with manifest_lock taken */
static void
gst_adaptive_demux_stream_fragment_download_finish (GstAdaptiveDemuxStream *
    stream, GstFlowReturn ret, GError * err)
{
  GST_DEBUG_OBJECT (stream->pad, "Download finish: %d %s - err: %p", ret,
      gst_flow_get_name (ret), err);

  /* if we have an error, only replace last_ret if it was OK before to avoid
   * overwriting the first error we got */
  if (stream->last_ret == GST_FLOW_OK) {
    stream->last_ret = ret;
    if (err) {
      g_clear_error (&stream->last_error);
      stream->last_error = g_error_copy (err);
    }
  }
  g_mutex_lock (&stream->fragment_download_lock);
  stream->download_finished = TRUE;
  g_cond_signal (&stream->fragment_download_cond);
  g_mutex_unlock (&stream->fragment_download_lock);
}

static GstFlowReturn
gst_adaptive_demux_eos_handling (GstAdaptiveDemuxStream * stream)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (stream->demux);

  if (!klass->need_another_chunk || stream->fragment.chunk_size == -1
      || !klass->need_another_chunk (stream)
      || stream->fragment.chunk_size == 0) {
    stream->fragment.finished = TRUE;
    ret = klass->finish_fragment (stream->demux, stream);
  }
  gst_adaptive_demux_stream_fragment_download_finish (stream, ret, NULL);

  return ret;
}

static gboolean
_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstAdaptiveDemuxStream *stream = gst_pad_get_element_private (pad);
  GstAdaptiveDemux *demux = stream->demux;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:{
      GST_MANIFEST_LOCK (demux);

      gst_adaptive_demux_eos_handling (stream);

      g_mutex_lock (&stream->fragment_download_lock);
      stream->download_finished = TRUE;
      g_cond_signal (&stream->fragment_download_cond);
      g_mutex_unlock (&stream->fragment_download_lock);

      GST_MANIFEST_UNLOCK (demux);
      break;
    }
    default:
      break;
  }

  gst_event_unref (event);

  return TRUE;
}

static gboolean
_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstAdaptiveDemuxStream *stream = gst_pad_get_element_private (pad);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_ALLOCATION:
      return FALSE;
      break;
    default:
      break;
  }

  return gst_pad_peer_query (stream->pad, query);
}

static GstPadProbeReturn
_uri_handler_probe (GstPad * pad, GstPadProbeInfo * info,
    GstAdaptiveDemuxStream * stream)
{
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;

  if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER) {
    GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER (info);
    if (stream->fragment_bytes_downloaded == 0) {
      stream->last_latency =
          gst_adaptive_demux_get_monotonic_time (stream->demux) -
          (stream->download_start_time * GST_USECOND);
      GST_DEBUG_OBJECT (pad,
          "FIRST BYTE since download_start %" GST_TIME_FORMAT,
          GST_TIME_ARGS (stream->last_latency));
    }
    stream->fragment_bytes_downloaded += gst_buffer_get_size (buf);
    GST_LOG_OBJECT (pad,
        "Received buffer, size %" G_GSIZE_FORMAT " total %" G_GUINT64_FORMAT,
        gst_buffer_get_size (buf), stream->fragment_bytes_downloaded);
  } else if (GST_PAD_PROBE_INFO_TYPE (info) &
      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
    GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);
    GST_LOG_OBJECT (pad, "Received event %s %" GST_PTR_FORMAT,
        GST_EVENT_TYPE_NAME (ev), ev);
    switch (GST_EVENT_TYPE (ev)) {
      case GST_EVENT_SEGMENT:
        stream->fragment_bytes_downloaded = 0;
        break;
      case GST_EVENT_EOS:
      {
        stream->last_download_time =
            gst_adaptive_demux_get_monotonic_time (stream->demux) -
            (stream->download_start_time * GST_USECOND);
        stream->last_bitrate =
            gst_util_uint64_scale (stream->fragment_bytes_downloaded,
            8 * GST_SECOND, stream->last_download_time);
        GST_DEBUG_OBJECT (pad,
            "EOS since download_start %" GST_TIME_FORMAT " bitrate %"
            G_GUINT64_FORMAT " bps", GST_TIME_ARGS (stream->last_download_time),
            stream->last_bitrate);
        /* Calculate bitrate since URI request */
      }
        break;
      default:
        break;
    }
  }

  return ret;
}

/* must be called with manifest_lock taken.
 * Can temporarily release manifest_lock
 */
static gboolean
gst_adaptive_demux_stream_wait_manifest_update (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  gboolean ret = TRUE;

  /* Wait until we're cancelled or there's something for
   * us to download in the playlist or the playlist
   * became non-live */
  while (TRUE) {
    GST_DEBUG_OBJECT (demux, "No fragment left but live playlist, wait a bit");

    /* get the manifest_update_lock while still holding the manifest_lock.
     * This will prevent other threads to signal the condition (they will need
     * both manifest_lock and manifest_update_lock in order to signal).
     * It cannot deadlock because all threads always get the manifest_lock first
     * and manifest_update_lock second.
     */
    g_mutex_lock (&demux->priv->manifest_update_lock);

    GST_MANIFEST_UNLOCK (demux);

    g_cond_wait (&demux->priv->manifest_cond,
        &demux->priv->manifest_update_lock);
    g_mutex_unlock (&demux->priv->manifest_update_lock);

    GST_MANIFEST_LOCK (demux);

    /* check for cancelled every time we get the manifest_lock */
    g_mutex_lock (&stream->fragment_download_lock);
    if (G_UNLIKELY (stream->cancelled)) {
      ret = FALSE;
      stream->last_ret = GST_FLOW_FLUSHING;
      g_mutex_unlock (&stream->fragment_download_lock);
      break;
    }
    g_mutex_unlock (&stream->fragment_download_lock);

    /* Got a new fragment or not live anymore? */
    if (gst_adaptive_demux_stream_has_next_fragment (demux, stream)) {
      GST_DEBUG_OBJECT (demux, "new fragment available, "
          "not waiting for manifest update");
      ret = TRUE;
      break;
    }

    if (!gst_adaptive_demux_is_live (demux)) {
      GST_DEBUG_OBJECT (demux, "Not live anymore, "
          "not waiting for manifest update");
      ret = FALSE;
      break;
    }
  }
  GST_DEBUG_OBJECT (demux, "Retrying now");
  return ret;
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_stream_update_source (GstAdaptiveDemuxStream * stream,
    const gchar * uri, const gchar * referer, gboolean refresh,
    gboolean allow_cache)
{
  GstAdaptiveDemux *demux = stream->demux;

  if (!gst_uri_is_valid (uri)) {
    GST_WARNING_OBJECT (stream->pad, "Invalid URI: %s", uri);
    return FALSE;
  }

  if (stream->src != NULL) {
    gchar *old_protocol, *new_protocol;
    gchar *old_uri;

    old_uri = gst_uri_handler_get_uri (GST_URI_HANDLER (stream->uri_handler));
    old_protocol = gst_uri_get_protocol (old_uri);
    new_protocol = gst_uri_get_protocol (uri);

    if (!g_str_equal (old_protocol, new_protocol)) {
      GstElement *src = stream->src;

      stream->src = NULL;
      gst_object_unref (stream->src_srcpad);
      stream->src_srcpad = NULL;
      GST_MANIFEST_UNLOCK (demux);
      gst_element_set_locked_state (src, TRUE);
      gst_element_set_state (src, GST_STATE_NULL);
      gst_bin_remove (GST_BIN_CAST (demux), src);
      GST_MANIFEST_LOCK (demux);
      GST_DEBUG_OBJECT (demux, "Can't re-use old source element");
    } else {
      GError *err = NULL;

      GST_DEBUG_OBJECT (demux, "Re-using old source element");
      if (!gst_uri_handler_set_uri (GST_URI_HANDLER (stream->uri_handler), uri,
              &err)) {
        GstElement *src = stream->src;

        stream->src = NULL;
        GST_DEBUG_OBJECT (demux, "Failed to re-use old source element: %s",
            err ? err->message : "Unknown error");
        g_clear_error (&err);
        gst_object_unref (stream->src_srcpad);
        stream->src_srcpad = NULL;
        GST_MANIFEST_UNLOCK (demux);
        gst_element_set_locked_state (src, TRUE);
        gst_element_set_state (src, GST_STATE_NULL);
        gst_bin_remove (GST_BIN_CAST (demux), src);
        GST_MANIFEST_LOCK (demux);
      }
    }
    g_free (old_uri);
    g_free (old_protocol);
    g_free (new_protocol);
  }

  if (stream->src == NULL) {
    GstPad *uri_handler_src;
    GstPad *queue_sink;
    GstPad *queue_src;
    GstElement *uri_handler;
    GstElement *queue;
    GstPadLinkReturn pad_link_ret;
    GObjectClass *gobject_class;
    gchar *internal_name, *bin_name;

    /* Our src consists of a bin containing uri_handler -> queue . The
     * purpose of the queue is to allow the uri_handler to download an
     * entire fragment without blocking, so we can accurately measure the
     * download bitrate. */

    queue = gst_element_factory_make ("queue", NULL);
    if (queue == NULL)
      return FALSE;

    g_object_set (queue, "max-size-bytes", (guint) SRC_QUEUE_MAX_BYTES, NULL);
    g_object_set (queue, "max-size-buffers", (guint) 0, NULL);
    g_object_set (queue, "max-size-time", (guint64) 0, NULL);

    uri_handler = gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL);
    if (uri_handler == NULL) {
      GST_ELEMENT_ERROR (demux, CORE, MISSING_PLUGIN,
          ("Missing plugin to handle URI: '%s'", uri), (NULL));
      gst_object_unref (queue);
      return FALSE;
    }

    gobject_class = G_OBJECT_GET_CLASS (uri_handler);

    if (g_object_class_find_property (gobject_class, "compress"))
      g_object_set (uri_handler, "compress", FALSE, NULL);
    if (g_object_class_find_property (gobject_class, "keep-alive"))
      g_object_set (uri_handler, "keep-alive", TRUE, NULL);
    if (g_object_class_find_property (gobject_class, "extra-headers")) {
      if (referer || refresh || !allow_cache) {
        GstStructure *extra_headers = gst_structure_new_empty ("headers");

        if (referer)
          gst_structure_set (extra_headers, "Referer", G_TYPE_STRING, referer,
              NULL);

        if (!allow_cache)
          gst_structure_set (extra_headers, "Cache-Control", G_TYPE_STRING,
              "no-cache", NULL);
        else if (refresh)
          gst_structure_set (extra_headers, "Cache-Control", G_TYPE_STRING,
              "max-age=0", NULL);

        g_object_set (uri_handler, "extra-headers", extra_headers, NULL);

        gst_structure_free (extra_headers);
      } else {
        g_object_set (uri_handler, "extra-headers", NULL, NULL);
      }
    }

    /* Source bin creation */
    bin_name = g_strdup_printf ("srcbin-%s", GST_PAD_NAME (stream->pad));
    stream->src = gst_bin_new (bin_name);
    g_free (bin_name);
    if (stream->src == NULL) {
      gst_object_unref (queue);
      gst_object_unref (uri_handler);
      return FALSE;
    }

    gst_bin_add (GST_BIN_CAST (stream->src), queue);
    gst_bin_add (GST_BIN_CAST (stream->src), uri_handler);

    uri_handler_src = gst_element_get_static_pad (uri_handler, "src");
    queue_sink = gst_element_get_static_pad (queue, "sink");

    pad_link_ret =
        gst_pad_link_full (uri_handler_src, queue_sink,
        GST_PAD_LINK_CHECK_NOTHING);
    if (GST_PAD_LINK_FAILED (pad_link_ret)) {
      GST_WARNING_OBJECT (demux,
          "Could not link pads %s:%s to %s:%s for reason %d",
          GST_DEBUG_PAD_NAME (uri_handler_src), GST_DEBUG_PAD_NAME (queue_sink),
          pad_link_ret);
      g_object_unref (queue_sink);
      g_object_unref (uri_handler_src);
      gst_object_unref (stream->src);
      stream->src = NULL;
      return FALSE;
    }

    /* Add a downstream event and data probe */
    gst_pad_add_probe (uri_handler_src, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
        (GstPadProbeCallback) _uri_handler_probe, stream, NULL);

    g_object_unref (queue_sink);
    g_object_unref (uri_handler_src);
    queue_src = gst_element_get_static_pad (queue, "src");
    stream->src_srcpad = gst_ghost_pad_new ("src", queue_src);
    g_object_unref (queue_src);
    gst_element_add_pad (stream->src, stream->src_srcpad);

    gst_element_set_locked_state (stream->src, TRUE);
    gst_bin_add (GST_BIN_CAST (demux), stream->src);
    stream->src_srcpad = gst_element_get_static_pad (stream->src, "src");

    /* set up our internal floating pad to drop all events from
     * the http src we don't care about. On the chain function
     * we just push the buffer forward */
    internal_name = g_strdup_printf ("internal-%s", GST_PAD_NAME (stream->pad));
    stream->internal_pad = gst_pad_new (internal_name, GST_PAD_SINK);
    g_free (internal_name);
    gst_object_set_parent (GST_OBJECT_CAST (stream->internal_pad),
        GST_OBJECT_CAST (demux));
    GST_OBJECT_FLAG_SET (stream->internal_pad, GST_PAD_FLAG_NEED_PARENT);
    gst_pad_set_element_private (stream->internal_pad, stream);
    gst_pad_set_active (stream->internal_pad, TRUE);
    gst_pad_set_chain_function (stream->internal_pad, _src_chain);
    gst_pad_set_event_function (stream->internal_pad, _src_event);
    gst_pad_set_query_function (stream->internal_pad, _src_query);

    if (gst_pad_link_full (stream->src_srcpad, stream->internal_pad,
            GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK) {
      GST_ERROR_OBJECT (stream->pad, "Failed to link internal pad");
      return FALSE;
    }

    stream->uri_handler = uri_handler;
    stream->queue = queue;

    stream->last_status_code = 200;     /* default to OK */
  }
  return TRUE;
}

static GstPadProbeReturn
gst_ad_stream_src_to_ready_cb (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  GstAdaptiveDemuxStream *stream = user_data;

  /* The source's src pad is IDLE so now set the state to READY */
  g_mutex_lock (&stream->fragment_download_lock);
  stream->src_at_ready = TRUE;
  g_cond_signal (&stream->fragment_download_cond);
  g_mutex_unlock (&stream->fragment_download_lock);

  return GST_PAD_PROBE_OK;
}

#ifndef GST_DISABLE_GST_DEBUG
static const char *
uritype (GstAdaptiveDemuxStream * s)
{
  if (s->downloading_header)
    return "header";
  if (s->downloading_index)
    return "index";
  return "fragment";
}
#endif

/* must be called with manifest_lock taken.
 * Can temporarily release manifest_lock
 */
static GstFlowReturn
gst_adaptive_demux_stream_download_uri (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, const gchar * uri, gint64 start,
    gint64 end, guint * http_status)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GST_DEBUG_OBJECT (stream->pad,
      "Downloading %s uri: %s, range:%" G_GINT64_FORMAT " - %" G_GINT64_FORMAT,
      uritype (stream), uri, start, end);

  if (http_status)
    *http_status = 200;         /* default to ok if no further information */

  if (!gst_adaptive_demux_stream_update_source (stream, uri, NULL, FALSE, TRUE)) {
    ret = stream->last_ret = GST_FLOW_ERROR;
    return ret;
  }

  gst_element_set_locked_state (stream->src, TRUE);

  GST_MANIFEST_UNLOCK (demux);
  if (gst_element_set_state (stream->src,
          GST_STATE_READY) != GST_STATE_CHANGE_FAILURE) {
    if (start != 0 || end != -1) {
      /* HTTP ranges are inclusive, GStreamer segments are exclusive for the
       * stop position */
      if (end != -1)
        end += 1;
      /* Send the seek event to the uri_handler, as the other pipeline elements
       * can't handle it when READY. */
      if (!gst_element_send_event (stream->uri_handler, gst_event_new_seek (1.0,
                  GST_FORMAT_BYTES, (GstSeekFlags) GST_SEEK_FLAG_FLUSH,
                  GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_SET, end))) {

        GST_MANIFEST_LOCK (demux);
        /* looks like the source can't handle seeks in READY */
        g_clear_error (&stream->last_error);
        stream->last_error = g_error_new (GST_CORE_ERROR,
            GST_CORE_ERROR_NOT_IMPLEMENTED,
            "Source element can't handle range requests");
        stream->last_ret = GST_FLOW_ERROR;
      } else {
        GST_MANIFEST_LOCK (demux);
      }
    } else {
      GST_MANIFEST_LOCK (demux);
    }

    if (G_LIKELY (stream->last_ret == GST_FLOW_OK)) {
      stream->download_start_time =
          GST_TIME_AS_USECONDS (gst_adaptive_demux_get_monotonic_time (demux));

      /* src element is in state READY. Before we start it, we reset
       * download_finished
       */
      g_mutex_lock (&stream->fragment_download_lock);
      stream->download_finished = FALSE;
      stream->downloading_first_buffer = TRUE;
      g_mutex_unlock (&stream->fragment_download_lock);

      GST_MANIFEST_UNLOCK (demux);

      if (!gst_element_sync_state_with_parent (stream->src)) {
        GST_WARNING_OBJECT (demux, "Could not sync state for src element");
        GST_MANIFEST_LOCK (demux);
        ret = stream->last_ret = GST_FLOW_ERROR;
        return ret;
      }

      /* wait for the fragment to be completely downloaded */
      GST_DEBUG_OBJECT (stream->pad,
          "Waiting for %s download to finish: %s", uritype (stream), uri);

      g_mutex_lock (&stream->fragment_download_lock);
      stream->src_at_ready = FALSE;
      if (G_UNLIKELY (stream->cancelled)) {
        g_mutex_unlock (&stream->fragment_download_lock);
        GST_MANIFEST_LOCK (demux);
        ret = stream->last_ret = GST_FLOW_FLUSHING;
        return ret;
      }
      while (!stream->cancelled && !stream->download_finished) {
        g_cond_wait (&stream->fragment_download_cond,
            &stream->fragment_download_lock);
      }
      g_mutex_unlock (&stream->fragment_download_lock);

      GST_MANIFEST_LOCK (demux);
      g_mutex_lock (&stream->fragment_download_lock);
      if (G_UNLIKELY (stream->cancelled)) {
        ret = stream->last_ret = GST_FLOW_FLUSHING;
        g_mutex_unlock (&stream->fragment_download_lock);
        return ret;
      }
      g_mutex_unlock (&stream->fragment_download_lock);

      ret = stream->last_ret;

      GST_DEBUG_OBJECT (stream->pad, "%s download finished: %s %d %s",
          uritype (stream), uri, stream->last_ret,
          gst_flow_get_name (stream->last_ret));
      if (stream->last_ret != GST_FLOW_OK && http_status) {
        *http_status = stream->last_status_code;
      }
    }

    /* changing src element state might try to join the streaming thread, so
     * we must not hold the manifest lock.
     */
    GST_MANIFEST_UNLOCK (demux);
  } else {
    GST_MANIFEST_UNLOCK (demux);
    if (stream->last_ret == GST_FLOW_OK)
      stream->last_ret = GST_FLOW_CUSTOM_ERROR;
    ret = GST_FLOW_CUSTOM_ERROR;
  }

  stream->src_at_ready = FALSE;

  gst_element_set_locked_state (stream->src, TRUE);
  gst_pad_add_probe (stream->src_srcpad, GST_PAD_PROBE_TYPE_IDLE,
      gst_ad_stream_src_to_ready_cb, stream, NULL);

  g_mutex_lock (&stream->fragment_download_lock);
  while (!stream->src_at_ready) {
    g_cond_wait (&stream->fragment_download_cond,
        &stream->fragment_download_lock);
  }
  g_mutex_unlock (&stream->fragment_download_lock);

  gst_element_set_state (stream->src, GST_STATE_READY);

  /* Need to drop the fragment_download_lock to get the MANIFEST lock */
  GST_MANIFEST_LOCK (demux);
  g_mutex_lock (&stream->fragment_download_lock);
  if (G_UNLIKELY (stream->cancelled)) {
    ret = stream->last_ret = GST_FLOW_FLUSHING;
    g_mutex_unlock (&stream->fragment_download_lock);
    return ret;
  }
  g_mutex_unlock (&stream->fragment_download_lock);

  /* deactivate and reactivate our ghostpad to make it fresh for a new
   * stream */
  gst_pad_set_active (stream->internal_pad, FALSE);
  gst_pad_set_active (stream->internal_pad, TRUE);

  return ret;
}

/* must be called with manifest_lock taken.
 * Can temporarily release manifest_lock
 */
static GstFlowReturn
gst_adaptive_demux_stream_download_header_fragment (GstAdaptiveDemuxStream *
    stream)
{
  GstAdaptiveDemux *demux = stream->demux;
  GstFlowReturn ret = GST_FLOW_OK;

  if (stream->fragment.header_uri != NULL) {
    GST_DEBUG_OBJECT (demux, "Fetching header %s %" G_GINT64_FORMAT "-%"
        G_GINT64_FORMAT, stream->fragment.header_uri,
        stream->fragment.header_range_start, stream->fragment.header_range_end);

    stream->downloading_header = TRUE;
    ret = gst_adaptive_demux_stream_download_uri (demux, stream,
        stream->fragment.header_uri, stream->fragment.header_range_start,
        stream->fragment.header_range_end, NULL);
    stream->downloading_header = FALSE;
  }

  /* check if we have an index */
  if (ret == GST_FLOW_OK) {     /* TODO check for other valid types */

    if (stream->fragment.index_uri != NULL) {
      GST_DEBUG_OBJECT (demux,
          "Fetching index %s %" G_GINT64_FORMAT "-%" G_GINT64_FORMAT,
          stream->fragment.index_uri,
          stream->fragment.index_range_start, stream->fragment.index_range_end);
      stream->downloading_index = TRUE;
      ret = gst_adaptive_demux_stream_download_uri (demux, stream,
          stream->fragment.index_uri, stream->fragment.index_range_start,
          stream->fragment.index_range_end, NULL);
      stream->downloading_index = FALSE;
    }
  }

  return ret;
}

/* must be called with manifest_lock taken.
 * Can temporarily release manifest_lock
 */
static GstFlowReturn
gst_adaptive_demux_stream_download_fragment (GstAdaptiveDemuxStream * stream)
{
  GstAdaptiveDemux *demux = stream->demux;
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  gchar *url = NULL;
  GstFlowReturn ret;
  gboolean retried_once = FALSE, live;
  guint http_status;
  guint last_status_code;

  stream->starting_fragment = TRUE;
  stream->last_ret = GST_FLOW_OK;
  stream->first_fragment_buffer = TRUE;

  if (stream->fragment.uri == NULL && stream->fragment.header_uri == NULL &&
      stream->fragment.index_uri == NULL)
    goto no_url_error;

  if (stream->need_header) {
    ret = gst_adaptive_demux_stream_download_header_fragment (stream);
    if (ret != GST_FLOW_OK) {
      return ret;
    }
    stream->need_header = FALSE;
  }

again:
  ret = GST_FLOW_OK;
  url = stream->fragment.uri;
  GST_DEBUG_OBJECT (stream->pad, "Got url '%s' for stream %p", url, stream);
  if (!url)
    return ret;

  stream->last_ret = GST_FLOW_OK;
  http_status = 200;

  if (klass->need_another_chunk && klass->need_another_chunk (stream)
      && stream->fragment.chunk_size != 0) {
    gint64 range_start, range_end, chunk_start, chunk_end;
    guint64 download_total_bytes;
    gint chunk_size = stream->fragment.chunk_size;

    range_start = chunk_start = stream->fragment.range_start;
    range_end = stream->fragment.range_end;
    /* HTTP ranges are inclusive for the end */
    if (chunk_size != -1)
      chunk_end = range_start + chunk_size - 1;
    else
      chunk_end = range_end;

    if (range_end != -1)
      chunk_end = MIN (chunk_end, range_end);

    while (!stream->fragment.finished && (chunk_start <= range_end
            || range_end == -1)) {
      download_total_bytes = stream->download_total_bytes;

      ret =
          gst_adaptive_demux_stream_download_uri (demux, stream, url,
          chunk_start, chunk_end, &http_status);

      GST_DEBUG_OBJECT (stream->pad,
          "Fragment chunk download result: %d (%d) %s", stream->last_ret,
          http_status, gst_flow_get_name (stream->last_ret));

      /* Don't retry for any chunks except the first. We would have sent
       * data downstream already otherwise and it's difficult to recover
       * from that in a meaningful way */
      if (chunk_start > range_start)
        retried_once = TRUE;

      /* FIXME: Check for 416 Range Not Satisfiable here and fall back to
       * downloading up to -1. We don't know the full duration.
       * Needs https://bugzilla.gnome.org/show_bug.cgi?id=756806 */
      if (ret != GST_FLOW_OK && chunk_end == -1) {
        break;
      } else if (ret != GST_FLOW_OK) {
        chunk_end = -1;
        stream->last_ret = GST_FLOW_OK;
        continue;
      }

      if (chunk_end == -1)
        break;

      /* Short read, we're at the end now */
      if (stream->download_total_bytes - download_total_bytes <
          chunk_end + 1 - chunk_start)
        break;

      if (!klass->need_another_chunk (stream))
        break;

      /* HTTP ranges are inclusive for the end */
      chunk_start += chunk_size;
      chunk_size = stream->fragment.chunk_size;
      if (chunk_size != -1)
        chunk_end = chunk_start + chunk_size - 1;
      else
        chunk_end = range_end;

      if (range_end != -1)
        chunk_end = MIN (chunk_end, range_end);
    }
  } else {
    ret =
        gst_adaptive_demux_stream_download_uri (demux, stream, url,
        stream->fragment.range_start, stream->fragment.range_end, &http_status);
    GST_DEBUG_OBJECT (stream->pad, "Fragment download result: %d (%d) %s",
        stream->last_ret, http_status, gst_flow_get_name (stream->last_ret));
  }
  if (ret == GST_FLOW_OK)
    goto beach;

  g_mutex_lock (&stream->fragment_download_lock);
  if (G_UNLIKELY (stream->cancelled)) {
    g_mutex_unlock (&stream->fragment_download_lock);
    return ret;
  }
  g_mutex_unlock (&stream->fragment_download_lock);

  /* TODO check if we are truly stopping */
  if (ret != GST_FLOW_CUSTOM_ERROR)
    goto beach;

  last_status_code = stream->last_status_code;
  GST_WARNING_OBJECT (stream->pad, "Got custom error, status %u, dc %d",
      last_status_code, stream->download_error_count);

  live = gst_adaptive_demux_is_live (demux);
  if (!retried_once && ((last_status_code / 100 == 4 && live) || last_status_code / 100 == 5)) {        /* 4xx/5xx */
    /* if current position is before available start, switch to next */
    if (!gst_adaptive_demux_stream_has_next_fragment (demux, stream))
      goto flushing;

    if (live) {
      gint64 range_start, range_stop;

      if (!gst_adaptive_demux_get_live_seek_range (demux, &range_start,
              &range_stop))
        goto flushing;

      if (demux->segment.position < range_start) {
        GST_DEBUG_OBJECT (stream->pad, "Retrying once with next segment");
        stream->last_ret = GST_FLOW_OK;
        ret = gst_adaptive_demux_eos_handling (stream);
        GST_DEBUG_OBJECT (stream->pad, "finish_fragment: %s",
            gst_flow_get_name (ret));
        ret = gst_adaptive_demux_stream_update_fragment_info (demux, stream);
        GST_DEBUG_OBJECT (stream->pad, "finish_fragment: %s",
            gst_flow_get_name (ret));
        if (ret == GST_FLOW_OK) {
          retried_once = TRUE;
          goto again;
        }
      } else if (demux->segment.position > range_stop) {
        /* wait a bit to be in range, we don't have any locks at that point */
        gint64 wait_time =
            gst_adaptive_demux_stream_get_fragment_waiting_time (demux, stream);
        if (wait_time > 0) {
          gint64 end_time = g_get_monotonic_time () + wait_time / GST_USECOND;

          GST_DEBUG_OBJECT (stream->pad,
              "Download waiting for %" GST_TIME_FORMAT,
              GST_TIME_ARGS (wait_time));

          GST_MANIFEST_UNLOCK (demux);
          g_mutex_lock (&stream->fragment_download_lock);
          if (G_UNLIKELY (stream->cancelled)) {
            g_mutex_unlock (&stream->fragment_download_lock);
            GST_MANIFEST_LOCK (demux);
            stream->last_ret = GST_FLOW_FLUSHING;
            goto flushing;
          }
          do {
            g_cond_wait_until (&stream->fragment_download_cond,
                &stream->fragment_download_lock, end_time);
            if (G_UNLIKELY (stream->cancelled)) {
              g_mutex_unlock (&stream->fragment_download_lock);
              GST_MANIFEST_LOCK (demux);
              stream->last_ret = GST_FLOW_FLUSHING;
              goto flushing;
            }
          } while (!stream->download_finished);
          g_mutex_unlock (&stream->fragment_download_lock);

          GST_MANIFEST_LOCK (demux);
        }
      }
    }

  flushing:
    if (++stream->download_error_count <= MAX_DOWNLOAD_ERROR_COUNT) {
      /* looks like there is no way of knowing when a live stream has ended
       * Have to assume we are falling behind and cause a manifest reload */
      GST_DEBUG_OBJECT (stream->pad, "Converting error of live stream to EOS");
      return GST_FLOW_EOS;
    }
  }

  else if (!gst_adaptive_demux_stream_has_next_fragment (demux, stream)) {
    /* If this is the last fragment, consider failures EOS and not actual
     * errors. Due to rounding errors in the durations, the last fragment
     * might not actually exist */
    GST_DEBUG_OBJECT (stream->pad, "Converting error for last fragment to EOS");
    return GST_FLOW_EOS;
  } else {
    /* retry once (same segment) for 5xx (server errors) */
    if (!retried_once) {
      retried_once = TRUE;
      /* wait a short time in case the server needs a bit to recover, we don't
       * care if we get woken up before end time. We can use sleep here since
       * we're already blocking and just want to wait some time. */
      g_usleep (100000);        /* a tenth of a second */
      goto again;
    }
  }

beach:
  return ret;

no_url_error:
  {
    GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
        (_("Failed to get fragment URL.")),
        ("An error happened when getting fragment URL"));
    gst_task_stop (stream->download_task);
    return GST_FLOW_ERROR;
  }
}

/* this function will take the manifest_lock and will keep it until the end.
 * It will release it temporarily only when going to sleep.
 * Every time it takes the manifest_lock, it will check for cancelled condition
 */
static void
gst_adaptive_demux_stream_download_loop (GstAdaptiveDemuxStream * stream)
{
  GstAdaptiveDemux *demux = stream->demux;
  GstClockTime next_download = gst_adaptive_demux_get_monotonic_time (demux);
  GstFlowReturn ret;
  gboolean live;

  GST_LOG_OBJECT (stream->pad, "download loop start");

  GST_MANIFEST_LOCK (demux);

  g_mutex_lock (&stream->fragment_download_lock);
  if (G_UNLIKELY (stream->cancelled)) {
    stream->last_ret = GST_FLOW_FLUSHING;
    g_mutex_unlock (&stream->fragment_download_lock);
    goto cancelled;
  }
  g_mutex_unlock (&stream->fragment_download_lock);

  /* Check if we're done with our segment */
  GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux);
  if (demux->segment.rate > 0) {
    if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop)
        && stream->segment.position >= stream->segment.stop) {
      GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);
      ret = GST_FLOW_EOS;
      gst_task_stop (stream->download_task);
      goto end_of_manifest;
    }
  } else {
    if (GST_CLOCK_TIME_IS_VALID (demux->segment.start)
        && stream->segment.position <= stream->segment.start) {
      GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);
      ret = GST_FLOW_EOS;
      gst_task_stop (stream->download_task);
      goto end_of_manifest;
    }
  }
  GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);

  /* Cleanup old streams if any */
  if (G_UNLIKELY (demux->priv->old_streams != NULL)) {
    GList *old_streams = demux->priv->old_streams;
    demux->priv->old_streams = NULL;

    GST_DEBUG_OBJECT (stream->pad, "Cleaning up old streams");
    g_list_free_full (old_streams,
        (GDestroyNotify) gst_adaptive_demux_stream_free);
    GST_DEBUG_OBJECT (stream->pad, "Cleaning up old streams (done)");

    /* gst_adaptive_demux_stream_free had temporarily released the manifest_lock.
     * Recheck the cancelled flag.
     */
    g_mutex_lock (&stream->fragment_download_lock);
    if (G_UNLIKELY (stream->cancelled)) {
      stream->last_ret = GST_FLOW_FLUSHING;
      g_mutex_unlock (&stream->fragment_download_lock);
      goto cancelled;
    }
    g_mutex_unlock (&stream->fragment_download_lock);
  }

  if (G_UNLIKELY (stream->restart_download)) {
    GstEvent *seg_event;
    GstClockTime cur, ts = 0;
    gint64 pos;

    GST_DEBUG_OBJECT (stream->pad,
        "Activating stream due to reconfigure event");

    if (gst_pad_peer_query_position (stream->pad, GST_FORMAT_TIME, &pos)) {
      ts = (GstClockTime) pos;
      GST_DEBUG_OBJECT (demux, "Downstream position: %"
          GST_TIME_FORMAT, GST_TIME_ARGS (ts));
    } else {
      /* query other pads as some faulty element in the pad's branch might
       * reject position queries. This should be better than using the
       * demux segment position that can be much ahead */
      GList *iter;

      for (iter = demux->streams; iter != NULL; iter = g_list_next (iter)) {
        GstAdaptiveDemuxStream *cur_stream =
            (GstAdaptiveDemuxStream *) iter->data;

        if (gst_pad_peer_query_position (cur_stream->pad, GST_FORMAT_TIME,
                &pos)) {
          ts = (GstClockTime) pos;
          GST_DEBUG_OBJECT (stream->pad, "Downstream position: %"
              GST_TIME_FORMAT, GST_TIME_ARGS (ts));
          break;
        }
      }
    }

    GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux);
    cur =
        gst_segment_to_stream_time (&stream->segment, GST_FORMAT_TIME,
        stream->segment.position);

    /* we might have already pushed this data */
    ts = MAX (ts, cur);

    GST_DEBUG_OBJECT (stream->pad, "Restarting stream at "
        "position %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));

    if (GST_CLOCK_TIME_IS_VALID (ts)) {
      GstClockTime offset, period_start;

      offset =
          gst_adaptive_demux_stream_get_presentation_offset (demux, stream);
      period_start = gst_adaptive_demux_get_period_start_time (demux);

      /* TODO check return */
      gst_adaptive_demux_stream_seek (demux, stream, demux->segment.rate >= 0,
          0, ts, &ts);

      stream->segment.position = ts - period_start + offset;
    }

    /* The stream's segment is still correct except for
     * the position, so let's send a new one with the
     * updated position */
    seg_event = gst_event_new_segment (&stream->segment);
    gst_event_set_seqnum (seg_event, demux->priv->segment_seqnum);
    GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);

    GST_DEBUG_OBJECT (stream->pad, "Sending restart segment: %"
        GST_PTR_FORMAT, seg_event);
    gst_pad_push_event (stream->pad, seg_event);

    stream->discont = TRUE;
    stream->restart_download = FALSE;
  }

  live = gst_adaptive_demux_is_live (demux);

  ret = gst_adaptive_demux_stream_update_fragment_info (demux, stream);
  GST_DEBUG_OBJECT (stream->pad, "Fragment info update result: %d %s",
      ret, gst_flow_get_name (ret));
  if (ret == GST_FLOW_OK) {

    /* wait for live fragments to be available */
    if (live) {
      gint64 wait_time =
          gst_adaptive_demux_stream_get_fragment_waiting_time (demux, stream);
      if (wait_time > 0) {
        GstClockTime end_time =
            gst_adaptive_demux_get_monotonic_time (demux) + wait_time;

        GST_DEBUG_OBJECT (stream->pad, "Download waiting for %" GST_TIME_FORMAT,
            GST_TIME_ARGS (wait_time));

        GST_MANIFEST_UNLOCK (demux);

        g_mutex_lock (&stream->fragment_download_lock);
        if (G_UNLIKELY (stream->cancelled)) {
          g_mutex_unlock (&stream->fragment_download_lock);
          GST_MANIFEST_LOCK (demux);
          stream->last_ret = GST_FLOW_FLUSHING;
          goto cancelled;
        }
        gst_adaptive_demux_wait_until (demux->realtime_clock,
            &stream->fragment_download_cond, &stream->fragment_download_lock,
            end_time);
        g_mutex_unlock (&stream->fragment_download_lock);

        GST_DEBUG_OBJECT (stream->pad, "Download finished waiting");

        GST_MANIFEST_LOCK (demux);

        g_mutex_lock (&stream->fragment_download_lock);
        if (G_UNLIKELY (stream->cancelled)) {
          stream->last_ret = GST_FLOW_FLUSHING;
          g_mutex_unlock (&stream->fragment_download_lock);
          goto cancelled;
        }
        g_mutex_unlock (&stream->fragment_download_lock);
      }
    }

    stream->last_ret = GST_FLOW_OK;

    next_download = gst_adaptive_demux_get_monotonic_time (demux);
    ret = gst_adaptive_demux_stream_download_fragment (stream);

    if (ret == GST_FLOW_FLUSHING) {
      g_mutex_lock (&stream->fragment_download_lock);
      if (G_UNLIKELY (stream->cancelled)) {
        stream->last_ret = GST_FLOW_FLUSHING;
        g_mutex_unlock (&stream->fragment_download_lock);
        goto cancelled;
      }
      g_mutex_unlock (&stream->fragment_download_lock);
    }

  } else {
    stream->last_ret = ret;
  }

  switch (ret) {
    case GST_FLOW_OK:
      break;                    /* all is good, let's go */
    case GST_FLOW_EOS:
      GST_DEBUG_OBJECT (stream->pad, "EOS, checking to stop download loop");
      /* we push the EOS after releasing the object lock */
      if (gst_adaptive_demux_is_live (demux)) {
        GstAdaptiveDemuxClass *demux_class =
            GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

        /* this might be a fragment download error, refresh the manifest, just in case */
        if (!demux_class->requires_periodical_playlist_update (demux)) {
          ret = gst_adaptive_demux_update_manifest (demux);
          break;
        } else if (gst_adaptive_demux_stream_wait_manifest_update (demux,
                stream)) {
          goto end;
        }
        gst_task_stop (stream->download_task);
      } else {
        gst_task_stop (stream->download_task);
        if (gst_adaptive_demux_combine_flows (demux) == GST_FLOW_EOS) {
          if (gst_adaptive_demux_has_next_period (demux)) {
            gst_adaptive_demux_advance_period (demux);
            ret = GST_FLOW_OK;
          }
        }
      }
      break;

    case GST_FLOW_NOT_LINKED:
    {
      GstFlowReturn ret;
      gst_task_stop (stream->download_task);

      ret = gst_adaptive_demux_combine_flows (demux);
      if (ret == GST_FLOW_NOT_LINKED) {
        GST_ELEMENT_FLOW_ERROR (demux, ret);
      }
    }
      break;

    case GST_FLOW_FLUSHING:{
      GList *iter;

      for (iter = demux->streams; iter; iter = g_list_next (iter)) {
        GstAdaptiveDemuxStream *other;

        other = iter->data;
        gst_task_stop (other->download_task);
      }
    }
      break;

    default:
      if (ret <= GST_FLOW_ERROR) {
        gboolean is_live = gst_adaptive_demux_is_live (demux);
        GST_WARNING_OBJECT (demux, "Error while downloading fragment");
        if (++stream->download_error_count > MAX_DOWNLOAD_ERROR_COUNT) {
          goto download_error;
        }

        g_clear_error (&stream->last_error);

        /* First try to update the playlist for non-live playlists
         * in case the URIs have changed in the meantime. But only
         * try it the first time, after that we're going to wait a
         * a bit to not flood the server */
        if (stream->download_error_count == 1 && !is_live) {
          /* TODO hlsdemux had more options to this function (boolean and err) */

          if (gst_adaptive_demux_update_manifest (demux) == GST_FLOW_OK) {
            /* Retry immediately, the playlist actually has changed */
            GST_DEBUG_OBJECT (demux, "Updated the playlist");
            goto end;
          }
        }

        /* Wait half the fragment duration before retrying */
        next_download += stream->fragment.duration / 2;

        GST_MANIFEST_UNLOCK (demux);

        g_mutex_lock (&stream->fragment_download_lock);
        if (G_UNLIKELY (stream->cancelled)) {
          g_mutex_unlock (&stream->fragment_download_lock);
          GST_MANIFEST_LOCK (demux);
          stream->last_ret = GST_FLOW_FLUSHING;
          goto cancelled;
        }
        gst_adaptive_demux_wait_until (demux->realtime_clock,
            &stream->fragment_download_cond, &stream->fragment_download_lock,
            next_download);
        g_mutex_unlock (&stream->fragment_download_lock);

        GST_DEBUG_OBJECT (demux, "Retrying now");

        GST_MANIFEST_LOCK (demux);

        g_mutex_lock (&stream->fragment_download_lock);
        if (G_UNLIKELY (stream->cancelled)) {
          stream->last_ret = GST_FLOW_FLUSHING;
          g_mutex_unlock (&stream->fragment_download_lock);
          goto cancelled;
        }
        g_mutex_unlock (&stream->fragment_download_lock);

        /* Refetch the playlist now after we waited */
        if (!is_live
            && gst_adaptive_demux_update_manifest (demux) == GST_FLOW_OK) {
          GST_DEBUG_OBJECT (demux, "Updated the playlist");
        }
        goto end;
      }
      break;
  }

end_of_manifest:
  if (G_UNLIKELY (ret == GST_FLOW_EOS)) {
    if (GST_OBJECT_PARENT (stream->pad) != NULL) {
      GST_DEBUG_OBJECT (stream->src, "Pushing EOS on pad");
      gst_adaptive_demux_stream_push_event (stream, gst_event_new_eos ());
    } else {
      GST_ERROR_OBJECT (demux, "Can't push EOS on non-exposed pad");
      goto download_error;
    }
  }

end:
  GST_MANIFEST_UNLOCK (demux);
  GST_LOG_OBJECT (stream->pad, "download loop end");
  return;

cancelled:
  {
    GST_DEBUG_OBJECT (stream->pad, "Stream has been cancelled");
    goto end;
  }
download_error:
  {
    GstMessage *msg;

    if (stream->last_error) {
      gchar *debug = g_strdup_printf ("Error on stream %s:%s",
          GST_DEBUG_PAD_NAME (stream->pad));
      msg =
          gst_message_new_error (GST_OBJECT_CAST (demux), stream->last_error,
          debug);
      GST_ERROR_OBJECT (stream->pad, "Download error: %s",
          stream->last_error->message);
      g_free (debug);
    } else {
      GError *err =
          g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
          _("Couldn't download fragments"));
      msg =
          gst_message_new_error (GST_OBJECT_CAST (demux), err,
          "Fragment downloading has failed consecutive times");
      g_error_free (err);
      GST_ERROR_OBJECT (stream->pad,
          "Download error: Couldn't download fragments, too many failures");
    }

    gst_task_stop (stream->download_task);
    if (stream->src) {
      GstElement *src = stream->src;

      stream->src = NULL;
      GST_MANIFEST_UNLOCK (demux);
      gst_element_set_locked_state (src, TRUE);
      gst_element_set_state (src, GST_STATE_NULL);
      gst_bin_remove (GST_BIN_CAST (demux), src);
      GST_MANIFEST_LOCK (demux);
    }

    gst_element_post_message (GST_ELEMENT_CAST (demux), msg);

    goto end;
  }
}

static void
gst_adaptive_demux_updates_loop (GstAdaptiveDemux * demux)
{
  GstClockTime next_update;
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  /* Loop for updating of the playlist. This periodically checks if
   * the playlist is updated and does so, then signals the streaming
   * thread in case it can continue downloading now. */

  /* block until the next scheduled update or the signal to quit this thread */
  GST_DEBUG_OBJECT (demux, "Started updates task");

  GST_MANIFEST_LOCK (demux);

  next_update =
      gst_adaptive_demux_get_monotonic_time (demux) +
      klass->get_manifest_update_interval (demux) * GST_USECOND;

  /* Updating playlist only needed for live playlists */
  while (gst_adaptive_demux_is_live (demux)) {
    GstFlowReturn ret = GST_FLOW_OK;

    /* Wait here until we should do the next update or we're cancelled */
    GST_DEBUG_OBJECT (demux, "Wait for next playlist update");

    GST_MANIFEST_UNLOCK (demux);

    g_mutex_lock (&demux->priv->updates_timed_lock);
    if (demux->priv->stop_updates_task) {
      g_mutex_unlock (&demux->priv->updates_timed_lock);
      goto quit;
    }
    gst_adaptive_demux_wait_until (demux->realtime_clock,
        &demux->priv->updates_timed_cond,
        &demux->priv->updates_timed_lock, next_update);
    g_mutex_unlock (&demux->priv->updates_timed_lock);

    GST_MANIFEST_LOCK (demux);

    g_mutex_lock (&demux->priv->updates_timed_lock);
    if (demux->priv->stop_updates_task) {
      g_mutex_unlock (&demux->priv->updates_timed_lock);
      GST_MANIFEST_UNLOCK (demux);
      goto quit;
    }
    g_mutex_unlock (&demux->priv->updates_timed_lock);

    GST_DEBUG_OBJECT (demux, "Updating playlist");

    ret = gst_adaptive_demux_update_manifest (demux);

    if (ret == GST_FLOW_EOS) {
    } else if (ret != GST_FLOW_OK) {
      /* update_failed_count is used only here, no need to protect it */
      demux->priv->update_failed_count++;
      if (demux->priv->update_failed_count <= DEFAULT_FAILED_COUNT) {
        GST_WARNING_OBJECT (demux, "Could not update the playlist");
        next_update = gst_adaptive_demux_get_monotonic_time (demux)
            + klass->get_manifest_update_interval (demux) * GST_USECOND;
      } else {
        GST_ELEMENT_ERROR (demux, STREAM, FAILED,
            (_("Internal data stream error.")), ("Could not update playlist"));
        GST_DEBUG_OBJECT (demux, "Stopped updates task because of error");
        gst_task_stop (demux->priv->updates_task);
        GST_MANIFEST_UNLOCK (demux);
        goto end;
      }
    } else {
      GST_DEBUG_OBJECT (demux, "Updated playlist successfully");
      demux->priv->update_failed_count = 0;
      next_update =
          gst_adaptive_demux_get_monotonic_time (demux) +
          klass->get_manifest_update_interval (demux) * GST_USECOND;

      /* Wake up download tasks */
      g_mutex_lock (&demux->priv->manifest_update_lock);
      g_cond_broadcast (&demux->priv->manifest_cond);
      g_mutex_unlock (&demux->priv->manifest_update_lock);
    }
  }

  GST_MANIFEST_UNLOCK (demux);

quit:
  {
    GST_DEBUG_OBJECT (demux, "Stop updates task request detected.");
  }

end:
  {
    return;
  }
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_stream_push_event (GstAdaptiveDemuxStream * stream,
    GstEvent * event)
{
  gboolean ret;
  GstPad *pad;
  GstAdaptiveDemux *demux = stream->demux;

  if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
    stream->eos = TRUE;
  }

  pad = gst_object_ref (GST_ADAPTIVE_DEMUX_STREAM_PAD (stream));

  /* Can't push events holding the manifest lock */
  GST_MANIFEST_UNLOCK (demux);

  GST_DEBUG_OBJECT (GST_ADAPTIVE_DEMUX_STREAM_PAD (stream),
      "Pushing event %" GST_PTR_FORMAT, event);

  ret = gst_pad_push_event (pad, event);

  gst_object_unref (pad);

  GST_MANIFEST_LOCK (demux);

  return ret;
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_is_live (GstAdaptiveDemux * demux)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  if (klass->is_live)
    return klass->is_live (demux);
  return FALSE;
}

/* must be called with manifest_lock taken */
static GstFlowReturn
gst_adaptive_demux_stream_seek (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, gboolean forward, GstSeekFlags flags,
    GstClockTime ts, GstClockTime * final_ts)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  if (klass->stream_seek)
    return klass->stream_seek (stream, forward, flags, ts, final_ts);
  return GST_FLOW_ERROR;
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_stream_has_next_fragment (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  gboolean ret = TRUE;

  if (klass->stream_has_next_fragment)
    ret = klass->stream_has_next_fragment (stream);

  return ret;
}

/* must be called with manifest_lock taken */
GstFlowReturn
gst_adaptive_demux_stream_advance_fragment (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, GstClockTime duration)
{
  GstFlowReturn ret;

  if (stream->last_ret == GST_FLOW_OK) {
    stream->last_ret =
        gst_adaptive_demux_stream_advance_fragment_unlocked (demux, stream,
        duration);
  }
  ret = stream->last_ret;

  return ret;
}

/* must be called with manifest_lock taken */
GstFlowReturn
gst_adaptive_demux_stream_advance_fragment_unlocked (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, GstClockTime duration)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  GstFlowReturn ret;

  g_return_val_if_fail (klass->stream_advance_fragment != NULL, GST_FLOW_ERROR);

  stream->download_error_count = 0;
  g_clear_error (&stream->last_error);

  /* FIXME - url has no indication of byte ranges for subsegments */
  gst_element_post_message (GST_ELEMENT_CAST (demux),
      gst_message_new_element (GST_OBJECT_CAST (demux),
          gst_structure_new (GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME,
              "manifest-uri", G_TYPE_STRING,
              demux->manifest_uri, "uri", G_TYPE_STRING,
              stream->fragment.uri, "fragment-start-time",
              GST_TYPE_CLOCK_TIME, stream->download_start_time,
              "fragment-stop-time", GST_TYPE_CLOCK_TIME,
              gst_util_get_timestamp (), "fragment-size", G_TYPE_UINT64,
              stream->download_total_bytes, "fragment-download-time",
              GST_TYPE_CLOCK_TIME, stream->last_download_time, NULL)));

  /* Don't update to the end of the segment if in reverse playback */
  GST_ADAPTIVE_DEMUX_SEGMENT_LOCK (demux);
  if (GST_CLOCK_TIME_IS_VALID (duration) && demux->segment.rate > 0) {
    GstClockTime offset =
        gst_adaptive_demux_stream_get_presentation_offset (demux, stream);
    GstClockTime period_start =
        gst_adaptive_demux_get_period_start_time (demux);

    stream->segment.position += duration;

    /* Convert from position inside the stream's segment to the demuxer's
     * segment, they are not necessarily the same */
    if (stream->segment.position - offset + period_start >
        demux->segment.position)
      demux->segment.position =
          stream->segment.position - offset + period_start;
  }
  GST_ADAPTIVE_DEMUX_SEGMENT_UNLOCK (demux);

  if (gst_adaptive_demux_is_live (demux)
      || gst_adaptive_demux_stream_has_next_fragment (demux, stream)) {
    ret = klass->stream_advance_fragment (stream);
  } else {
    ret = GST_FLOW_EOS;
  }

  stream->download_start_time =
      GST_TIME_AS_USECONDS (gst_adaptive_demux_get_monotonic_time (demux));

  if (ret == GST_FLOW_OK) {
    if (gst_adaptive_demux_stream_select_bitrate (demux, stream,
            gst_adaptive_demux_stream_update_current_bitrate (demux, stream))) {
      stream->need_header = TRUE;
      ret = (GstFlowReturn) GST_ADAPTIVE_DEMUX_FLOW_SWITCH;
    }

    /* the subclass might want to switch pads */
    if (G_UNLIKELY (demux->next_streams)) {
      GList *iter;
      gboolean can_expose = TRUE;

      gst_task_stop (stream->download_task);

      ret = GST_FLOW_EOS;

      for (iter = demux->streams; iter; iter = g_list_next (iter)) {
        /* Only expose if all streams are now cancelled or finished downloading */
        GstAdaptiveDemuxStream *other = iter->data;
        if (other != stream) {
          g_mutex_lock (&other->fragment_download_lock);
          can_expose &= (other->cancelled == TRUE
              || other->download_finished == TRUE);
          g_mutex_unlock (&other->fragment_download_lock);
        }
      }

      if (can_expose) {
        GST_DEBUG_OBJECT (demux, "Subclass wants new pads "
            "to do bitrate switching");
        gst_adaptive_demux_prepare_streams (demux, FALSE);
        gst_adaptive_demux_start_tasks (demux, TRUE);
      } else {
        GST_LOG_OBJECT (demux, "Not switching yet - ongoing downloads");
      }
    }
  }

  return ret;
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_stream_select_bitrate (GstAdaptiveDemux *
    demux, GstAdaptiveDemuxStream * stream, guint64 bitrate)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  if (klass->stream_select_bitrate)
    return klass->stream_select_bitrate (stream, bitrate);
  return FALSE;
}

/* must be called with manifest_lock taken */
static GstFlowReturn
gst_adaptive_demux_stream_update_fragment_info (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  g_return_val_if_fail (klass->stream_update_fragment_info != NULL,
      GST_FLOW_ERROR);

  /* Make sure the sub-class will update bitrate, or else
   * we will later */
  stream->fragment.bitrate = 0;
  stream->fragment.finished = FALSE;

  return klass->stream_update_fragment_info (stream);
}

/* must be called with manifest_lock taken */
static gint64
gst_adaptive_demux_stream_get_fragment_waiting_time (GstAdaptiveDemux *
    demux, GstAdaptiveDemuxStream * stream)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  if (klass->stream_get_fragment_waiting_time)
    return klass->stream_get_fragment_waiting_time (stream);
  return 0;
}

/* must be called with manifest_lock taken */
static GstFlowReturn
gst_adaptive_demux_update_manifest_default (GstAdaptiveDemux * demux)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  GstFragment *download;
  GstBuffer *buffer;
  GstFlowReturn ret;

  download = gst_uri_downloader_fetch_uri (demux->downloader,
      demux->manifest_uri, NULL, TRUE, TRUE, TRUE, NULL);
  if (download) {
    g_free (demux->manifest_uri);
    g_free (demux->manifest_base_uri);
    if (download->redirect_permanent && download->redirect_uri) {
      demux->manifest_uri = g_strdup (download->redirect_uri);
      demux->manifest_base_uri = NULL;
    } else {
      demux->manifest_uri = g_strdup (download->uri);
      demux->manifest_base_uri = g_strdup (download->redirect_uri);
    }

    buffer = gst_fragment_get_buffer (download);
    g_object_unref (download);
    ret = klass->update_manifest_data (demux, buffer);
    gst_buffer_unref (buffer);
    /* FIXME: Should the manifest uri vars be reverted to original
     * values if updating fails? */
  } else {
    ret = GST_FLOW_NOT_LINKED;
  }

  return ret;
}

/* must be called with manifest_lock taken */
static GstFlowReturn
gst_adaptive_demux_update_manifest (GstAdaptiveDemux * demux)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  GstFlowReturn ret;

  ret = klass->update_manifest (demux);

  if (ret == GST_FLOW_OK) {
    GstClockTime duration;
    /* Send an updated duration message */
    duration = klass->get_duration (demux);
    if (duration != GST_CLOCK_TIME_NONE) {
      GST_DEBUG_OBJECT (demux,
          "Sending duration message : %" GST_TIME_FORMAT,
          GST_TIME_ARGS (duration));
      gst_element_post_message (GST_ELEMENT (demux),
          gst_message_new_duration_changed (GST_OBJECT (demux)));
    } else {
      GST_DEBUG_OBJECT (demux,
          "Duration unknown, can not send the duration message");
    }
  }

  return ret;
}

void
gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f)
{
  g_free (f->uri);
  f->uri = NULL;
  f->range_start = 0;
  f->range_end = -1;

  g_free (f->header_uri);
  f->header_uri = NULL;
  f->header_range_start = 0;
  f->header_range_end = -1;

  g_free (f->index_uri);
  f->index_uri = NULL;
  f->index_range_start = 0;
  f->index_range_end = -1;

  f->finished = FALSE;
}

/* must be called with manifest_lock taken */
static gboolean
gst_adaptive_demux_has_next_period (GstAdaptiveDemux * demux)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
  gboolean ret = FALSE;

  if (klass->has_next_period)
    ret = klass->has_next_period (demux);
  GST_DEBUG_OBJECT (demux, "Has next period: %d", ret);
  return ret;
}

/* must be called with manifest_lock taken */
static void
gst_adaptive_demux_advance_period (GstAdaptiveDemux * demux)
{
  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);

  g_return_if_fail (klass->advance_period != NULL);

  GST_DEBUG_OBJECT (demux, "Advancing to next period");
  klass->advance_period (demux);
  gst_adaptive_demux_prepare_streams (demux, FALSE);
  gst_adaptive_demux_start_tasks (demux, TRUE);
}

/**
 * gst_adaptive_demux_get_monotonic_time:
 * Returns: a monotonically increasing time, using the system realtime clock
 */
GstClockTime
gst_adaptive_demux_get_monotonic_time (GstAdaptiveDemux * demux)
{
  g_return_val_if_fail (demux != NULL, GST_CLOCK_TIME_NONE);
  return gst_clock_get_time (demux->realtime_clock);
}

/**
 * gst_adaptive_demux_get_client_now_utc:
 * @demux: #GstAdaptiveDemux
 * Returns: the client's estimate of UTC
 *
 * Used to find the client's estimate of UTC, using the system realtime clock.
 */
GDateTime *
gst_adaptive_demux_get_client_now_utc (GstAdaptiveDemux * demux)
{
  GstClockTime rtc_now;
  gint64 utc_now;
  GTimeVal gtv;

  rtc_now = gst_clock_get_time (demux->realtime_clock);
  utc_now = demux->clock_offset + GST_TIME_AS_USECONDS (rtc_now);
  gtv.tv_sec = utc_now / G_TIME_SPAN_SECOND;
  gtv.tv_usec = utc_now % G_TIME_SPAN_SECOND;
  return g_date_time_new_from_timeval_utc (&gtv);
}

static GstAdaptiveDemuxTimer *
gst_adaptive_demux_timer_new (GCond * cond, GMutex * mutex)
{
  GstAdaptiveDemuxTimer *timer;

  timer = g_slice_new (GstAdaptiveDemuxTimer);
  timer->fired = FALSE;
  timer->cond = cond;
  timer->mutex = mutex;
  timer->ref_count = 1;
  return timer;
}

static GstAdaptiveDemuxTimer *
gst_adaptive_demux_timer_ref (GstAdaptiveDemuxTimer * timer)
{
  g_return_val_if_fail (timer != NULL, NULL);
  g_atomic_int_inc (&timer->ref_count);
  return timer;
}

static void
gst_adaptive_demux_timer_unref (GstAdaptiveDemuxTimer * timer)
{
  g_return_if_fail (timer != NULL);
  if (g_atomic_int_dec_and_test (&timer->ref_count)) {
    g_slice_free (GstAdaptiveDemuxTimer, timer);
  }
}

/* gst_adaptive_demux_wait_until:
 * A replacement for g_cond_wait_until that uses the clock rather
 * than system time to control the duration of the sleep. Typically
 * clock is actually a #GstSystemClock, in which case this function
 * behaves exactly like g_cond_wait_until. Inside unit tests,
 * the clock is typically a #GstTestClock, which allows tests to run
 * in non-realtime.
 * This function must be called with mutex held.
 */
static gboolean
gst_adaptive_demux_wait_until (GstClock * clock, GCond * cond, GMutex * mutex,
    GstClockTime end_time)
{
  GstAdaptiveDemuxTimer *timer;
  gboolean fired;
  GstClockReturn res;

  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (end_time))) {
    /* for an invalid time, gst_clock_id_wait_async will try to call
     * gst_adaptive_demux_clock_callback from the current thread.
     * It still holds the mutex while doing that, so it will deadlock.
     * g_cond_wait_until would return immediately with false, so we'll do the same.
     */
    return FALSE;
  }
  timer = gst_adaptive_demux_timer_new (cond, mutex);
  timer->clock_id = gst_clock_new_single_shot_id (clock, end_time);
  res =
      gst_clock_id_wait_async (timer->clock_id,
      gst_adaptive_demux_clock_callback, gst_adaptive_demux_timer_ref (timer),
      (GDestroyNotify) gst_adaptive_demux_timer_unref);
  /* clock does not support asynchronously wait. Assert and return */
  if (res == GST_CLOCK_UNSUPPORTED) {
    gst_clock_id_unref (timer->clock_id);
    gst_adaptive_demux_timer_unref (timer);
    g_return_val_if_reached (TRUE);
  }
  g_assert (!timer->fired);
  /* the gst_adaptive_demux_clock_callback() will signal the
   * cond when the clock's single shot timer fires, or the cond will be
   * signalled by another thread that wants to cause this wait to finish
   * early (e.g. to terminate the waiting thread).
   * There is no need for a while loop here, because that logic is
   * implemented by the function calling gst_adaptive_demux_wait_until() */
  g_cond_wait (cond, mutex);
  fired = timer->fired;
  if (!fired)
    gst_clock_id_unschedule (timer->clock_id);
  gst_clock_id_unref (timer->clock_id);
  gst_adaptive_demux_timer_unref (timer);
  return !fired;
}

static gboolean
gst_adaptive_demux_clock_callback (GstClock * clock,
    GstClockTime time, GstClockID id, gpointer user_data)
{
  GstAdaptiveDemuxTimer *timer = (GstAdaptiveDemuxTimer *) user_data;
  g_return_val_if_fail (timer != NULL, FALSE);
  g_mutex_lock (timer->mutex);
  timer->fired = TRUE;
  g_cond_signal (timer->cond);
  g_mutex_unlock (timer->mutex);
  return TRUE;
}
