/*
 * DASH demux plugin for GStreamer
 *
 * gstdashdemux.c
 *
 * Copyright (C) 2012 Orange
 *
 * Authors:
 *   David Corvoysier <david.corvoysier@orange.com>
 *   Hamid Zakari <hamid.zakari@gmail.com>
 *
 * Copyright (C) 2013 Smart TV Alliance
 *  Author: Thiago Sousa Santos <thiago.sousa.santos@collabora.com>, Collabora Ltd.
 *
 * 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.1 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 (COPYING); if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
/**
 * SECTION:element-dashdemux
 * @title: dashdemux
 *
 * DASH demuxer element.
 * ## Example launch line
 * |[
 * gst-launch-1.0 playbin uri="http://www-itec.uni-klu.ac.at/ftp/datasets/mmsys12/RedBullPlayStreets/redbull_4s/RedBullPlayStreets_4s_isoffmain_DIS_23009_1_v_2_1c2_2011_08_30.mpd"
 * ]|
 */

/* Implementation notes:
 *
 * The following section describes how dashdemux works internally.
 *
 * Introduction:
 *
 * dashdemux is a "fake" demux, as unlike traditional demux elements, it
 * doesn't split data streams contained in an envelope to expose them to
 * downstream decoding elements.
 *
 * Instead, it parses an XML file called a manifest to identify a set of
 * individual stream fragments it needs to fetch and expose to the actual
 * demux elements that will handle them (this behavior is sometimes
 * referred as the "demux after a demux" scenario).
 *
 * For a given section of content, several representations corresponding
 * to different bitrates may be available: dashdemux will select the most
 * appropriate representation based on local conditions (typically the
 * available bandwidth and the amount of buffering available, capped by
 * a maximum allowed bitrate).
 *
 * The representation selection algorithm can be configured using
 * specific properties: max bitrate, min/max buffering, bandwidth ratio.
 *
 *
 * General Design:
 *
 * dashdemux has a single sink pad that accepts the data corresponding
 * to the manifest, typically fetched from an HTTP or file source.
 *
 * dashdemux exposes the streams it recreates based on the fragments it
 * fetches through dedicated src pads corresponding to the caps of the
 * fragments container (ISOBMFF/MP4 or MPEG2TS).
 *
 * During playback, new representations will typically be exposed as a
 * new set of pads (see 'Switching between representations' below).
 *
 * Fragments downloading is performed using a dedicated task that fills
 * an internal queue. Another task is in charge of popping fragments
 * from the queue and pushing them downstream.
 *
 * Switching between representations:
 *
 * Decodebin supports scenarios allowing to seamlessly switch from one
 * stream to another inside the same "decoding chain".
 *
 * To achieve that, it combines the elements it autoplugged in chains
 *  and groups, allowing only one decoding group to be active at a given
 * time for a given chain.
 *
 * A chain can signal decodebin that it is complete by sending a
 * no-more-pads event, but even after that new pads can be added to
 * create new subgroups, providing that a new no-more-pads event is sent.
 *
 * We take advantage of that to dynamically create a new decoding group
 * in order to select a different representation during playback.
 *
 * Typically, assuming that each fragment contains both audio and video,
 * the following tree would be created:
 *
 * chain "DASH Demux"
 * |_ group "Representation set 1"
 * |   |_ chain "Qt Demux 0"
 * |       |_ group "Stream 0"
 * |           |_ chain "H264"
 * |           |_ chain "AAC"
 * |_ group "Representation set 2"
 *     |_ chain "Qt Demux 1"
 *         |_ group "Stream 1"
 *             |_ chain "H264"
 *             |_ chain "AAC"
 *
 * Or, if audio and video are contained in separate fragments:
 *
 * chain "DASH Demux"
 * |_ group "Representation set 1"
 * |   |_ chain "Qt Demux 0"
 * |   |   |_ group "Stream 0"
 * |   |       |_ chain "H264"
 * |   |_ chain "Qt Demux 1"
 * |       |_ group "Stream 1"
 * |           |_ chain "AAC"
 * |_ group "Representation set 2"
 *     |_ chain "Qt Demux 3"
 *     |   |_ group "Stream 2"
 *     |       |_ chain "H264"
 *     |_ chain "Qt Demux 4"
 *         |_ group "Stream 3"
 *             |_ chain "AAC"
 *
 * In both cases, when switching from Set 1 to Set 2 an EOS is sent on
 * each end pad corresponding to Rep 0, triggering the "drain" state to
 * propagate upstream.
 * Once both EOS have been processed, the "Set 1" group is completely
 * drained, and decodebin2 will switch to the "Set 2" group.
 *
 * Note: nothing can be pushed to the new decoding group before the
 * old one has been drained, which means that in order to be able to
 * adapt quickly to bandwidth changes, we will not be able to rely
 * on downstream buffering, and will instead manage an internal queue.
 *
 *
 * Keyframe trick-mode implementation:
 *
 * When requested (with GST_SEEK_FLAG_TRICKMODE_KEY_UNIT) and if the format
 * is supported (ISOBMFF profiles), dashdemux can download only keyframes
 * in order to provide fast forward/reverse playback without exceeding the
 * available bandwith/cpu/memory usage.
 *
 * This is done in two parts:
 * 1) Parsing ISOBMFF atoms to detect the location of keyframes and only
 *    download/push those.
 * 2) Deciding what the ideal next keyframe to download is in order to
 *    provide as many keyframes as possible without rebuffering.
 *
 * * Keyframe-only downloads:
 *
 * For each beginning of fragment, the fragment header will be parsed in
 * gst_dash_demux_parse_isobmff() and then the information (offset, pts...)
 * of each keyframe will be stored in moof_sync_samples.
 *
 * gst_dash_demux_stream_update_fragment_info() will specify the range
 * start and end of the current keyframe, which will cause GstAdaptiveDemux
 * to do a new upstream range request.
 *
 * When advancing, if there are still some keyframes in the current
 * fragment, gst_dash_demux_stream_advance_fragment() will call
 * gst_dash_demux_stream_advance_sync_sample() which decides what the next
 * keyframe to get will be (it can be in reverse order for example, or
 * might not be the *next* keyframe but one further as explained below).
 *
 * If no more keyframes are available in the current fragment, dash will
 * advance to the next fragment (just like in the normal case) or to a
 * fragment much further away (as explained below).
 *
 *
 * * Deciding the optimal "next" keyframe/fragment to download:
 *
 * The main reason for doing keyframe-only downloads is for trick-modes
 * (i.e. being able to do fast reverse/forward playback with limited
 * bandwith/cpu/memory).
 *
 * Downloading all keyframes might not be the optimal solution, especially
 * at high playback rates, since the time taken to download the keyframe
 * might exceed the available running time between two displayed frames
 * (i.e. all frames would end up arriving late). This would cause severe
 * rebuffering.
 *
 * Note: The values specified below can be in either the segment running
 * time or in absolute values. Where position values need to be converted
 * to segment running time the "running_time(val)" notation is used, and
 * where running time need ot be converted to segment poisition the
 * "position(val)" notation is used.
 *
 * The goal instead is to be able to download/display as many frames as
 * possible for a given playback rate. For that the implementation will
 * take into account:
 *  * The requested playback rate and segment
 *  * The average time to request and download a keyframe (in running time)
 *  * The current position of dashdemux in the stream
 *  * The current downstream (i.e. sink) position (in running time)
 *
 * To reach this goal we consider that there is some amount of buffering
 * (in time) between dashdemux and the display sink. While we do not know
 * the exact amount of buffering available, a safe and reasonable assertion
 * is that there is at least a second (in running time).
 *
 * The average time to request and fully download a keyframe (with or
 * without fragment header) is obtained by averaging the
 * GstAdaptiveDemuxStream->last_download_time and is stored in
 * GstDashDemuxStream->average_download_time. Those values include the
 * network latency and full download time, which are more interesting and
 * correct than just bitrates (with small download sizes, the impact of the
 * network latency is much higher).
 *
 * The current position is calculated based on the fragment timestamp and
 * the current keyframe index within that fragment. It is stored in
 * GstDashDemuxStream->actual_position.
 *
 * The downstream position of the pipeline is obtained via QoS events and
 * is stored in GstAdaptiveDemuxStream->qos_earliest_time (note: it's a
 * running time value).
 *
 * The estimated buffering level between dashdemux and downstream is
 * therefore:
 *   buffering_level = running_time(actual_position) - qos_earliest_time
 *
 * In order to avoid rebuffering, we want to ensure that the next keyframe
 * (including potential fragment header) we request will be download, demuxed
 * and decoded in time so that it is not late. That next keyframe time is
 * called the "target_time" and is calculated whenever we have finished
 * pushing a keyframe downstream.
 *
 * One simple observation at this point is that we *need* to make sure that
 * the target time is chosen such that:
 *   running_time(target_time) > qos_earliest_time + average_download_time
 *
 * i.e. we chose a target time which will be greater than the time at which
 * downstream will be once we request and download the keyframe (otherwise
 * we're guaranteed to be late).
 *
 * This would provide the highest number of displayed frames per
 * second, but it is just a *minimal* value and is not enough as-is,
 * since it doesn't take into account the following items which could
 * cause frames to arrive late (and therefore rebuffering):
 * * Network jitter (i.e. by how much the download time can fluctuate)
 * * Network stalling
 * * Different keyframe sizes (and therefore download time)
 * * Decoding speed
 *
 * Instead, we adjust the target time calculation based on the
 * buffering_level.
 *
 * The smaller the buffering level is (i.e. the closer we are between
 * current and downstream), the more aggresively we skip forward (and
 * guarantee the keyframe will be downloaded, decoded and displayed in
 * time). And the higher the buffering level, the least aggresivelly
 * we need to skip forward (and therefore display more frames per
 * second).
 *
 * Right now the threshold for agressive switching is set to 3
 * average_download_time. Below that buffering level we set the target time
 * to at least 3 average_download_time distance beyond the
 * qos_earliest_time.
 *
 * If we are above that buffering level we set the target time to:
 *      position(running_time(position) + average_download_time)
 *
 * The logic is therefore:
 * WHILE(!EOS)
 *   Calculate target_time
 *   Advance to keyframe/fragment for that target_time
 *   Adaptivedemux downloads that keyframe/fragment
 *
 */

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

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <gio/gio.h>
#include <gst/base/gsttypefindhelper.h>
#include <gst/tag/tag.h>
#include <gst/net/gstnet.h>
#include "gst/gst-i18n-plugin.h"
#include "gstdashdemux.h"
#include "gstdash_debug.h"

static GstStaticPadTemplate gst_dash_demux_videosrc_template =
GST_STATIC_PAD_TEMPLATE ("video_%02u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate gst_dash_demux_audiosrc_template =
GST_STATIC_PAD_TEMPLATE ("audio_%02u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate gst_dash_demux_subtitlesrc_template =
GST_STATIC_PAD_TEMPLATE ("subtitle_%02u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/dash+xml"));

GST_DEBUG_CATEGORY (gst_dash_demux_debug);
#define GST_CAT_DEFAULT gst_dash_demux_debug

enum
{
  PROP_0,

  PROP_MAX_BUFFERING_TIME,
  PROP_BANDWIDTH_USAGE,
  PROP_MAX_BITRATE,
  PROP_MAX_VIDEO_WIDTH,
  PROP_MAX_VIDEO_HEIGHT,
  PROP_MAX_VIDEO_FRAMERATE,
  PROP_PRESENTATION_DELAY,
  PROP_LAST
};

/* Default values for properties */
#define DEFAULT_MAX_BUFFERING_TIME       30     /* in seconds */
#define DEFAULT_BANDWIDTH_USAGE         0.8f    /* 0 to 1     */
#define DEFAULT_MAX_BITRATE               0     /* in bit/s  */
#define DEFAULT_MAX_VIDEO_WIDTH           0
#define DEFAULT_MAX_VIDEO_HEIGHT          0
#define DEFAULT_MAX_VIDEO_FRAMERATE_N     0
#define DEFAULT_MAX_VIDEO_FRAMERATE_D     1
#define DEFAULT_PRESENTATION_DELAY     "10s"    /* 10s */

/* Clock drift compensation for live streams */
#define SLOW_CLOCK_UPDATE_INTERVAL  (1000000 * 30 * 60) /* 30 minutes */
#define FAST_CLOCK_UPDATE_INTERVAL  (1000000 * 30)      /* 30 seconds */
#define SUPPORTED_CLOCK_FORMATS (GST_MPD_UTCTIMING_TYPE_NTP | GST_MPD_UTCTIMING_TYPE_HTTP_HEAD | GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE | GST_MPD_UTCTIMING_TYPE_HTTP_ISO | GST_MPD_UTCTIMING_TYPE_HTTP_NTP)
#define NTP_TO_UNIX_EPOCH G_GUINT64_CONSTANT(2208988800)        /* difference (in seconds) between NTP epoch and Unix epoch */

struct _GstDashDemuxClockDrift
{
  GMutex clock_lock;            /* used to protect access to struct */
  guint selected_url;
  gint64 next_update;
  /* @clock_compensation: amount (in usecs) to add to client's idea of
     now to map it to the server's idea of now */
  GTimeSpan clock_compensation;
  GstClock *ntp_clock;
};

typedef struct
{
  guint64 start_offset, end_offset;
  /* TODO: Timestamp and duration */
} GstDashStreamSyncSample;

/* GObject */
static void gst_dash_demux_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_dash_demux_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_dash_demux_dispose (GObject * obj);

/* GstAdaptiveDemux */
static GstClockTime gst_dash_demux_get_duration (GstAdaptiveDemux * ademux);
static gboolean gst_dash_demux_is_live (GstAdaptiveDemux * ademux);
static void gst_dash_demux_reset (GstAdaptiveDemux * ademux);
static gboolean gst_dash_demux_process_manifest (GstAdaptiveDemux * ademux,
    GstBuffer * buf);
static gboolean gst_dash_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek);
static GstFlowReturn
gst_dash_demux_stream_update_fragment_info (GstAdaptiveDemuxStream * stream);
static GstFlowReturn gst_dash_demux_stream_seek (GstAdaptiveDemuxStream *
    stream, gboolean forward, GstSeekFlags flags, GstClockTime ts,
    GstClockTime * final_ts);
static gboolean gst_dash_demux_stream_has_next_fragment (GstAdaptiveDemuxStream
    * stream);
static GstFlowReturn
gst_dash_demux_stream_advance_fragment (GstAdaptiveDemuxStream * stream);
static gboolean
gst_dash_demux_stream_advance_subfragment (GstAdaptiveDemuxStream * stream);
static gboolean gst_dash_demux_stream_select_bitrate (GstAdaptiveDemuxStream *
    stream, guint64 bitrate);
static gint64 gst_dash_demux_get_manifest_update_interval (GstAdaptiveDemux *
    demux);
static GstFlowReturn gst_dash_demux_update_manifest_data (GstAdaptiveDemux *
    demux, GstBuffer * buf);
static gint64
gst_dash_demux_stream_get_fragment_waiting_time (GstAdaptiveDemuxStream *
    stream);
static void gst_dash_demux_advance_period (GstAdaptiveDemux * demux);
static gboolean gst_dash_demux_has_next_period (GstAdaptiveDemux * demux);
static GstFlowReturn gst_dash_demux_data_received (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
static gboolean
gst_dash_demux_stream_fragment_start (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream);
static GstFlowReturn
gst_dash_demux_stream_fragment_finished (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream);
static gboolean gst_dash_demux_need_another_chunk (GstAdaptiveDemuxStream *
    stream);

/* GstDashDemux */
static gboolean gst_dash_demux_setup_all_streams (GstDashDemux * demux);
static void gst_dash_demux_stream_free (GstAdaptiveDemuxStream * stream);

static GstCaps *gst_dash_demux_get_input_caps (GstDashDemux * demux,
    GstActiveStream * stream);
static GstPad *gst_dash_demux_create_pad (GstDashDemux * demux,
    GstActiveStream * stream);
static GstDashDemuxClockDrift *gst_dash_demux_clock_drift_new (GstDashDemux *
    demux);
static void gst_dash_demux_clock_drift_free (GstDashDemuxClockDrift *);
static gboolean gst_dash_demux_poll_clock_drift (GstDashDemux * demux);
static GTimeSpan gst_dash_demux_get_clock_compensation (GstDashDemux * demux);
static GDateTime *gst_dash_demux_get_server_now_utc (GstDashDemux * demux);

#define SIDX(s) (&(s)->sidx_parser.sidx)

static inline GstSidxBoxEntry *
SIDX_ENTRY (GstDashDemuxStream * s, gint i)
{
  g_assert (i < SIDX (s)->entries_count);
  return &(SIDX (s)->entries[(i)]);
}

#define SIDX_CURRENT_ENTRY(s) SIDX_ENTRY(s, SIDX(s)->entry_index)

static void gst_dash_demux_send_content_protection_event (gpointer cp_data,
    gpointer stream);

#define gst_dash_demux_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstDashDemux, gst_dash_demux, GST_TYPE_ADAPTIVE_DEMUX,
    GST_DEBUG_CATEGORY_INIT (gst_dash_demux_debug, "dashdemux", 0,
        "dashdemux element")
    );

static void
gst_dash_demux_dispose (GObject * obj)
{
  GstDashDemux *demux = GST_DASH_DEMUX (obj);

  gst_dash_demux_reset (GST_ADAPTIVE_DEMUX_CAST (demux));

  if (demux->client) {
    gst_mpd_client_free (demux->client);
    demux->client = NULL;
  }

  g_mutex_clear (&demux->client_lock);

  gst_dash_demux_clock_drift_free (demux->clock_drift);
  demux->clock_drift = NULL;
  g_free (demux->default_presentation_delay);
  G_OBJECT_CLASS (parent_class)->dispose (obj);
}

static gboolean
gst_dash_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
    gint64 * stop)
{
  GstDashDemux *self = GST_DASH_DEMUX (demux);
  GDateTime *now;
  GDateTime *mstart;
  GTimeSpan stream_now;
  GstClockTime seg_duration;

  if (self->client->mpd_node->availabilityStartTime == NULL)
    return FALSE;

  seg_duration = gst_mpd_client_get_maximum_segment_duration (self->client);
  now = gst_dash_demux_get_server_now_utc (self);
  mstart =
      gst_date_time_to_g_date_time (self->client->
      mpd_node->availabilityStartTime);
  stream_now = g_date_time_difference (now, mstart);
  g_date_time_unref (now);
  g_date_time_unref (mstart);

  if (stream_now <= 0)
    return FALSE;

  *stop = stream_now * GST_USECOND;
  if (self->client->mpd_node->timeShiftBufferDepth == GST_MPD_DURATION_NONE) {
    *start = 0;
  } else {
    *start =
        *stop - (self->client->mpd_node->timeShiftBufferDepth * GST_MSECOND);
    if (*start < 0)
      *start = 0;
  }

  /* As defined in 5.3.9.5.3 of the DASH specification, a segment does
     not become available until the sum of:
     * the value of the MPD@availabilityStartTime,
     * the PeriodStart time of the containing Period
     * the MPD start time of the Media Segment, and
     * the MPD duration of the Media Segment.
     Therefore we need to subtract the media segment duration from the stop
     time.
   */
  *stop -= seg_duration;
  return TRUE;
}

static GstClockTime
gst_dash_demux_get_presentation_offset (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);

  return gst_mpd_parser_get_stream_presentation_offset (dashdemux->client,
      dashstream->index);
}

static GstClockTime
gst_dash_demux_get_period_start_time (GstAdaptiveDemux * demux)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);

  return gst_mpd_parser_get_period_start_time (dashdemux->client);
}

static void
gst_dash_demux_class_init (GstDashDemuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstAdaptiveDemuxClass *gstadaptivedemux_class;

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

  gobject_class->set_property = gst_dash_demux_set_property;
  gobject_class->get_property = gst_dash_demux_get_property;
  gobject_class->dispose = gst_dash_demux_dispose;

#ifndef GST_REMOVE_DEPRECATED
  g_object_class_install_property (gobject_class, PROP_MAX_BUFFERING_TIME,
      g_param_spec_uint ("max-buffering-time", "Maximum buffering time",
          "Maximum number of seconds of buffer accumulated during playback"
          "(deprecated)",
          2, G_MAXUINT, DEFAULT_MAX_BUFFERING_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED));

  g_object_class_install_property (gobject_class, PROP_BANDWIDTH_USAGE,
      g_param_spec_float ("bandwidth-usage",
          "Bandwidth usage [0..1]",
          "Percentage of the available bandwidth to use when "
          "selecting representations (deprecated)",
          0, 1, DEFAULT_BANDWIDTH_USAGE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED));
#endif

  g_object_class_install_property (gobject_class, PROP_MAX_BITRATE,
      g_param_spec_uint ("max-bitrate", "Max bitrate",
          "Max of bitrate supported by target video decoder (0 = no maximum)",
          0, G_MAXUINT, DEFAULT_MAX_BITRATE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_WIDTH,
      g_param_spec_uint ("max-video-width", "Max video width",
          "Max video width to select (0 = no maximum)",
          0, G_MAXUINT, DEFAULT_MAX_VIDEO_WIDTH,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_HEIGHT,
      g_param_spec_uint ("max-video-height", "Max video height",
          "Max video height to select (0 = no maximum)",
          0, G_MAXUINT, DEFAULT_MAX_VIDEO_HEIGHT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_FRAMERATE,
      gst_param_spec_fraction ("max-video-framerate", "Max video framerate",
          "Max video framerate to select (0/1 = no maximum)",
          0, 1, G_MAXINT, 1, DEFAULT_MAX_VIDEO_FRAMERATE_N,
          DEFAULT_MAX_VIDEO_FRAMERATE_D,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PRESENTATION_DELAY,
      g_param_spec_string ("presentation-delay", "Presentation delay",
          "Default presentation delay (in seconds, milliseconds or fragments) (e.g. 12s, 2500ms, 3f)",
          DEFAULT_PRESENTATION_DELAY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_dash_demux_audiosrc_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_dash_demux_videosrc_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_dash_demux_subtitlesrc_template);

  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);

  gst_element_class_set_static_metadata (gstelement_class,
      "DASH Demuxer",
      "Codec/Demuxer/Adaptive",
      "Dynamic Adaptive Streaming over HTTP demuxer",
      "David Corvoysier <david.corvoysier@orange.com>\n\
                Hamid Zakari <hamid.zakari@gmail.com>\n\
                Gianluca Gennari <gennarone@gmail.com>");


  gstadaptivedemux_class->get_duration = gst_dash_demux_get_duration;
  gstadaptivedemux_class->is_live = gst_dash_demux_is_live;
  gstadaptivedemux_class->reset = gst_dash_demux_reset;
  gstadaptivedemux_class->seek = gst_dash_demux_seek;

  gstadaptivedemux_class->process_manifest = gst_dash_demux_process_manifest;
  gstadaptivedemux_class->update_manifest_data =
      gst_dash_demux_update_manifest_data;
  gstadaptivedemux_class->get_manifest_update_interval =
      gst_dash_demux_get_manifest_update_interval;

  gstadaptivedemux_class->has_next_period = gst_dash_demux_has_next_period;
  gstadaptivedemux_class->advance_period = gst_dash_demux_advance_period;
  gstadaptivedemux_class->stream_has_next_fragment =
      gst_dash_demux_stream_has_next_fragment;
  gstadaptivedemux_class->stream_advance_fragment =
      gst_dash_demux_stream_advance_fragment;
  gstadaptivedemux_class->stream_get_fragment_waiting_time =
      gst_dash_demux_stream_get_fragment_waiting_time;
  gstadaptivedemux_class->stream_seek = gst_dash_demux_stream_seek;
  gstadaptivedemux_class->stream_select_bitrate =
      gst_dash_demux_stream_select_bitrate;
  gstadaptivedemux_class->stream_update_fragment_info =
      gst_dash_demux_stream_update_fragment_info;
  gstadaptivedemux_class->stream_free = gst_dash_demux_stream_free;
  gstadaptivedemux_class->get_live_seek_range =
      gst_dash_demux_get_live_seek_range;
  gstadaptivedemux_class->get_presentation_offset =
      gst_dash_demux_get_presentation_offset;
  gstadaptivedemux_class->get_period_start_time =
      gst_dash_demux_get_period_start_time;

  gstadaptivedemux_class->start_fragment = gst_dash_demux_stream_fragment_start;
  gstadaptivedemux_class->finish_fragment =
      gst_dash_demux_stream_fragment_finished;
  gstadaptivedemux_class->data_received = gst_dash_demux_data_received;
  gstadaptivedemux_class->need_another_chunk =
      gst_dash_demux_need_another_chunk;
}

static void
gst_dash_demux_init (GstDashDemux * demux)
{
  /* Properties */
  demux->max_buffering_time = DEFAULT_MAX_BUFFERING_TIME * GST_SECOND;
  demux->max_bitrate = DEFAULT_MAX_BITRATE;
  demux->max_video_width = DEFAULT_MAX_VIDEO_WIDTH;
  demux->max_video_height = DEFAULT_MAX_VIDEO_HEIGHT;
  demux->max_video_framerate_n = DEFAULT_MAX_VIDEO_FRAMERATE_N;
  demux->max_video_framerate_d = DEFAULT_MAX_VIDEO_FRAMERATE_D;
  demux->default_presentation_delay = g_strdup (DEFAULT_PRESENTATION_DELAY);

  g_mutex_init (&demux->client_lock);

  gst_adaptive_demux_set_stream_struct_size (GST_ADAPTIVE_DEMUX_CAST (demux),
      sizeof (GstDashDemuxStream));
}

static void
gst_dash_demux_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAdaptiveDemux *adaptivedemux = GST_ADAPTIVE_DEMUX_CAST (object);
  GstDashDemux *demux = GST_DASH_DEMUX (object);

  switch (prop_id) {
    case PROP_MAX_BUFFERING_TIME:
      demux->max_buffering_time = g_value_get_uint (value) * GST_SECOND;
      break;
    case PROP_BANDWIDTH_USAGE:
      adaptivedemux->bitrate_limit = g_value_get_float (value);
      break;
    case PROP_MAX_BITRATE:
      demux->max_bitrate = g_value_get_uint (value);
      break;
    case PROP_MAX_VIDEO_WIDTH:
      demux->max_video_width = g_value_get_uint (value);
      break;
    case PROP_MAX_VIDEO_HEIGHT:
      demux->max_video_height = g_value_get_uint (value);
      break;
    case PROP_MAX_VIDEO_FRAMERATE:
      demux->max_video_framerate_n = gst_value_get_fraction_numerator (value);
      demux->max_video_framerate_d = gst_value_get_fraction_denominator (value);
      break;
    case PROP_PRESENTATION_DELAY:
      g_free (demux->default_presentation_delay);
      demux->default_presentation_delay = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_dash_demux_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstAdaptiveDemux *adaptivedemux = GST_ADAPTIVE_DEMUX_CAST (object);
  GstDashDemux *demux = GST_DASH_DEMUX (object);

  switch (prop_id) {
    case PROP_MAX_BUFFERING_TIME:
      g_value_set_uint (value, demux->max_buffering_time / GST_SECOND);
      break;
    case PROP_BANDWIDTH_USAGE:
      g_value_set_float (value, adaptivedemux->bitrate_limit);
      break;
    case PROP_MAX_BITRATE:
      g_value_set_uint (value, demux->max_bitrate);
      break;
    case PROP_MAX_VIDEO_WIDTH:
      g_value_set_uint (value, demux->max_video_width);
      break;
    case PROP_MAX_VIDEO_HEIGHT:
      g_value_set_uint (value, demux->max_video_height);
      break;
    case PROP_MAX_VIDEO_FRAMERATE:
      gst_value_set_fraction (value, demux->max_video_framerate_n,
          demux->max_video_framerate_d);
      break;
    case PROP_PRESENTATION_DELAY:
      if (demux->default_presentation_delay == NULL)
        g_value_set_static_string (value, "");
      else
        g_value_set_string (value, demux->default_presentation_delay);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_dash_demux_setup_mpdparser_streams (GstDashDemux * demux,
    GstMpdClient * client)
{
  gboolean has_streams = FALSE;
  GList *adapt_sets, *iter;

  adapt_sets = gst_mpd_client_get_adaptation_sets (client);
  for (iter = adapt_sets; iter; iter = g_list_next (iter)) {
    GstAdaptationSetNode *adapt_set_node = iter->data;

    gst_mpd_client_setup_streaming (client, adapt_set_node);
    has_streams = TRUE;
  }

  if (!has_streams) {
    GST_ELEMENT_ERROR (demux, STREAM, DEMUX, ("Manifest has no playable "
            "streams"), ("No streams could be activated from the manifest"));
  }
  return has_streams;
}

static gboolean
gst_dash_demux_setup_all_streams (GstDashDemux * demux)
{
  guint i;

  GST_DEBUG_OBJECT (demux, "Setting up streams for period %d",
      gst_mpd_client_get_period_index (demux->client));

  /* clean old active stream list, if any */
  gst_active_streams_free (demux->client);

  if (!gst_dash_demux_setup_mpdparser_streams (demux, demux->client)) {
    return FALSE;
  }

  GST_DEBUG_OBJECT (demux, "Creating stream objects");
  for (i = 0; i < gst_mpdparser_get_nb_active_stream (demux->client); i++) {
    GstDashDemuxStream *stream;
    GstActiveStream *active_stream;
    GstCaps *caps;
    GstStructure *s;
    GstPad *srcpad;
    gchar *lang = NULL;
    GstTagList *tags = NULL;

    active_stream = gst_mpdparser_get_active_stream_by_index (demux->client, i);
    if (active_stream == NULL)
      continue;

    if (demux->trickmode_no_audio
        && active_stream->mimeType == GST_STREAM_AUDIO) {
      GST_DEBUG_OBJECT (demux,
          "Skipping audio stream %d because of TRICKMODE_NO_AUDIO flag", i);
      continue;
    }

    srcpad = gst_dash_demux_create_pad (demux, active_stream);
    if (srcpad == NULL)
      continue;

    caps = gst_dash_demux_get_input_caps (demux, active_stream);
    GST_LOG_OBJECT (demux, "Creating stream %d %" GST_PTR_FORMAT, i, caps);

    if (active_stream->cur_adapt_set) {
      GstAdaptationSetNode *adp_set = active_stream->cur_adapt_set;
      lang = adp_set->lang;

      /* Fallback to the language in ContentComponent node */
      if (lang == NULL) {
        GList *it;

        for (it = adp_set->ContentComponents; it; it = it->next) {
          GstContentComponentNode *cc_node = it->data;
          if (cc_node->lang) {
            lang = cc_node->lang;
            break;
          }
        }
      }
    }

    if (lang) {
      if (gst_tag_check_language_code (lang))
        tags = gst_tag_list_new (GST_TAG_LANGUAGE_CODE, lang, NULL);
      else
        tags = gst_tag_list_new (GST_TAG_LANGUAGE_NAME, lang, NULL);
    }

    stream = (GstDashDemuxStream *)
        gst_adaptive_demux_stream_new (GST_ADAPTIVE_DEMUX_CAST (demux), srcpad);
    stream->active_stream = active_stream;
    s = gst_caps_get_structure (caps, 0);
    stream->allow_sidx =
        gst_mpd_client_has_isoff_ondemand_profile (demux->client);
    stream->is_isobmff = gst_structure_has_name (s, "video/quicktime")
        || gst_structure_has_name (s, "audio/x-m4a");
    stream->first_sync_sample_always_after_moof = TRUE;
    stream->adapter = gst_adapter_new ();
    gst_adaptive_demux_stream_set_caps (GST_ADAPTIVE_DEMUX_STREAM_CAST (stream),
        caps);
    if (tags)
      gst_adaptive_demux_stream_set_tags (GST_ADAPTIVE_DEMUX_STREAM_CAST
          (stream), tags);
    stream->index = i;
    stream->pending_seek_ts = GST_CLOCK_TIME_NONE;
    stream->sidx_position = GST_CLOCK_TIME_NONE;
    stream->actual_position = GST_CLOCK_TIME_NONE;
    stream->target_time = GST_CLOCK_TIME_NONE;
    /* Set a default average keyframe download time of a quarter of a second */
    stream->average_download_time = 250 * GST_MSECOND;
    if (active_stream->cur_adapt_set &&
        active_stream->cur_adapt_set->RepresentationBase &&
        active_stream->cur_adapt_set->RepresentationBase->ContentProtection) {
      GST_DEBUG_OBJECT (demux, "Adding ContentProtection events to source pad");
      g_list_foreach (active_stream->cur_adapt_set->RepresentationBase->
          ContentProtection, gst_dash_demux_send_content_protection_event,
          stream);
    }

    gst_isoff_sidx_parser_init (&stream->sidx_parser);
  }

  return TRUE;
}

static void
gst_dash_demux_send_content_protection_event (gpointer data, gpointer userdata)
{
  GstDescriptorType *cp = (GstDescriptorType *) data;
  GstDashDemuxStream *stream = (GstDashDemuxStream *) userdata;
  GstEvent *event;
  GstBuffer *pssi;
  glong pssi_len;
  gchar *schemeIdUri;

  if (cp->schemeIdUri == NULL)
    return;

  GST_TRACE_OBJECT (stream, "check schemeIdUri %s", cp->schemeIdUri);
  /* RFC 2141 states: The leading "urn:" sequence is case-insensitive */
  schemeIdUri = g_ascii_strdown (cp->schemeIdUri, -1);
  if (g_str_has_prefix (schemeIdUri, "urn:uuid:")) {
    pssi_len = strlen (cp->value);
    pssi = gst_buffer_new_wrapped (g_memdup (cp->value, pssi_len), pssi_len);
    GST_LOG_OBJECT (stream, "Queuing Protection event on source pad");
    /* RFC 4122 states that the hex part of a UUID is in lower case,
     * but some streams seem to ignore this and use upper case for the
     * protection system ID */
    event = gst_event_new_protection (cp->schemeIdUri + 9, pssi, "dash/mpd");
    gst_adaptive_demux_stream_queue_event ((GstAdaptiveDemuxStream *) stream,
        event);
    gst_buffer_unref (pssi);
  }
  g_free (schemeIdUri);
}

static GstClockTime
gst_dash_demux_get_duration (GstAdaptiveDemux * ademux)
{
  GstDashDemux *demux = GST_DASH_DEMUX_CAST (ademux);

  g_return_val_if_fail (demux->client != NULL, GST_CLOCK_TIME_NONE);

  return gst_mpd_client_get_media_presentation_duration (demux->client);
}

static gboolean
gst_dash_demux_is_live (GstAdaptiveDemux * ademux)
{
  GstDashDemux *demux = GST_DASH_DEMUX_CAST (ademux);

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

  return gst_mpd_client_is_live (demux->client);
}

static gboolean
gst_dash_demux_setup_streams (GstAdaptiveDemux * demux)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
  gboolean ret = TRUE;
  GstDateTime *now = NULL;
  guint period_idx;

  /* setup video, audio and subtitle streams, starting from first Period if
   * non-live */
  period_idx = 0;
  if (gst_mpd_client_is_live (dashdemux->client)) {
    GDateTime *g_now;
    if (dashdemux->client->mpd_node->availabilityStartTime == NULL) {
      ret = FALSE;
      GST_ERROR_OBJECT (demux, "MPD does not have availabilityStartTime");
      goto done;
    }
    if (dashdemux->clock_drift == NULL) {
      gchar **urls;
      urls =
          gst_mpd_client_get_utc_timing_sources (dashdemux->client,
          SUPPORTED_CLOCK_FORMATS, NULL);
      if (urls) {
        GST_DEBUG_OBJECT (dashdemux, "Found a supported UTCTiming element");
        dashdemux->clock_drift = gst_dash_demux_clock_drift_new (dashdemux);
        gst_dash_demux_poll_clock_drift (dashdemux);
      }
    }
    /* get period index for period encompassing the current time */
    g_now = gst_dash_demux_get_server_now_utc (dashdemux);
    now = gst_date_time_new_from_g_date_time (g_now);
    if (dashdemux->client->mpd_node->suggestedPresentationDelay != -1) {
      GstDateTime *target = gst_mpd_client_add_time_difference (now,
          dashdemux->client->mpd_node->suggestedPresentationDelay * -1000);
      gst_date_time_unref (now);
      now = target;
    } else if (dashdemux->default_presentation_delay) {
      gint64 dfp =
          gst_mpd_client_parse_default_presentation_delay (dashdemux->client,
          dashdemux->default_presentation_delay);
      GstDateTime *target = gst_mpd_client_add_time_difference (now,
          dfp * -1000);
      gst_date_time_unref (now);
      now = target;
    }
    period_idx =
        gst_mpd_client_get_period_index_at_time (dashdemux->client, now);
    if (period_idx == G_MAXUINT) {
#ifndef GST_DISABLE_GST_DEBUG
      gchar *date_str = gst_date_time_to_iso8601_string (now);
      GST_DEBUG_OBJECT (demux, "Unable to find live period active at %s",
          date_str);
      g_free (date_str);
#endif
      ret = FALSE;
      goto done;
    }
  }

  if (!gst_mpd_client_set_period_index (dashdemux->client, period_idx) ||
      !gst_dash_demux_setup_all_streams (dashdemux)) {
    ret = FALSE;
    goto done;
  }

  /* If stream is live, try to find the segment that
   * is closest to current time */
  if (gst_mpd_client_is_live (dashdemux->client)) {
    GDateTime *gnow;

    GST_DEBUG_OBJECT (demux, "Seeking to current time of day for live stream ");

    gnow = gst_date_time_to_g_date_time (now);
    gst_mpd_client_seek_to_time (dashdemux->client, gnow);
    g_date_time_unref (gnow);
  } else {
    GST_DEBUG_OBJECT (demux, "Seeking to first segment for on-demand stream ");

    /* start playing from the first segment */
    gst_mpd_client_seek_to_first_segment (dashdemux->client);
  }

done:
  if (now != NULL)
    gst_date_time_unref (now);
  return ret;
}

static gboolean
gst_dash_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
  gboolean ret = FALSE;
  gchar *manifest;
  GstMapInfo mapinfo;

  if (dashdemux->client)
    gst_mpd_client_free (dashdemux->client);
  dashdemux->client = gst_mpd_client_new ();
  gst_mpd_client_set_uri_downloader (dashdemux->client, demux->downloader);

  dashdemux->client->mpd_uri = g_strdup (demux->manifest_uri);
  dashdemux->client->mpd_base_uri = g_strdup (demux->manifest_base_uri);

  GST_DEBUG_OBJECT (demux, "Fetched MPD file at URI: %s (base: %s)",
      dashdemux->client->mpd_uri,
      GST_STR_NULL (dashdemux->client->mpd_base_uri));

  if (gst_buffer_map (buf, &mapinfo, GST_MAP_READ)) {
    manifest = (gchar *) mapinfo.data;
    if (gst_mpd_parse (dashdemux->client, manifest, mapinfo.size)) {
      if (gst_mpd_client_setup_media_presentation (dashdemux->client, 0, 0,
              NULL)) {
        ret = TRUE;
      } else {
        GST_ELEMENT_ERROR (demux, STREAM, DECODE,
            ("Incompatible manifest file."), (NULL));
      }
    }
    gst_buffer_unmap (buf, &mapinfo);
  } else {
    GST_WARNING_OBJECT (demux, "Failed to map manifest buffer");
  }

  if (ret)
    ret = gst_dash_demux_setup_streams (demux);

  return ret;
}

static GstPad *
gst_dash_demux_create_pad (GstDashDemux * demux, GstActiveStream * stream)
{
  GstPad *pad;
  GstPadTemplate *tmpl;
  gchar *name;

  switch (stream->mimeType) {
    case GST_STREAM_AUDIO:
      name = g_strdup_printf ("audio_%02u", demux->n_audio_streams++);
      tmpl = gst_static_pad_template_get (&gst_dash_demux_audiosrc_template);
      break;
    case GST_STREAM_VIDEO:
      name = g_strdup_printf ("video_%02u", demux->n_video_streams++);
      tmpl = gst_static_pad_template_get (&gst_dash_demux_videosrc_template);
      break;
    case GST_STREAM_APPLICATION:
      if (gst_mpd_client_active_stream_contains_subtitles (stream)) {
        name = g_strdup_printf ("subtitle_%02u", demux->n_subtitle_streams++);
        tmpl =
            gst_static_pad_template_get (&gst_dash_demux_subtitlesrc_template);
      } else {
        return NULL;
      }
      break;
    default:
      g_assert_not_reached ();
      return NULL;
  }

  /* Create and activate new pads */
  pad = gst_pad_new_from_template (tmpl, name);
  g_free (name);
  gst_object_unref (tmpl);

  gst_pad_set_active (pad, TRUE);
  GST_INFO_OBJECT (demux, "Creating srcpad %s:%s", GST_DEBUG_PAD_NAME (pad));
  return pad;
}

static void
gst_dash_demux_reset (GstAdaptiveDemux * ademux)
{
  GstDashDemux *demux = GST_DASH_DEMUX_CAST (ademux);

  GST_DEBUG_OBJECT (demux, "Resetting demux");

  demux->end_of_period = FALSE;
  demux->end_of_manifest = FALSE;

  if (demux->client) {
    gst_mpd_client_free (demux->client);
    demux->client = NULL;
  }
  gst_dash_demux_clock_drift_free (demux->clock_drift);
  demux->clock_drift = NULL;
  demux->client = gst_mpd_client_new ();
  gst_mpd_client_set_uri_downloader (demux->client, ademux->downloader);

  demux->n_audio_streams = 0;
  demux->n_video_streams = 0;
  demux->n_subtitle_streams = 0;

  demux->trickmode_no_audio = FALSE;
  demux->allow_trickmode_key_units = TRUE;
}

static GstCaps *
gst_dash_demux_get_video_input_caps (GstDashDemux * demux,
    GstActiveStream * stream)
{
  guint width = 0, height = 0;
  gint fps_num = 0, fps_den = 1;
  gboolean have_fps = FALSE;
  GstCaps *caps = NULL;

  if (stream == NULL)
    return NULL;

  /* if bitstreamSwitching is true we dont need to swich pads on resolution change */
  if (!gst_mpd_client_get_bitstream_switching_flag (stream)) {
    width = gst_mpd_client_get_video_stream_width (stream);
    height = gst_mpd_client_get_video_stream_height (stream);
    have_fps =
        gst_mpd_client_get_video_stream_framerate (stream, &fps_num, &fps_den);
  }
  caps = gst_mpd_client_get_stream_caps (stream);
  if (caps == NULL)
    return NULL;

  if (width > 0 && height > 0) {
    gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height",
        G_TYPE_INT, height, NULL);
  }

  if (have_fps) {
    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, fps_num,
        fps_den, NULL);
  }

  return caps;
}

static GstCaps *
gst_dash_demux_get_audio_input_caps (GstDashDemux * demux,
    GstActiveStream * stream)
{
  guint rate = 0, channels = 0;
  GstCaps *caps = NULL;

  if (stream == NULL)
    return NULL;

  /* if bitstreamSwitching is true we dont need to swich pads on rate/channels change */
  if (!gst_mpd_client_get_bitstream_switching_flag (stream)) {
    channels = gst_mpd_client_get_audio_stream_num_channels (stream);
    rate = gst_mpd_client_get_audio_stream_rate (stream);
  }
  caps = gst_mpd_client_get_stream_caps (stream);
  if (caps == NULL)
    return NULL;

  if (rate > 0) {
    gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate, NULL);
  }
  if (channels > 0) {
    gst_caps_set_simple (caps, "channels", G_TYPE_INT, channels, NULL);
  }

  return caps;
}

static GstCaps *
gst_dash_demux_get_application_input_caps (GstDashDemux * demux,
    GstActiveStream * stream)
{
  GstCaps *caps = NULL;

  if (stream == NULL)
    return NULL;

  caps = gst_mpd_client_get_stream_caps (stream);
  if (caps == NULL)
    return NULL;

  return caps;
}

static GstCaps *
gst_dash_demux_get_input_caps (GstDashDemux * demux, GstActiveStream * stream)
{
  switch (stream->mimeType) {
    case GST_STREAM_VIDEO:
      return gst_dash_demux_get_video_input_caps (demux, stream);
    case GST_STREAM_AUDIO:
      return gst_dash_demux_get_audio_input_caps (demux, stream);
    case GST_STREAM_APPLICATION:
      return gst_dash_demux_get_application_input_caps (demux, stream);
    default:
      return GST_CAPS_NONE;
  }
}

static void
gst_dash_demux_stream_update_headers_info (GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (stream->demux);
  gchar *path = NULL;

  gst_mpd_client_get_next_header (dashdemux->client,
      &path, dashstream->index,
      &stream->fragment.header_range_start, &stream->fragment.header_range_end);

  if (path != NULL) {
    stream->fragment.header_uri =
        gst_uri_join_strings (gst_mpdparser_get_baseURL (dashdemux->client,
            dashstream->index), path);
    g_free (path);
    path = NULL;
  }

  gst_mpd_client_get_next_header_index (dashdemux->client,
      &path, dashstream->index,
      &stream->fragment.index_range_start, &stream->fragment.index_range_end);

  if (path != NULL) {
    stream->fragment.index_uri =
        gst_uri_join_strings (gst_mpdparser_get_baseURL (dashdemux->client,
            dashstream->index), path);
    g_free (path);
  }
}

static GstFlowReturn
gst_dash_demux_stream_update_fragment_info (GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (stream->demux);
  GstClockTime ts;
  GstMediaFragmentInfo fragment;
  gboolean isombff;

  gst_adaptive_demux_stream_fragment_clear (&stream->fragment);

  isombff = gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client);

  /* Reset chunk size if any */
  stream->fragment.chunk_size = 0;
  dashstream->current_fragment_keyframe_distance = GST_CLOCK_TIME_NONE;

  if (GST_ADAPTIVE_DEMUX_STREAM_NEED_HEADER (stream) && isombff) {
    gst_dash_demux_stream_update_headers_info (stream);
    /* sidx entries may not be available in here */
    if (stream->fragment.index_uri
        && dashstream->sidx_position != GST_CLOCK_TIME_NONE) {
      /* request only the index to be downloaded as we need to reposition the
       * stream to a subsegment */
      return GST_FLOW_OK;
    }
  }

  if (dashstream->moof_sync_samples
      && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (dashdemux)) {
    GstDashStreamSyncSample *sync_sample =
        &g_array_index (dashstream->moof_sync_samples, GstDashStreamSyncSample,
        dashstream->current_sync_sample);

    gst_mpd_client_get_next_fragment (dashdemux->client, dashstream->index,
        &fragment);

    if (isombff && dashstream->sidx_position != GST_CLOCK_TIME_NONE
        && SIDX (dashstream)->entries) {
      GstSidxBoxEntry *entry = SIDX_CURRENT_ENTRY (dashstream);
      dashstream->current_fragment_timestamp = fragment.timestamp = entry->pts;
      dashstream->current_fragment_duration = fragment.duration =
          entry->duration;
    } else {
      dashstream->current_fragment_timestamp = fragment.timestamp;
      dashstream->current_fragment_duration = fragment.duration;
    }

    dashstream->current_fragment_keyframe_distance =
        fragment.duration / dashstream->moof_sync_samples->len;
    dashstream->actual_position =
        fragment.timestamp +
        dashstream->current_sync_sample *
        dashstream->current_fragment_keyframe_distance;
    if (stream->segment.rate < 0.0)
      dashstream->actual_position +=
          dashstream->current_fragment_keyframe_distance;
    dashstream->actual_position =
        MIN (dashstream->actual_position,
        fragment.timestamp + fragment.duration);

    stream->fragment.uri = fragment.uri;
    stream->fragment.timestamp = GST_CLOCK_TIME_NONE;
    stream->fragment.duration = GST_CLOCK_TIME_NONE;
    stream->fragment.range_start = sync_sample->start_offset;
    stream->fragment.range_end = sync_sample->end_offset;

    GST_DEBUG_OBJECT (stream->pad, "Actual position %" GST_TIME_FORMAT,
        GST_TIME_ARGS (dashstream->actual_position));

    return GST_FLOW_OK;
  }

  if (gst_mpd_client_get_next_fragment_timestamp (dashdemux->client,
          dashstream->index, &ts)) {
    if (GST_ADAPTIVE_DEMUX_STREAM_NEED_HEADER (stream)) {
      gst_adaptive_demux_stream_fragment_clear (&stream->fragment);
      gst_dash_demux_stream_update_headers_info (stream);
    }

    gst_mpd_client_get_next_fragment (dashdemux->client, dashstream->index,
        &fragment);

    stream->fragment.uri = fragment.uri;
    /* If mpd does not specify indexRange (i.e., null index_uri),
     * sidx entries may not be available until download it */
    if (isombff && dashstream->sidx_position != GST_CLOCK_TIME_NONE
        && SIDX (dashstream)->entries) {
      GstSidxBoxEntry *entry = SIDX_CURRENT_ENTRY (dashstream);
      stream->fragment.range_start =
          dashstream->sidx_base_offset + entry->offset;
      dashstream->actual_position = stream->fragment.timestamp = entry->pts;
      dashstream->current_fragment_timestamp = stream->fragment.timestamp =
          entry->pts;
      dashstream->current_fragment_duration = stream->fragment.duration =
          entry->duration;
      if (stream->demux->segment.rate < 0.0) {
        stream->fragment.range_end =
            stream->fragment.range_start + entry->size - 1;
        dashstream->actual_position += entry->duration;
      } else {
        stream->fragment.range_end = fragment.range_end;
      }
    } else {
      dashstream->actual_position = stream->fragment.timestamp =
          fragment.timestamp;
      dashstream->current_fragment_timestamp = fragment.timestamp;
      dashstream->current_fragment_duration = stream->fragment.duration =
          fragment.duration;
      if (stream->demux->segment.rate < 0.0)
        dashstream->actual_position += fragment.duration;
      stream->fragment.range_start =
          MAX (fragment.range_start, dashstream->sidx_base_offset);
      stream->fragment.range_end = fragment.range_end;
    }

    GST_DEBUG_OBJECT (stream->pad, "Actual position %" GST_TIME_FORMAT,
        GST_TIME_ARGS (dashstream->actual_position));

    return GST_FLOW_OK;
  }

  return GST_FLOW_EOS;
}

static gint
gst_dash_demux_index_entry_search (GstSidxBoxEntry * entry, GstClockTime * ts,
    gpointer user_data)
{
  GstClockTime entry_ts = entry->pts + entry->duration;
  if (entry_ts <= *ts)
    return -1;
  else if (entry->pts > *ts)
    return 1;
  else
    return 0;
}

static GstFlowReturn
gst_dash_demux_stream_sidx_seek (GstDashDemuxStream * dashstream,
    gboolean forward, GstSeekFlags flags, GstClockTime ts,
    GstClockTime * final_ts)
{
  GstSidxBox *sidx = SIDX (dashstream);
  GstSidxBoxEntry *entry;
  gint idx = sidx->entries_count;
  GstFlowReturn ret = GST_FLOW_OK;

  if (sidx->entries_count == 0)
    return GST_FLOW_EOS;

  entry =
      gst_util_array_binary_search (sidx->entries, sidx->entries_count,
      sizeof (GstSidxBoxEntry),
      (GCompareDataFunc) gst_dash_demux_index_entry_search,
      GST_SEARCH_MODE_EXACT, &ts, NULL);

  /* No exact match found, nothing in our index
   * This is usually a bug or broken stream, as the seeking code already
   * makes sure that we're in the correct period and segment, and only need
   * to find the correct place inside the segment. Allow for some rounding
   * errors and inaccuracies here though */
  if (!entry) {
    GstSidxBoxEntry *last_entry = &sidx->entries[sidx->entries_count - 1];

    GST_WARNING_OBJECT (dashstream->parent.pad, "Couldn't find SIDX entry");

    if (ts < sidx->entries[0].pts
        && ts + 250 * GST_MSECOND >= sidx->entries[0].pts)
      entry = &sidx->entries[0];
    else if (ts >= last_entry->pts + last_entry->duration &&
        ts < last_entry->pts + last_entry->duration + 250 * GST_MSECOND)
      entry = last_entry;
  }
  if (!entry)
    return GST_FLOW_EOS;

  idx = entry - sidx->entries;

  /* FIXME in reverse mode, if we are exactly at a fragment start it makes more
   * sense to start from the end of the previous fragment */
  if (!forward && idx > 0 && entry->pts == ts) {
    idx--;
    entry = &sidx->entries[idx];
  }

  /* Now entry->pts <= ts < entry->pts + entry->duration, need to adjust for
   * snapping */
  if ((flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST) {
    if (idx + 1 < sidx->entries_count
        && sidx->entries[idx + 1].pts - ts < ts - sidx->entries[idx].pts)
      idx += 1;
  } else if ((forward && (flags & GST_SEEK_FLAG_SNAP_AFTER)) || (!forward
          && (flags & GST_SEEK_FLAG_SNAP_BEFORE))) {
    if (idx + 1 < sidx->entries_count && entry->pts < ts)
      idx += 1;
  }

  g_assert (sidx->entry_index < sidx->entries_count);

  sidx->entry_index = idx;
  dashstream->sidx_position = sidx->entries[idx].pts;

  if (final_ts)
    *final_ts = dashstream->sidx_position;

  return ret;
}

static GstFlowReturn
gst_dash_demux_stream_seek (GstAdaptiveDemuxStream * stream, gboolean forward,
    GstSeekFlags flags, GstClockTime ts, GstClockTime * final_ts)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (stream->demux);
  gint last_index, last_repeat;
  gboolean is_isobmff;

  last_index = dashstream->active_stream->segment_index;
  last_repeat = dashstream->active_stream->segment_repeat_index;

  if (dashstream->adapter)
    gst_adapter_clear (dashstream->adapter);
  dashstream->current_offset = -1;
  dashstream->current_index_header_or_data = 0;

  dashstream->isobmff_parser.current_fourcc = 0;
  dashstream->isobmff_parser.current_start_offset = 0;
  dashstream->isobmff_parser.current_size = 0;

  if (dashstream->moof)
    gst_isoff_moof_box_free (dashstream->moof);
  dashstream->moof = NULL;
  if (dashstream->moof_sync_samples)
    g_array_free (dashstream->moof_sync_samples, TRUE);
  dashstream->moof_sync_samples = NULL;
  dashstream->current_sync_sample = -1;
  dashstream->target_time = GST_CLOCK_TIME_NONE;

  is_isobmff = gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client);

  if (!gst_mpd_client_stream_seek (dashdemux->client, dashstream->active_stream,
          forward,
          is_isobmff ? (flags & (~(GST_SEEK_FLAG_SNAP_BEFORE |
                      GST_SEEK_FLAG_SNAP_AFTER))) : flags, ts, final_ts)) {
    return GST_FLOW_EOS;
  }

  if (is_isobmff) {
    GstClockTime period_start, offset;

    period_start = gst_mpd_parser_get_period_start_time (dashdemux->client);
    offset =
        gst_mpd_parser_get_stream_presentation_offset (dashdemux->client,
        dashstream->index);

    if (G_UNLIKELY (ts < period_start))
      ts = offset;
    else
      ts += offset - period_start;

    if (last_index != dashstream->active_stream->segment_index ||
        last_repeat != dashstream->active_stream->segment_repeat_index) {
      GST_LOG_OBJECT (stream->pad,
          "Segment index was changed, reset sidx parser");
      gst_isoff_sidx_parser_clear (&dashstream->sidx_parser);
      dashstream->sidx_base_offset = 0;
      dashstream->allow_sidx = TRUE;
    }

    if (dashstream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
      if (gst_dash_demux_stream_sidx_seek (dashstream, forward, flags, ts,
              final_ts) != GST_FLOW_OK) {
        GST_ERROR_OBJECT (stream->pad, "Couldn't find position in sidx");
        dashstream->sidx_position = GST_CLOCK_TIME_NONE;
        gst_isoff_sidx_parser_clear (&dashstream->sidx_parser);
      }
      dashstream->pending_seek_ts = GST_CLOCK_TIME_NONE;
    } else {
      /* no index yet, seek when we have it */
      /* FIXME - the final_ts won't be correct here */
      dashstream->pending_seek_ts = ts;
    }
  }

  stream->discont = TRUE;

  return GST_FLOW_OK;
}

static gboolean
gst_dash_demux_stream_has_next_sync_sample (GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;

  if (dashstream->moof_sync_samples &&
      GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (stream->demux)) {
    if (stream->demux->segment.rate > 0.0) {
      if (dashstream->current_sync_sample + 1 <
          dashstream->moof_sync_samples->len)
        return TRUE;
    } else {
      if (dashstream->current_sync_sample >= 1)
        return TRUE;
    }
  }
  return FALSE;
}

static gboolean
gst_dash_demux_stream_has_next_subfragment (GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  GstSidxBox *sidx = SIDX (dashstream);

  if (dashstream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
    if (stream->demux->segment.rate > 0.0) {
      if (sidx->entry_index + 1 < sidx->entries_count)
        return TRUE;
    } else {
      if (sidx->entry_index >= 1)
        return TRUE;
    }
  }
  return FALSE;
}

static gboolean
gst_dash_demux_stream_advance_sync_sample (GstAdaptiveDemuxStream * stream,
    GstClockTime target_time)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  gboolean fragment_finished = FALSE;
  guint idx = -1;

  if (GST_CLOCK_TIME_IS_VALID (target_time)) {
    GST_LOG_OBJECT (stream->pad,
        "target_time:%" GST_TIME_FORMAT " fragment ts %" GST_TIME_FORMAT
        " average keyframe dist: %" GST_TIME_FORMAT
        " current keyframe dist: %" GST_TIME_FORMAT
        " fragment duration:%" GST_TIME_FORMAT,
        GST_TIME_ARGS (target_time),
        GST_TIME_ARGS (dashstream->current_fragment_timestamp),
        GST_TIME_ARGS (dashstream->keyframe_average_distance),
        GST_TIME_ARGS (dashstream->current_fragment_keyframe_distance),
        GST_TIME_ARGS (stream->fragment.duration));

    if (stream->demux->segment.rate > 0.0) {
      idx =
          (target_time -
          dashstream->current_fragment_timestamp) /
          dashstream->current_fragment_keyframe_distance;

      /* Prevent getting stuck in a loop due to rounding errors */
      if (idx == dashstream->current_sync_sample)
        idx++;
    } else {
      GstClockTime end_time =
          dashstream->current_fragment_timestamp +
          dashstream->current_fragment_duration;

      if (end_time < target_time) {
        idx = dashstream->moof_sync_samples->len;
      } else {
        idx =
            (end_time -
            target_time) / dashstream->current_fragment_keyframe_distance;
        if (idx == dashstream->moof_sync_samples->len) {
          dashstream->current_sync_sample = -1;
          fragment_finished = TRUE;
          goto beach;
        }
        idx = dashstream->moof_sync_samples->len - 1 - idx;
      }

      /* Prevent getting stuck in a loop due to rounding errors */
      if (idx == dashstream->current_sync_sample) {
        if (idx == 0) {
          dashstream->current_sync_sample = -1;
          fragment_finished = TRUE;
          goto beach;
        }

        idx--;
      }
    }
  }

  GST_DEBUG_OBJECT (stream->pad,
      "Advancing sync sample #%d target #%d",
      dashstream->current_sync_sample, idx);

  if (idx != -1 && idx >= dashstream->moof_sync_samples->len) {
    dashstream->current_sync_sample = -1;
    fragment_finished = TRUE;
    goto beach;
  }

  if (stream->demux->segment.rate > 0.0) {
    /* Try to get the sync sample for the target time */
    if (idx != -1) {
      dashstream->current_sync_sample = idx;
    } else {
      dashstream->current_sync_sample++;
      if (dashstream->current_sync_sample >= dashstream->moof_sync_samples->len) {
        fragment_finished = TRUE;
      }
    }
  } else {
    if (idx != -1) {
      dashstream->current_sync_sample = idx;
    } else if (dashstream->current_sync_sample == -1) {
      dashstream->current_sync_sample = dashstream->moof_sync_samples->len - 1;
    } else if (dashstream->current_sync_sample == 0) {
      dashstream->current_sync_sample = -1;
      fragment_finished = TRUE;
    } else {
      dashstream->current_sync_sample--;
    }
  }

beach:
  GST_DEBUG_OBJECT (stream->pad,
      "Advancing sync sample #%d fragment_finished:%d",
      dashstream->current_sync_sample, fragment_finished);

  if (!fragment_finished)
    stream->discont = TRUE;

  return !fragment_finished;
}

static gboolean
gst_dash_demux_stream_advance_subfragment (GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;

  GstSidxBox *sidx = SIDX (dashstream);
  gboolean fragment_finished = TRUE;

  if (dashstream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
    if (stream->demux->segment.rate > 0.0) {
      gint idx = ++sidx->entry_index;
      if (idx < sidx->entries_count) {
        fragment_finished = FALSE;
      }

      if (idx == sidx->entries_count)
        dashstream->sidx_position =
            sidx->entries[idx - 1].pts + sidx->entries[idx - 1].duration;
      else
        dashstream->sidx_position = sidx->entries[idx].pts;
    } else {
      gint idx = --sidx->entry_index;

      if (idx >= 0) {
        fragment_finished = FALSE;
        dashstream->sidx_position = sidx->entries[idx].pts;
      } else {
        dashstream->sidx_position = GST_CLOCK_TIME_NONE;
      }
    }
  }

  GST_DEBUG_OBJECT (stream->pad, "New sidx index: %d / %d. "
      "Finished fragment: %d", sidx->entry_index, sidx->entries_count,
      fragment_finished);

  return !fragment_finished;
}

static gboolean
gst_dash_demux_stream_has_next_fragment (GstAdaptiveDemuxStream * stream)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (stream->demux);
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;

  if (dashstream->moof_sync_samples &&
      GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (dashdemux)) {
    if (gst_dash_demux_stream_has_next_sync_sample (stream))
      return TRUE;
  }

  if (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client)) {
    if (gst_dash_demux_stream_has_next_subfragment (stream))
      return TRUE;
  }

  return gst_mpd_client_has_next_segment (dashdemux->client,
      dashstream->active_stream, stream->demux->segment.rate > 0.0);
}

/* The goal here is to figure out, once we have pushed a keyframe downstream,
 * what the next ideal keyframe to download is.
 * 
 * This is done based on:
 * * the current internal position (i.e. actual_position)
 * * the reported downstream position (QoS feedback)
 * * the average keyframe download time (average_download_time)
 */
static GstClockTime
gst_dash_demux_stream_get_target_time (GstDashDemux * dashdemux,
    GstAdaptiveDemuxStream * stream, GstClockTime cur_position,
    GstClockTime min_skip)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  GstClockTime cur_running, min_running, min_position;
  GstClockTimeDiff diff;
  GstClockTime ret = cur_position;
  GstClockTime deadline;
  GstClockTime earliest_time = GST_CLOCK_TIME_NONE;

  g_assert (min_skip > 0);

  /* minimum stream position we have to skip to */
  if (stream->segment.rate > 0)
    min_position = cur_position + min_skip;
  else if (cur_position < min_skip)
    min_position = 0;
  else
    min_position = cur_position - min_skip;

  /* Use current clock time or the QoS earliest time, whichever is further in
   * the future. The QoS time is only updated on every QoS event and
   * especially not if e.g. a videodecoder or converter drops a frame further
   * downstream.
   *
   * We only use the times if we ever received a QoS event since the last
   * flush, as otherwise base_time and clock might not be correct because of a
   * still pre-rolling sink
   */
  if (stream->qos_earliest_time != GST_CLOCK_TIME_NONE) {
    GstClock *clock;

    clock = gst_element_get_clock (GST_ELEMENT_CAST (dashdemux));

    if (clock) {
      GstClockTime base_time;
      GstClockTime now_time;

      base_time = gst_element_get_base_time (GST_ELEMENT_CAST (dashdemux));
      now_time = gst_clock_get_time (clock);
      if (now_time > base_time)
        now_time -= base_time;
      else
        now_time = 0;

      gst_object_unref (clock);

      earliest_time = MAX (now_time, stream->qos_earliest_time);
    } else {
      earliest_time = stream->qos_earliest_time;
    }
  }

  /* our current position in running time */
  cur_running =
      gst_segment_to_running_time (&stream->segment, GST_FORMAT_TIME,
      cur_position);

  /* the minimum position we have to skip to in running time */
  min_running =
      gst_segment_to_running_time (&stream->segment, GST_FORMAT_TIME,
      min_position);

  GST_DEBUG_OBJECT (stream->pad,
      "position: current %" GST_TIME_FORMAT " min next %" GST_TIME_FORMAT,
      GST_TIME_ARGS (cur_position), GST_TIME_ARGS (min_position));
  GST_DEBUG_OBJECT (stream->pad,
      "running time: current %" GST_TIME_FORMAT " min next %" GST_TIME_FORMAT
      " earliest %" GST_TIME_FORMAT, GST_TIME_ARGS (cur_running),
      GST_TIME_ARGS (min_running), GST_TIME_ARGS (earliest_time));

  /* Take configured maximum video bandwidth and framerate into account */
  {
    GstClockTime min_run_dist, min_frame_dist, diff = 0;
    guint max_fps_n, max_fps_d;

    min_run_dist = min_skip / ABS (stream->segment.rate);

    if (dashdemux->max_video_framerate_n != 0) {
      max_fps_n = dashdemux->max_video_framerate_n;
      max_fps_d = dashdemux->max_video_framerate_d;
    } else {
      /* more than 10 fps is not very useful if we're skipping anyway */
      max_fps_n = 10;
      max_fps_d = 1;
    }

    min_frame_dist = gst_util_uint64_scale_ceil (GST_SECOND,
        max_fps_d, max_fps_n);

    GST_DEBUG_OBJECT (stream->pad,
        "Have max framerate %d/%d - Min dist %" GST_TIME_FORMAT
        ", min requested dist %" GST_TIME_FORMAT,
        max_fps_n, max_fps_d,
        GST_TIME_ARGS (min_run_dist), GST_TIME_ARGS (min_frame_dist));
    if (min_frame_dist > min_run_dist)
      diff = MAX (diff, min_frame_dist - min_run_dist);

    if (dashdemux->max_bitrate != 0) {
      guint64 max_bitrate = gst_util_uint64_scale_ceil (GST_SECOND,
          8 * dashstream->keyframe_average_size,
          dashstream->keyframe_average_distance) * ABS (stream->segment.rate);

      if (max_bitrate > dashdemux->max_bitrate) {
        min_frame_dist = gst_util_uint64_scale_ceil (GST_SECOND,
            8 * dashstream->keyframe_average_size,
            dashdemux->max_bitrate) * ABS (stream->segment.rate);

        GST_DEBUG_OBJECT (stream->pad,
            "Have max bitrate %u - Min dist %" GST_TIME_FORMAT
            ", min requested dist %" GST_TIME_FORMAT, dashdemux->max_bitrate,
            GST_TIME_ARGS (min_run_dist), GST_TIME_ARGS (min_frame_dist));
        if (min_frame_dist > min_run_dist)
          diff = MAX (diff, min_frame_dist - min_run_dist);
      }
    }

    if (diff > 0) {
      GST_DEBUG_OBJECT (stream->pad,
          "Skipping further ahead by %" GST_TIME_FORMAT, GST_TIME_ARGS (diff));
      min_running += diff;
    }
  }

  if (earliest_time == GST_CLOCK_TIME_NONE) {
    GstClockTime run_key_dist;

    run_key_dist =
        dashstream->keyframe_average_distance / ABS (stream->segment.rate);

    /* If we don't have downstream information (such as at startup or
     * without live sinks), just get the next time by taking the minimum
     * amount we have to skip ahead
     * Except if it takes us longer to download */
    if (run_key_dist > dashstream->average_download_time)
      ret =
          gst_segment_position_from_running_time (&stream->segment,
          GST_FORMAT_TIME, min_running);
    else
      ret = gst_segment_position_from_running_time (&stream->segment,
          GST_FORMAT_TIME,
          min_running - run_key_dist + dashstream->average_download_time);

    GST_DEBUG_OBJECT (stream->pad,
        "Advancing to %" GST_TIME_FORMAT " (was %" GST_TIME_FORMAT ")",
        GST_TIME_ARGS (ret), GST_TIME_ARGS (min_position));

    goto out;
  }

  /* Figure out the difference, in running time, between where we are and
   * where downstream is */
  diff = min_running - earliest_time;
  GST_LOG_OBJECT (stream->pad,
      "min_running %" GST_TIME_FORMAT " diff %" GST_STIME_FORMAT
      " average_download %" GST_TIME_FORMAT, GST_TIME_ARGS (min_running),
      GST_STIME_ARGS (diff), GST_TIME_ARGS (dashstream->average_download_time));

  /* Have at least 500ms or 3 keyframes safety between current position and downstream */
  deadline = MAX (500 * GST_MSECOND, 3 * dashstream->average_download_time);

  /* The furthest away we are from the current position, the least we need to advance */
  if (diff < 0 || diff < deadline) {
    /* Force skipping (but not more than 1s ahead) */
    ret =
        gst_segment_position_from_running_time (&stream->segment,
        GST_FORMAT_TIME, earliest_time + MIN (deadline, GST_SECOND));
    GST_DEBUG_OBJECT (stream->pad,
        "MUST SKIP to at least %" GST_TIME_FORMAT " (was %" GST_TIME_FORMAT ")",
        GST_TIME_ARGS (ret), GST_TIME_ARGS (min_position));
  } else if (diff < 4 * dashstream->average_download_time) {
    /* Go forward a bit less aggresively (and at most 1s forward) */
    ret = gst_segment_position_from_running_time (&stream->segment,
        GST_FORMAT_TIME, min_running + MIN (GST_SECOND,
            2 * dashstream->average_download_time));
    GST_DEBUG_OBJECT (stream->pad,
        "MUST SKIP to at least %" GST_TIME_FORMAT " (was %" GST_TIME_FORMAT ")",
        GST_TIME_ARGS (ret), GST_TIME_ARGS (min_position));
  } else {
    /* Get the next position satisfying the download time */
    ret = gst_segment_position_from_running_time (&stream->segment,
        GST_FORMAT_TIME, min_running);
    GST_DEBUG_OBJECT (stream->pad,
        "Advance to %" GST_TIME_FORMAT " (was %" GST_TIME_FORMAT ")",
        GST_TIME_ARGS (ret), GST_TIME_ARGS (min_position));
  }

out:

  {
    GstClockTime cur_skip =
        (cur_position < ret) ? ret - cur_position : cur_position - ret;

    if (dashstream->average_skip_size == 0) {
      dashstream->average_skip_size = cur_skip;
    } else {
      dashstream->average_skip_size =
          (cur_skip + 3 * dashstream->average_skip_size) / 4;
    }

    if (dashstream->average_skip_size >
        cur_skip + dashstream->keyframe_average_distance
        && dashstream->average_skip_size > min_skip) {
      if (stream->segment.rate > 0)
        ret = cur_position + dashstream->average_skip_size;
      else if (cur_position > dashstream->average_skip_size)
        ret = cur_position - dashstream->average_skip_size;
      else
        ret = 0;
    }
  }

  return ret;
}

static GstFlowReturn
gst_dash_demux_stream_advance_fragment (GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (stream->demux);
  GstClockTime target_time = GST_CLOCK_TIME_NONE;
  GstClockTime previous_position;
  GstFlowReturn ret;

  GST_DEBUG_OBJECT (stream->pad, "Advance fragment");

  /* Update download statistics */
  if (dashstream->moof_sync_samples &&
      GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (dashdemux) &&
      GST_CLOCK_TIME_IS_VALID (stream->last_download_time)) {
    if (GST_CLOCK_TIME_IS_VALID (dashstream->average_download_time)) {
      dashstream->average_download_time =
          (3 * dashstream->average_download_time +
          stream->last_download_time) / 4;
    } else {
      dashstream->average_download_time = stream->last_download_time;
    }

    GST_DEBUG_OBJECT (stream->pad,
        "Download time last: %" GST_TIME_FORMAT " average: %" GST_TIME_FORMAT,
        GST_TIME_ARGS (stream->last_download_time),
        GST_TIME_ARGS (dashstream->average_download_time));
  }

  previous_position = dashstream->actual_position;

  /* Update internal position */
  if (GST_CLOCK_TIME_IS_VALID (dashstream->actual_position)) {
    GstClockTime dur;
    if (dashstream->moof_sync_samples
        && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (dashdemux)) {
      GST_LOG_OBJECT (stream->pad, "current sync sample #%d",
          dashstream->current_sync_sample);
      if (dashstream->current_sync_sample == -1) {
        dur = 0;
      } else if (dashstream->current_sync_sample <
          dashstream->moof_sync_samples->len) {
        dur = dashstream->current_fragment_keyframe_distance;
      } else {
        if (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client) &&
            dashstream->sidx_position != GST_CLOCK_TIME_NONE
            && SIDX (dashstream)->entries) {
          GstSidxBoxEntry *entry = SIDX_CURRENT_ENTRY (dashstream);
          dur = entry->duration;
        } else {
          dur =
              dashstream->current_fragment_timestamp +
              dashstream->current_fragment_duration -
              dashstream->actual_position;
        }
      }
    } else if (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client) &&
        dashstream->sidx_position != GST_CLOCK_TIME_NONE
        && SIDX (dashstream)->entries) {
      GstSidxBoxEntry *entry = SIDX_CURRENT_ENTRY (dashstream);
      dur = entry->duration;
    } else {
      dur = stream->fragment.duration;
    }

    if (dashstream->moof_sync_samples
        && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (dashdemux)) {
      /* We just downloaded the header, we actually use the previous
       * target_time now as it was not used up yet */
      if (dashstream->current_sync_sample == -1)
        target_time = dashstream->target_time;
      else
        target_time =
            gst_dash_demux_stream_get_target_time (dashdemux, stream,
            dashstream->actual_position, dur);
      dashstream->actual_position = target_time;
    } else {
      /* Adjust based on direction */
      if (stream->demux->segment.rate > 0.0)
        dashstream->actual_position += dur;
      else if (dashstream->actual_position >= dur)
        dashstream->actual_position -= dur;
      else
        dashstream->actual_position = 0;
    }

    GST_DEBUG_OBJECT (stream->pad, "Actual position %" GST_TIME_FORMAT,
        GST_TIME_ARGS (dashstream->actual_position));
  }
  dashstream->target_time = target_time;

  GST_DEBUG_OBJECT (stream->pad, "target_time: %" GST_TIME_FORMAT,
      GST_TIME_ARGS (target_time));

  /* If downloading only keyframes, switch to the next one or fall through */
  if (dashstream->moof_sync_samples &&
      GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (dashdemux)) {
    if (gst_dash_demux_stream_advance_sync_sample (stream, target_time))
      return GST_FLOW_OK;
  }

  dashstream->isobmff_parser.current_fourcc = 0;
  dashstream->isobmff_parser.current_start_offset = 0;
  dashstream->isobmff_parser.current_size = 0;

  if (dashstream->moof)
    gst_isoff_moof_box_free (dashstream->moof);
  dashstream->moof = NULL;
  if (dashstream->moof_sync_samples)
    g_array_free (dashstream->moof_sync_samples, TRUE);
  dashstream->moof_sync_samples = NULL;
  dashstream->current_sync_sample = -1;

  /* Check if we just need to 'advance' to the next fragment, or if we
   * need to skip by more. */
  if (GST_CLOCK_TIME_IS_VALID (target_time)
      && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (stream->demux) &&
      dashstream->active_stream->mimeType == GST_STREAM_VIDEO) {
    GstClockTime actual_ts;
    GstSeekFlags flags = 0;

    /* Key-unit trick mode, seek to fragment containing target time
     *
     * We first try seeking without snapping. As above code to skip keyframes
     * in the current fragment was not successful, we should go at least one
     * fragment ahead. Due to rounding errors we could end up at the same
     * fragment again here, in which case we retry seeking with the SNAP_AFTER
     * flag.
     *
     * We don't always set that flag as we would then end up one further
     * fragment in the future in all good cases.
     */
    while (TRUE) {
      ret =
          gst_dash_demux_stream_seek (stream, (stream->segment.rate > 0), flags,
          target_time, &actual_ts);

      if (ret != GST_FLOW_OK) {
        GST_WARNING_OBJECT (stream->pad, "Failed to seek to %" GST_TIME_FORMAT,
            GST_TIME_ARGS (target_time));
        /* Give up */
        if (flags != 0)
          break;

        /* Retry with skipping ahead */
        flags |= GST_SEEK_FLAG_SNAP_AFTER;
        continue;
      }

      GST_DEBUG_OBJECT (stream->pad,
          "Skipped to %" GST_TIME_FORMAT " (wanted %" GST_TIME_FORMAT ", was %"
          GST_TIME_FORMAT ")", GST_TIME_ARGS (actual_ts),
          GST_TIME_ARGS (target_time), GST_TIME_ARGS (previous_position));

      if ((stream->segment.rate > 0 && actual_ts <= previous_position) ||
          (stream->segment.rate < 0 && actual_ts >= previous_position)) {
        /* Give up */
        if (flags != 0)
          break;

        /* Retry with forcing skipping ahead */
        flags |= GST_SEEK_FLAG_SNAP_AFTER;

        continue;
      }

      /* All good */
      break;
    }
  } else {
    /* Normal mode, advance to the next fragment */
    if (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client)) {
      if (gst_dash_demux_stream_advance_subfragment (stream))
        return GST_FLOW_OK;
    }

    if (dashstream->adapter)
      gst_adapter_clear (dashstream->adapter);

    gst_isoff_sidx_parser_clear (&dashstream->sidx_parser);
    dashstream->sidx_base_offset = 0;
    dashstream->sidx_position = GST_CLOCK_TIME_NONE;
    dashstream->allow_sidx = TRUE;

    ret = gst_mpd_client_advance_segment (dashdemux->client,
        dashstream->active_stream, stream->demux->segment.rate > 0.0);
  }
  return ret;
}

static gboolean
gst_dash_demux_stream_select_bitrate (GstAdaptiveDemuxStream * stream,
    guint64 bitrate)
{
  GstActiveStream *active_stream = NULL;
  GList *rep_list = NULL;
  gint new_index;
  GstAdaptiveDemux *base_demux = stream->demux;
  GstDashDemux *demux = GST_DASH_DEMUX_CAST (stream->demux);
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  gboolean ret = FALSE;

  active_stream = dashstream->active_stream;
  if (active_stream == NULL) {
    goto end;
  }

  /* In key-frame trick mode don't change bitrates */
  if (GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (demux)) {
    GST_DEBUG_OBJECT (demux, "In key-frame trick mode, not changing bitrates");
    goto end;
  }

  /* retrieve representation list */
  if (active_stream->cur_adapt_set)
    rep_list = active_stream->cur_adapt_set->Representations;
  if (!rep_list) {
    goto end;
  }

  GST_DEBUG_OBJECT (stream->pad,
      "Trying to change to bitrate: %" G_GUINT64_FORMAT, bitrate);

  if (active_stream->mimeType == GST_STREAM_VIDEO && demux->max_bitrate) {
    bitrate = MIN (demux->max_bitrate, bitrate);
  }

  /* get representation index with current max_bandwidth */
  if (GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (base_demux) ||
      ABS (base_demux->segment.rate) <= 1.0) {
    new_index =
        gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list, bitrate,
        demux->max_video_width, demux->max_video_height,
        demux->max_video_framerate_n, demux->max_video_framerate_d);
  } else {
    new_index =
        gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list,
        bitrate / ABS (base_demux->segment.rate), demux->max_video_width,
        demux->max_video_height, demux->max_video_framerate_n,
        demux->max_video_framerate_d);
  }

  /* if no representation has the required bandwidth, take the lowest one */
  if (new_index == -1)
    new_index = gst_mpdparser_get_rep_idx_with_min_bandwidth (rep_list);

  if (new_index != active_stream->representation_idx) {
    GstRepresentationNode *rep = g_list_nth_data (rep_list, new_index);
    GST_INFO_OBJECT (demux, "Changing representation idx: %d %d %u",
        dashstream->index, new_index, rep->bandwidth);
    if (gst_mpd_client_setup_representation (demux->client, active_stream, rep)) {
      GstCaps *caps;

      GST_INFO_OBJECT (demux, "Switching bitrate to %d",
          active_stream->cur_representation->bandwidth);
      caps = gst_dash_demux_get_input_caps (demux, active_stream);
      gst_adaptive_demux_stream_set_caps (stream, caps);
      ret = TRUE;

    } else {
      GST_WARNING_OBJECT (demux, "Can not switch representation, aborting...");
    }
  }

  if (ret) {
    if (gst_mpd_client_has_isoff_ondemand_profile (demux->client)
        && SIDX (dashstream)->entries) {
      /* store our current position to change to the same one in a different
       * representation if needed */
      if (SIDX (dashstream)->entry_index < SIDX (dashstream)->entries_count)
        dashstream->sidx_position = SIDX_CURRENT_ENTRY (dashstream)->pts;
      else if (SIDX (dashstream)->entry_index >=
          SIDX (dashstream)->entries_count)
        dashstream->sidx_position =
            SIDX_ENTRY (dashstream,
            SIDX (dashstream)->entries_count - 1)->pts + SIDX_ENTRY (dashstream,
            SIDX (dashstream)->entries_count - 1)->duration;
      else
        dashstream->sidx_position = GST_CLOCK_TIME_NONE;
    } else {
      dashstream->sidx_position = GST_CLOCK_TIME_NONE;
    }

    gst_isoff_sidx_parser_clear (&dashstream->sidx_parser);
    dashstream->sidx_base_offset = 0;
    dashstream->allow_sidx = TRUE;

    /* Reset ISOBMFF box parsing state */
    dashstream->isobmff_parser.current_fourcc = 0;
    dashstream->isobmff_parser.current_start_offset = 0;
    dashstream->isobmff_parser.current_size = 0;

    dashstream->current_offset = -1;
    dashstream->current_index_header_or_data = 0;

    if (dashstream->adapter)
      gst_adapter_clear (dashstream->adapter);

    if (dashstream->moof)
      gst_isoff_moof_box_free (dashstream->moof);
    dashstream->moof = NULL;
    if (dashstream->moof_sync_samples)
      g_array_free (dashstream->moof_sync_samples, TRUE);
    dashstream->moof_sync_samples = NULL;
    dashstream->current_sync_sample = -1;
    dashstream->target_time = GST_CLOCK_TIME_NONE;
  }

end:
  return ret;
}

#define SEEK_UPDATES_PLAY_POSITION(r, start_type, stop_type) \
  ((r >= 0 && start_type != GST_SEEK_TYPE_NONE) || \
   (r < 0 && stop_type != GST_SEEK_TYPE_NONE))

static gboolean
gst_dash_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
{
  gdouble rate;
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  gint64 start, stop;
  GList *list;
  GstClockTime current_pos, target_pos;
  guint current_period;
  GstStreamPeriod *period;
  GList *iter, *streams = NULL;
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
  gboolean trickmode_no_audio;

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

  if (!SEEK_UPDATES_PLAY_POSITION (rate, start_type, stop_type)) {
    /* nothing to do if we don't have to update the current position */
    return TRUE;
  }

  if (demux->segment.rate > 0.0) {
    target_pos = (GstClockTime) start;
  } else {
    target_pos = (GstClockTime) stop;
  }

  /* select the requested Period in the Media Presentation */
  if (!gst_mpd_client_setup_media_presentation (dashdemux->client, target_pos,
          -1, NULL))
    return FALSE;

  current_period = 0;
  for (list = g_list_first (dashdemux->client->periods); list;
      list = g_list_next (list)) {
    period = list->data;
    current_pos = period->start;
    current_period = period->number;
    GST_DEBUG_OBJECT (demux, "Looking at period %u) start:%"
        GST_TIME_FORMAT " - duration:%"
        GST_TIME_FORMAT ") for position %" GST_TIME_FORMAT,
        current_period, GST_TIME_ARGS (current_pos),
        GST_TIME_ARGS (period->duration), GST_TIME_ARGS (target_pos));
    if (current_pos <= target_pos
        && target_pos <= current_pos + period->duration) {
      break;
    }
  }
  if (list == NULL) {
    GST_WARNING_OBJECT (demux, "Could not find seeked Period");
    return FALSE;
  }

  trickmode_no_audio = ! !(flags & GST_SEEK_FLAG_TRICKMODE_NO_AUDIO);

  streams = demux->streams;
  if (current_period != gst_mpd_client_get_period_index (dashdemux->client)) {
    GST_DEBUG_OBJECT (demux, "Seeking to Period %d", current_period);

    /* clean old active stream list, if any */
    gst_active_streams_free (dashdemux->client);
    dashdemux->trickmode_no_audio = trickmode_no_audio;

    /* setup video, audio and subtitle streams, starting from the new Period */
    if (!gst_mpd_client_set_period_index (dashdemux->client, current_period)
        || !gst_dash_demux_setup_all_streams (dashdemux))
      return FALSE;
    streams = demux->next_streams;
  } else if (dashdemux->trickmode_no_audio != trickmode_no_audio) {
    /* clean old active stream list, if any */
    gst_active_streams_free (dashdemux->client);
    dashdemux->trickmode_no_audio = trickmode_no_audio;

    /* setup video, audio and subtitle streams, starting from the new Period */
    if (!gst_dash_demux_setup_all_streams (dashdemux))
      return FALSE;
    streams = demux->next_streams;
  }

  /* Update the current sequence on all streams */
  for (iter = streams; iter; iter = g_list_next (iter)) {
    GstAdaptiveDemuxStream *stream = iter->data;
    GstDashDemuxStream *dashstream = iter->data;

    dashstream->average_skip_size = 0;
    if (gst_dash_demux_stream_seek (stream, rate >= 0, 0, target_pos,
            NULL) != GST_FLOW_OK)
      return FALSE;
  }

  return TRUE;
}

static gint64
gst_dash_demux_get_manifest_update_interval (GstAdaptiveDemux * demux)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
  return MIN (dashdemux->client->mpd_node->minimumUpdatePeriod * 1000,
      SLOW_CLOCK_UPDATE_INTERVAL);
}

static GstFlowReturn
gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux,
    GstBuffer * buffer)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
  GstMpdClient *new_client = NULL;
  GstMapInfo mapinfo;

  GST_DEBUG_OBJECT (demux, "Updating manifest file from URL");

  /* parse the manifest file */
  new_client = gst_mpd_client_new ();
  gst_mpd_client_set_uri_downloader (new_client, demux->downloader);
  new_client->mpd_uri = g_strdup (demux->manifest_uri);
  new_client->mpd_base_uri = g_strdup (demux->manifest_base_uri);
  gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);

  if (gst_mpd_parse (new_client, (gchar *) mapinfo.data, mapinfo.size)) {
    const gchar *period_id;
    guint period_idx;
    GList *iter;
    GList *streams_iter;
    GList *streams;

    /* prepare the new manifest and try to transfer the stream position
     * status from the old manifest client  */

    GST_DEBUG_OBJECT (demux, "Updating manifest");

    period_id = gst_mpd_client_get_period_id (dashdemux->client);
    period_idx = gst_mpd_client_get_period_index (dashdemux->client);

    /* setup video, audio and subtitle streams, starting from current Period */
    if (!gst_mpd_client_setup_media_presentation (new_client, -1,
            (period_id ? -1 : period_idx), period_id)) {
      /* TODO */
    }

    if (period_id) {
      if (!gst_mpd_client_set_period_id (new_client, period_id)) {
        GST_DEBUG_OBJECT (demux, "Error setting up the updated manifest file");
        gst_mpd_client_free (new_client);
        gst_buffer_unmap (buffer, &mapinfo);
        return GST_FLOW_EOS;
      }
    } else {
      if (!gst_mpd_client_set_period_index (new_client, period_idx)) {
        GST_DEBUG_OBJECT (demux, "Error setting up the updated manifest file");
        gst_mpd_client_free (new_client);
        gst_buffer_unmap (buffer, &mapinfo);
        return GST_FLOW_EOS;
      }
    }

    if (!gst_dash_demux_setup_mpdparser_streams (dashdemux, new_client)) {
      GST_ERROR_OBJECT (demux, "Failed to setup streams on manifest " "update");
      gst_mpd_client_free (new_client);
      gst_buffer_unmap (buffer, &mapinfo);
      return GST_FLOW_ERROR;
    }

    /* If no pads have been exposed yet, need to use those */
    streams = NULL;
    if (demux->streams == NULL) {
      if (demux->prepared_streams) {
        streams = demux->prepared_streams;
      }
    } else {
      streams = demux->streams;
    }

    /* update the streams to play from the next segment */
    for (iter = streams, streams_iter = new_client->active_streams;
        iter && streams_iter;
        iter = g_list_next (iter), streams_iter = g_list_next (streams_iter)) {
      GstDashDemuxStream *demux_stream = iter->data;
      GstActiveStream *new_stream = streams_iter->data;
      GstClockTime ts;

      if (!new_stream) {
        GST_DEBUG_OBJECT (demux,
            "Stream of index %d is missing from manifest update",
            demux_stream->index);
        gst_mpd_client_free (new_client);
        gst_buffer_unmap (buffer, &mapinfo);
        return GST_FLOW_EOS;
      }

      if (gst_mpd_client_get_next_fragment_timestamp (dashdemux->client,
              demux_stream->index, &ts)
          || gst_mpd_client_get_last_fragment_timestamp_end (dashdemux->client,
              demux_stream->index, &ts)) {

        /* Due to rounding when doing the timescale conversions it might happen
         * that the ts falls back to a previous segment, leading the same data
         * to be downloaded twice. We try to work around this by always adding
         * 10 microseconds to get back to the correct segment. The errors are
         * usually on the order of nanoseconds so it should be enough.
         */

        /* _get_next_fragment_timestamp() returned relative timestamp to
         * corresponding period start, but _client_stream_seek expects absolute
         * MPD time. */
        ts += gst_mpd_parser_get_period_start_time (dashdemux->client);

        GST_DEBUG_OBJECT (GST_ADAPTIVE_DEMUX_STREAM_PAD (demux_stream),
            "Current position: %" GST_TIME_FORMAT ", updating to %"
            GST_TIME_FORMAT, GST_TIME_ARGS (ts),
            GST_TIME_ARGS (ts + (10 * GST_USECOND)));
        ts += 10 * GST_USECOND;
        gst_mpd_client_stream_seek (new_client, new_stream,
            demux->segment.rate >= 0, 0, ts, NULL);
      }

      demux_stream->active_stream = new_stream;
    }

    gst_mpd_client_free (dashdemux->client);
    dashdemux->client = new_client;

    GST_DEBUG_OBJECT (demux, "Manifest file successfully updated");
    if (dashdemux->clock_drift) {
      gst_dash_demux_poll_clock_drift (dashdemux);
    }
  } else {
    /* 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_WARNING_OBJECT (demux, "Error parsing the manifest.");
    gst_mpd_client_free (new_client);
    gst_buffer_unmap (buffer, &mapinfo);
    return GST_FLOW_ERROR;
  }

  gst_buffer_unmap (buffer, &mapinfo);

  return GST_FLOW_OK;
}

static gint64
gst_dash_demux_stream_get_fragment_waiting_time (GstAdaptiveDemuxStream *
    stream)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (stream->demux);
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
  GstDateTime *segmentAvailability;
  GstActiveStream *active_stream = dashstream->active_stream;

  segmentAvailability =
      gst_mpd_client_get_next_segment_availability_start_time
      (dashdemux->client, active_stream);

  if (segmentAvailability) {
    gint64 diff;
    GstDateTime *cur_time;

    cur_time =
        gst_date_time_new_from_g_date_time
        (gst_adaptive_demux_get_client_now_utc (GST_ADAPTIVE_DEMUX_CAST
            (dashdemux)));
    diff =
        gst_mpd_client_calculate_time_difference (cur_time,
        segmentAvailability);
    gst_date_time_unref (segmentAvailability);
    gst_date_time_unref (cur_time);
    /* subtract the server's clock drift, so that if the server's
       time is behind our idea of UTC, we need to sleep for longer
       before requesting a fragment */
    return diff -
        gst_dash_demux_get_clock_compensation (dashdemux) * GST_USECOND;
  }
  return 0;
}

static gboolean
gst_dash_demux_has_next_period (GstAdaptiveDemux * demux)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);

  if (demux->segment.rate >= 0)
    return gst_mpd_client_has_next_period (dashdemux->client);
  else
    return gst_mpd_client_has_previous_period (dashdemux->client);
}

static void
gst_dash_demux_advance_period (GstAdaptiveDemux * demux)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);

  if (demux->segment.rate >= 0) {
    if (!gst_mpd_client_set_period_index (dashdemux->client,
            gst_mpd_client_get_period_index (dashdemux->client) + 1)) {
      /* TODO error */
      return;
    }
  } else {
    if (!gst_mpd_client_set_period_index (dashdemux->client,
            gst_mpd_client_get_period_index (dashdemux->client) - 1)) {
      /* TODO error */
      return;
    }
  }

  gst_dash_demux_setup_all_streams (dashdemux);
  gst_mpd_client_seek_to_first_segment (dashdemux->client);
}

static GstBuffer *
_gst_buffer_split (GstBuffer * buffer, gint offset, gsize size)
{
  GstBuffer *newbuf = gst_buffer_copy_region (buffer,
      GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_META
      | GST_BUFFER_COPY_MEMORY, offset, size == -1 ? size : size - offset);

  gst_buffer_resize (buffer, 0, offset);

  return newbuf;
}

static gboolean
gst_dash_demux_stream_fragment_start (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;

  GST_LOG_OBJECT (stream->pad, "Actual position %" GST_TIME_FORMAT,
      GST_TIME_ARGS (dashstream->actual_position));

  dashstream->current_index_header_or_data = 0;
  dashstream->current_offset = -1;

  /* We need to mark every first buffer of a key unit as discont,
   * and also every first buffer of a moov and moof. This ensures
   * that qtdemux takes note of our buffer offsets for each of those
   * buffers instead of keeping track of them itself from the first
   * buffer. We need offsets to be consistent between moof and mdat
   */
  if (dashstream->is_isobmff && dashdemux->allow_trickmode_key_units
      && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (demux)
      && dashstream->active_stream->mimeType == GST_STREAM_VIDEO)
    stream->discont = TRUE;

  return TRUE;
}

static GstFlowReturn
gst_dash_demux_stream_fragment_finished (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;

  /* We need to mark every first buffer of a key unit as discont,
   * and also every first buffer of a moov and moof. This ensures
   * that qtdemux takes note of our buffer offsets for each of those
   * buffers instead of keeping track of them itself from the first
   * buffer. We need offsets to be consistent between moof and mdat
   */
  if (dashstream->is_isobmff && dashdemux->allow_trickmode_key_units
      && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (demux)
      && dashstream->active_stream->mimeType == GST_STREAM_VIDEO)
    stream->discont = TRUE;

  /* Only handle fragment advancing specifically for SIDX if we're not
   * in key unit mode */
  if (!(dashstream->moof_sync_samples
          && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (dashdemux))
      && gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client)
      && dashstream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
    /* fragment is advanced on data_received when byte limits are reached */
    if (dashstream->pending_seek_ts != GST_CLOCK_TIME_NONE) {
      if (SIDX (dashstream)->entry_index < SIDX (dashstream)->entries_count)
        return GST_FLOW_OK;
    } else if (gst_dash_demux_stream_has_next_subfragment (stream)) {
      return GST_FLOW_OK;
    }
  }

  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);
}

static gboolean
gst_dash_demux_need_another_chunk (GstAdaptiveDemuxStream * stream)
{
  GstDashDemux *dashdemux = (GstDashDemux *) stream->demux;
  GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;

  /* We're chunked downloading for ISOBMFF in KEY_UNITS mode for the actual
   * fragment until we parsed the moof and arrived at the mdat. 8192 is a
   * random guess for the moof size
   */
  if (dashstream->is_isobmff
      && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (stream->demux)
      && dashstream->active_stream->mimeType == GST_STREAM_VIDEO
      && !stream->downloading_header && !stream->downloading_index
      && dashdemux->allow_trickmode_key_units) {
    if (dashstream->isobmff_parser.current_fourcc != GST_ISOFF_FOURCC_MDAT) {
      /* Need to download the moof first to know anything */

      stream->fragment.chunk_size = 8192;
      /* Do we have the first fourcc already or are we in the middle */
      if (dashstream->isobmff_parser.current_fourcc == 0) {
        stream->fragment.chunk_size += dashstream->moof_average_size;
        if (dashstream->first_sync_sample_always_after_moof) {
          gboolean first = FALSE;
          /* Check if we'll really need that first sample */
          if (GST_CLOCK_TIME_IS_VALID (dashstream->target_time)) {
            first =
                ((dashstream->target_time -
                    dashstream->current_fragment_timestamp) /
                dashstream->keyframe_average_distance) == 0 ? TRUE : FALSE;
          } else if (stream->segment.rate > 0) {
            first = TRUE;
          }

          if (first)
            stream->fragment.chunk_size += dashstream->keyframe_average_size;
        }
      }

      if (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client) &&
          dashstream->sidx_parser.sidx.entries) {
        guint64 sidx_start_offset =
            dashstream->sidx_base_offset +
            SIDX_CURRENT_ENTRY (dashstream)->offset;
        guint64 sidx_end_offset =
            sidx_start_offset + SIDX_CURRENT_ENTRY (dashstream)->size;
        guint64 downloaded_end_offset;

        if (dashstream->current_offset == GST_CLOCK_TIME_NONE) {
          downloaded_end_offset = sidx_start_offset;
        } else {
          downloaded_end_offset =
              dashstream->current_offset +
              gst_adapter_available (dashstream->adapter);
        }

        downloaded_end_offset = MAX (downloaded_end_offset, sidx_start_offset);

        if (stream->fragment.chunk_size +
            downloaded_end_offset > sidx_end_offset) {
          stream->fragment.chunk_size = sidx_end_offset - downloaded_end_offset;
        }
      }
    } else if (dashstream->moof && dashstream->moof_sync_samples) {
      /* Have the moof, either we're done now or we want to download the
       * directly following sync sample */
      if (dashstream->first_sync_sample_after_moof
          && dashstream->current_sync_sample == 0) {
        GstDashStreamSyncSample *sync_sample =
            &g_array_index (dashstream->moof_sync_samples,
            GstDashStreamSyncSample, 0);
        guint64 end_offset = sync_sample->end_offset + 1;
        guint64 downloaded_end_offset;

        downloaded_end_offset =
            dashstream->current_offset +
            gst_adapter_available (dashstream->adapter);

        if (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client) &&
            dashstream->sidx_parser.sidx.entries) {
          guint64 sidx_end_offset =
              dashstream->sidx_base_offset +
              SIDX_CURRENT_ENTRY (dashstream)->offset +
              SIDX_CURRENT_ENTRY (dashstream)->size;

          if (end_offset > sidx_end_offset) {
            end_offset = sidx_end_offset;
          }
        }

        if (downloaded_end_offset < end_offset) {
          stream->fragment.chunk_size = end_offset - downloaded_end_offset;
        } else {
          stream->fragment.chunk_size = 0;
        }
      } else {
        stream->fragment.chunk_size = 0;
      }
    } else {
      /* Have moof but can't do key-units mode, just download until the end */
      stream->fragment.chunk_size = -1;
    }
  } else {
    /* We might've decided that we can't allow key-unit only
     * trickmodes while doing chunked downloading. In that case
     * just download from here to the end now */
    if (dashstream->moof
        && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (stream->demux)) {
      stream->fragment.chunk_size = -1;
    } else {
      stream->fragment.chunk_size = 0;
    }
  }

  return stream->fragment.chunk_size != 0;
}

static GstFlowReturn
gst_dash_demux_parse_isobmff (GstAdaptiveDemux * demux,
    GstDashDemuxStream * dash_stream, gboolean * sidx_seek_needed)
{
  GstAdaptiveDemuxStream *stream = (GstAdaptiveDemuxStream *) dash_stream;
  GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
  gsize available;
  GstBuffer *buffer;
  GstMapInfo map;
  GstByteReader reader;
  guint32 fourcc;
  guint header_size;
  guint64 size, buffer_offset;

  *sidx_seek_needed = FALSE;

  /* This must not be called when we're in the mdat. We only look at the mdat
   * header and then stop parsing the boxes as we're only interested in the
   * metadata! Handling mdat is the job of the surrounding code, as well as
   * stopping or starting the next fragment when mdat is over (=> sidx)
   */
  g_assert (dash_stream->isobmff_parser.current_fourcc !=
      GST_ISOFF_FOURCC_MDAT);

  available = gst_adapter_available (dash_stream->adapter);
  buffer = gst_adapter_take_buffer (dash_stream->adapter, available);
  buffer_offset = dash_stream->current_offset;

  /* Always at the start of a box here */
  g_assert (dash_stream->isobmff_parser.current_size == 0);

  /* At the start of a box => Parse it */
  gst_buffer_map (buffer, &map, GST_MAP_READ);
  gst_byte_reader_init (&reader, map.data, map.size);

  /* While there are more boxes left to parse ... */
  dash_stream->isobmff_parser.current_start_offset = buffer_offset;
  do {
    dash_stream->isobmff_parser.current_fourcc = 0;
    dash_stream->isobmff_parser.current_size = 0;

    if (!gst_isoff_parse_box_header (&reader, &fourcc, NULL, &header_size,
            &size)) {
      break;
    }

    dash_stream->isobmff_parser.current_fourcc = fourcc;
    if (size == 0) {
      /* We assume this is mdat, anything else with "size until end"
       * does not seem to make sense */
      g_assert (dash_stream->isobmff_parser.current_fourcc ==
          GST_ISOFF_FOURCC_MDAT);
      dash_stream->isobmff_parser.current_size = -1;
      break;
    }

    dash_stream->isobmff_parser.current_size = size;

    /* Do we have the complete box or are at MDAT */
    if (gst_byte_reader_get_remaining (&reader) < size - header_size ||
        dash_stream->isobmff_parser.current_fourcc == GST_ISOFF_FOURCC_MDAT) {
      /* Reset byte reader to the beginning of the box */
      gst_byte_reader_set_pos (&reader,
          gst_byte_reader_get_pos (&reader) - header_size);
      break;
    }

    GST_LOG_OBJECT (stream->pad,
        "box %" GST_FOURCC_FORMAT " at offset %" G_GUINT64_FORMAT " size %"
        G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc),
        dash_stream->isobmff_parser.current_start_offset, size);

    if (dash_stream->isobmff_parser.current_fourcc == GST_ISOFF_FOURCC_MOOF) {
      GstByteReader sub_reader;

      /* Only allow SIDX before the very first moof */
      dash_stream->allow_sidx = FALSE;

      g_assert (dash_stream->moof == NULL);
      g_assert (dash_stream->moof_sync_samples == NULL);
      gst_byte_reader_get_sub_reader (&reader, &sub_reader, size - header_size);
      dash_stream->moof = gst_isoff_moof_box_parse (&sub_reader);
      dash_stream->moof_offset =
          dash_stream->isobmff_parser.current_start_offset;
      dash_stream->moof_size = size;
      dash_stream->current_sync_sample = -1;

      if (dash_stream->moof_average_size) {
        if (dash_stream->moof_average_size < size)
          dash_stream->moof_average_size =
              (size * 3 + dash_stream->moof_average_size) / 4;
        else
          dash_stream->moof_average_size =
              (size + dash_stream->moof_average_size + 3) / 4;
      } else {
        dash_stream->moof_average_size = size;
      }
    } else if (dash_stream->isobmff_parser.current_fourcc ==
        GST_ISOFF_FOURCC_SIDX &&
        gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client) &&
        dash_stream->allow_sidx) {
      GstByteReader sub_reader;
      GstIsoffParserResult res;
      guint dummy;

      dash_stream->sidx_base_offset =
          dash_stream->isobmff_parser.current_start_offset + size;
      dash_stream->allow_sidx = FALSE;

      gst_byte_reader_get_sub_reader (&reader, &sub_reader, size - header_size);

      res =
          gst_isoff_sidx_parser_parse (&dash_stream->sidx_parser, &sub_reader,
          &dummy);

      if (res == GST_ISOFF_PARSER_DONE) {
        guint64 first_offset = dash_stream->sidx_parser.sidx.first_offset;
        GstSidxBox *sidx = SIDX (dash_stream);
        guint i;

        if (first_offset) {
          GST_LOG_OBJECT (stream->pad,
              "non-zero sidx first offset %" G_GUINT64_FORMAT, first_offset);
          dash_stream->sidx_base_offset += first_offset;
        }

        for (i = 0; i < sidx->entries_count; i++) {
          GstSidxBoxEntry *entry = &sidx->entries[i];

          if (entry->ref_type != 0) {
            GST_FIXME_OBJECT (stream->pad, "SIDX ref_type 1 not supported yet");
            dash_stream->sidx_position = GST_CLOCK_TIME_NONE;
            gst_isoff_sidx_parser_clear (&dash_stream->sidx_parser);
            break;
          }
        }

        /* We might've cleared the index above */
        if (sidx->entries_count > 0) {
          if (GST_CLOCK_TIME_IS_VALID (dash_stream->pending_seek_ts)) {
            /* FIXME, preserve seek flags */
            if (gst_dash_demux_stream_sidx_seek (dash_stream,
                    demux->segment.rate >= 0, 0, dash_stream->pending_seek_ts,
                    NULL) != GST_FLOW_OK) {
              GST_ERROR_OBJECT (stream->pad, "Couldn't find position in sidx");
              dash_stream->sidx_position = GST_CLOCK_TIME_NONE;
              gst_isoff_sidx_parser_clear (&dash_stream->sidx_parser);
            }
            dash_stream->pending_seek_ts = GST_CLOCK_TIME_NONE;
          } else {

            if (dash_stream->sidx_position == GST_CLOCK_TIME_NONE) {
              SIDX (dash_stream)->entry_index = 0;
            } else {
              if (gst_dash_demux_stream_sidx_seek (dash_stream,
                      demux->segment.rate >= 0, GST_SEEK_FLAG_SNAP_BEFORE,
                      dash_stream->sidx_position, NULL) != GST_FLOW_OK) {
                GST_ERROR_OBJECT (stream->pad,
                    "Couldn't find position in sidx");
                dash_stream->sidx_position = GST_CLOCK_TIME_NONE;
                gst_isoff_sidx_parser_clear (&dash_stream->sidx_parser);
              }
            }
            dash_stream->sidx_position =
                SIDX (dash_stream)->entries[SIDX (dash_stream)->
                entry_index].pts;
          }
        }

        if (dash_stream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED &&
            SIDX (dash_stream)->entry_index != 0) {
          /* Need to jump to the requested SIDX entry. Push everything up to
           * the SIDX box below and let the caller handle everything else */
          *sidx_seek_needed = TRUE;
          break;
        }
      }
    } else {
      gst_byte_reader_skip (&reader, size - header_size);
    }

    dash_stream->isobmff_parser.current_fourcc = 0;
    dash_stream->isobmff_parser.current_start_offset += size;
    dash_stream->isobmff_parser.current_size = 0;
  } while (gst_byte_reader_get_remaining (&reader) > 0);

  gst_buffer_unmap (buffer, &map);

  /* mdat? Push all we have and wait for it to be over */
  if (dash_stream->isobmff_parser.current_fourcc == GST_ISOFF_FOURCC_MDAT) {
    GstBuffer *pending;

    GST_LOG_OBJECT (stream->pad,
        "box %" GST_FOURCC_FORMAT " at offset %" G_GUINT64_FORMAT " size %"
        G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc),
        dash_stream->isobmff_parser.current_start_offset,
        dash_stream->isobmff_parser.current_size);

    /* At mdat. Move the start of the mdat to the adapter and have everything
     * else be pushed. We parsed all header boxes at this point and are not
     * supposed to be called again until the next moof */
    pending = _gst_buffer_split (buffer, gst_byte_reader_get_pos (&reader), -1);
    gst_adapter_push (dash_stream->adapter, pending);
    dash_stream->current_offset += gst_byte_reader_get_pos (&reader);
    dash_stream->isobmff_parser.current_size = 0;

    GST_BUFFER_OFFSET (buffer) = buffer_offset;
    GST_BUFFER_OFFSET_END (buffer) =
        buffer_offset + gst_buffer_get_size (buffer);
    return gst_adaptive_demux_stream_push_buffer (stream, buffer);
  } else if (gst_byte_reader_get_pos (&reader) != 0) {
    GstBuffer *pending;

    /* Multiple complete boxes and no mdat? Push them and keep the remainder,
     * which is the start of the next box if any remainder */

    pending = _gst_buffer_split (buffer, gst_byte_reader_get_pos (&reader), -1);
    gst_adapter_push (dash_stream->adapter, pending);
    dash_stream->current_offset += gst_byte_reader_get_pos (&reader);
    dash_stream->isobmff_parser.current_size = 0;

    GST_BUFFER_OFFSET (buffer) = buffer_offset;
    GST_BUFFER_OFFSET_END (buffer) =
        buffer_offset + gst_buffer_get_size (buffer);
    return gst_adaptive_demux_stream_push_buffer (stream, buffer);
  }

  /* Not even a single complete, non-mdat box, wait */
  dash_stream->isobmff_parser.current_size = 0;
  gst_adapter_push (dash_stream->adapter, buffer);

  return GST_FLOW_OK;
}

static gboolean
gst_dash_demux_find_sync_samples (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstDashDemux *dashdemux = (GstDashDemux *) stream->demux;
  GstDashDemuxStream *dash_stream = (GstDashDemuxStream *) stream;
  guint i;
  guint32 track_id = 0;
  guint64 prev_traf_end;
  gboolean trex_sample_flags = FALSE;

  if (!dash_stream->moof) {
    dashdemux->allow_trickmode_key_units = FALSE;
    return FALSE;
  }

  dash_stream->current_sync_sample = -1;
  dash_stream->moof_sync_samples =
      g_array_new (FALSE, FALSE, sizeof (GstDashStreamSyncSample));

  prev_traf_end = dash_stream->moof_offset;

  /* generate table of keyframes and offsets */
  for (i = 0; i < dash_stream->moof->traf->len; i++) {
    GstTrafBox *traf = &g_array_index (dash_stream->moof->traf, GstTrafBox, i);
    guint64 traf_offset = 0, prev_trun_end;
    guint j;

    if (i == 0) {
      track_id = traf->tfhd.track_id;
    } else if (track_id != traf->tfhd.track_id) {
      GST_ERROR_OBJECT (stream->pad,
          "moof with trafs of different track ids (%u != %u)", track_id,
          traf->tfhd.track_id);
      g_array_free (dash_stream->moof_sync_samples, TRUE);
      dash_stream->moof_sync_samples = NULL;
      dashdemux->allow_trickmode_key_units = FALSE;
      return FALSE;
    }

    if (traf->tfhd.flags & GST_TFHD_FLAGS_BASE_DATA_OFFSET_PRESENT) {
      traf_offset = traf->tfhd.base_data_offset;
    } else if (traf->tfhd.flags & GST_TFHD_FLAGS_DEFAULT_BASE_IS_MOOF) {
      traf_offset = dash_stream->moof_offset;
    } else {
      traf_offset = prev_traf_end;
    }

    prev_trun_end = traf_offset;

    for (j = 0; j < traf->trun->len; j++) {
      GstTrunBox *trun = &g_array_index (traf->trun, GstTrunBox, j);
      guint64 trun_offset, prev_sample_end;
      guint k;

      if (trun->flags & GST_TRUN_FLAGS_DATA_OFFSET_PRESENT) {
        trun_offset = traf_offset + trun->data_offset;
      } else {
        trun_offset = prev_trun_end;
      }

      prev_sample_end = trun_offset;
      for (k = 0; k < trun->samples->len; k++) {
        GstTrunSample *sample =
            &g_array_index (trun->samples, GstTrunSample, k);
        guint64 sample_offset;
        guint32 sample_flags;
#if 0
        guint32 sample_duration;
#endif

        sample_offset = prev_sample_end;

        if (trun->flags & GST_TRUN_FLAGS_SAMPLE_FLAGS_PRESENT) {
          sample_flags = sample->sample_flags;
        } else if ((trun->flags & GST_TRUN_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT)
            && k == 0) {
          sample_flags = trun->first_sample_flags;
        } else if (traf->
            tfhd.flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT) {
          sample_flags = traf->tfhd.default_sample_flags;
        } else {
          trex_sample_flags = TRUE;
          continue;
        }

#if 0
        if (trun->flags & GST_TRUN_FLAGS_SAMPLE_DURATION_PRESENT) {
          sample_duration = sample->sample_duration;
        } else if (traf->
            tfhd.flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT) {
          sample_duration = traf->tfhd.default_sample_duration;
        } else {
          GST_FIXME_OBJECT (stream->pad,
              "Sample duration given by trex - can't download only keyframes");
          g_array_free (dash_stream->moof_sync_samples, TRUE);
          dash_stream->moof_sync_samples = NULL;
          return FALSE;
        }
#endif

        if (trun->flags & GST_TRUN_FLAGS_SAMPLE_SIZE_PRESENT) {
          prev_sample_end += sample->sample_size;
        } else if (traf->
            tfhd.flags & GST_TFHD_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT) {
          prev_sample_end += traf->tfhd.default_sample_size;
        } else {
          GST_FIXME_OBJECT (stream->pad,
              "Sample size given by trex - can't download only keyframes");
          g_array_free (dash_stream->moof_sync_samples, TRUE);
          dash_stream->moof_sync_samples = NULL;
          dashdemux->allow_trickmode_key_units = FALSE;
          return FALSE;
        }

        /* Non-non-sync sample aka sync sample */
        if (!GST_ISOFF_SAMPLE_FLAGS_SAMPLE_IS_NON_SYNC_SAMPLE (sample_flags) ||
            GST_ISOFF_SAMPLE_FLAGS_SAMPLE_DEPENDS_ON (sample_flags) == 2) {
          GstDashStreamSyncSample sync_sample =
              { sample_offset, prev_sample_end - 1 };
          /* TODO: need timestamps so we can decide to download or not */
          g_array_append_val (dash_stream->moof_sync_samples, sync_sample);
        }
      }

      prev_trun_end = prev_sample_end;
    }

    prev_traf_end = prev_trun_end;
  }

  if (trex_sample_flags) {
    if (dash_stream->moof_sync_samples->len > 0) {
      GST_LOG_OBJECT (stream->pad,
          "Some sample flags given by trex but still found sync samples");
    } else {
      GST_FIXME_OBJECT (stream->pad,
          "Sample flags given by trex - can't download only keyframes");
      g_array_free (dash_stream->moof_sync_samples, TRUE);
      dash_stream->moof_sync_samples = NULL;
      dashdemux->allow_trickmode_key_units = FALSE;
      return FALSE;
    }
  }

  if (dash_stream->moof_sync_samples->len == 0) {
    GST_LOG_OBJECT (stream->pad, "No sync samples found in fragment");
    g_array_free (dash_stream->moof_sync_samples, TRUE);
    dash_stream->moof_sync_samples = NULL;
    dashdemux->allow_trickmode_key_units = FALSE;
    return FALSE;
  }

  {
    GstDashStreamSyncSample *sync_sample;
    guint i;
    guint size;
    GstClockTime current_keyframe_distance;

    for (i = 0; i < dash_stream->moof_sync_samples->len; i++) {
      sync_sample =
          &g_array_index (dash_stream->moof_sync_samples,
          GstDashStreamSyncSample, i);
      size = sync_sample->end_offset + 1 - sync_sample->start_offset;

      if (dash_stream->keyframe_average_size) {
        /* Over-estimate the keyframe size */
        if (dash_stream->keyframe_average_size < size)
          dash_stream->keyframe_average_size =
              (size * 3 + dash_stream->keyframe_average_size) / 4;
        else
          dash_stream->keyframe_average_size =
              (size + dash_stream->keyframe_average_size * 3) / 4;
      } else {
        dash_stream->keyframe_average_size = size;
      }

      if (i == 0) {
        if (dash_stream->moof_offset + dash_stream->moof_size + 8 <
            sync_sample->start_offset) {
          dash_stream->first_sync_sample_after_moof = FALSE;
          dash_stream->first_sync_sample_always_after_moof = FALSE;
        } else {
          dash_stream->first_sync_sample_after_moof =
              (dash_stream->moof_sync_samples->len == 1
              || demux->segment.rate > 0.0);
        }
      }
    }

    g_assert (stream->fragment.duration != 0);
    g_assert (stream->fragment.duration != GST_CLOCK_TIME_NONE);

    if (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client)
        && dash_stream->sidx_position != GST_CLOCK_TIME_NONE
        && SIDX (dash_stream)->entries) {
      GstSidxBoxEntry *entry = SIDX_CURRENT_ENTRY (dash_stream);
      current_keyframe_distance =
          entry->duration / dash_stream->moof_sync_samples->len;
    } else {
      current_keyframe_distance =
          stream->fragment.duration / dash_stream->moof_sync_samples->len;
    }
    dash_stream->current_fragment_keyframe_distance = current_keyframe_distance;

    if (dash_stream->keyframe_average_distance) {
      /* Under-estimate the keyframe distance */
      if (dash_stream->keyframe_average_distance > current_keyframe_distance)
        dash_stream->keyframe_average_distance =
            (dash_stream->keyframe_average_distance * 3 +
            current_keyframe_distance) / 4;
      else
        dash_stream->keyframe_average_distance =
            (dash_stream->keyframe_average_distance +
            current_keyframe_distance * 3) / 4;
    } else {
      dash_stream->keyframe_average_distance = current_keyframe_distance;
    }

    GST_DEBUG_OBJECT (stream->pad,
        "average keyframe sample size: %" G_GUINT64_FORMAT,
        dash_stream->keyframe_average_size);
    GST_DEBUG_OBJECT (stream->pad,
        "average keyframe distance: %" GST_TIME_FORMAT " (%" GST_TIME_FORMAT
        ")", GST_TIME_ARGS (dash_stream->keyframe_average_distance),
        GST_TIME_ARGS (current_keyframe_distance));
    GST_DEBUG_OBJECT (stream->pad, "first sync sample after moof: %d",
        dash_stream->first_sync_sample_after_moof);
  }

  return TRUE;
}


static GstFlowReturn
gst_dash_demux_handle_isobmff (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dash_stream = (GstDashDemuxStream *) stream;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *buffer;
  gboolean sidx_advance = FALSE;

  /* We parse all ISOBMFF boxes of a (sub)fragment until the mdat. This covers
   * at least moov, moof and sidx boxes. Once mdat is received we just output
   * everything until the next (sub)fragment */
  if (dash_stream->isobmff_parser.current_fourcc != GST_ISOFF_FOURCC_MDAT) {
    gboolean sidx_seek_needed = FALSE;

    ret = gst_dash_demux_parse_isobmff (demux, dash_stream, &sidx_seek_needed);
    if (ret != GST_FLOW_OK)
      return ret;

    /* Go to selected segment if needed here */
    if (sidx_seek_needed && !stream->downloading_index)
      return GST_ADAPTIVE_DEMUX_FLOW_END_OF_FRAGMENT;

    /* No mdat yet, let's get called again with the next boxes */
    if (dash_stream->isobmff_parser.current_fourcc != GST_ISOFF_FOURCC_MDAT)
      return ret;

    /* Here we end up only if we're right at the mdat start */

    /* Jump to the next sync sample. As we're doing chunked downloading
     * here, just drop data until our chunk is over so we can reuse the
     * HTTP connection instead of having to create a new one or
     * reuse the data if the sync sample follows the moof */
    if (dash_stream->active_stream->mimeType == GST_STREAM_VIDEO
        && gst_dash_demux_find_sync_samples (demux, stream) &&
        GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (stream->demux)) {
      guint idx = -1;

      if (GST_CLOCK_TIME_IS_VALID (dash_stream->target_time)) {
        idx =
            (dash_stream->target_time -
            dash_stream->current_fragment_timestamp) /
            dash_stream->current_fragment_keyframe_distance;
      } else if (stream->segment.rate > 0) {
        idx = 0;
      }

      GST_DEBUG_OBJECT (stream->pad, "target %" GST_TIME_FORMAT " idx %d",
          GST_TIME_ARGS (dash_stream->target_time), idx);
      /* Figure out target time */

      if (dash_stream->first_sync_sample_after_moof && idx == 0) {
        /* If we're here, don't throw away data but collect sync
         * sample while we're at it below. We're doing chunked
         * downloading so might need to adjust the next chunk size for
         * the remainder */
        dash_stream->current_sync_sample = 0;
        GST_DEBUG_OBJECT (stream->pad, "Using first keyframe after header");
      }
    }

    if (gst_adapter_available (dash_stream->adapter) == 0)
      return ret;

    /* We have some data from the mdat available in the adapter, handle it
     * below in the push code */
  } else {
    /* Somewhere in the middle of the mdat */
  }

  /* At mdat */
  if (dash_stream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
    guint64 sidx_end_offset =
        dash_stream->sidx_base_offset +
        SIDX_CURRENT_ENTRY (dash_stream)->offset +
        SIDX_CURRENT_ENTRY (dash_stream)->size;
    gboolean has_next = gst_dash_demux_stream_has_next_subfragment (stream);
    gsize available;

    /* Need to handle everything in the adapter according to the parsed SIDX
     * and advance subsegments accordingly */

    available = gst_adapter_available (dash_stream->adapter);
    if (dash_stream->current_offset + available < sidx_end_offset) {
      buffer = gst_adapter_take_buffer (dash_stream->adapter, available);
    } else {
      if (!has_next && sidx_end_offset <= dash_stream->current_offset) {
        /* Drain all bytes, since there might be trailing bytes at the end of subfragment */
        buffer = gst_adapter_take_buffer (dash_stream->adapter, available);
      } else {
        if (sidx_end_offset <= dash_stream->current_offset) {
          /* This means a corrupted stream or a bug: ignoring bugs, it
           * should only happen if the SIDX index is corrupt */
          GST_ERROR_OBJECT (stream->pad, "Invalid SIDX state");
          gst_adapter_clear (dash_stream->adapter);
          return GST_FLOW_ERROR;
        } else {
          buffer =
              gst_adapter_take_buffer (dash_stream->adapter,
              sidx_end_offset - dash_stream->current_offset);
          sidx_advance = TRUE;
        }
      }
    }
  } else {
    /* Take it all and handle it further below */
    buffer =
        gst_adapter_take_buffer (dash_stream->adapter,
        gst_adapter_available (dash_stream->adapter));

    /* Attention: All code paths below need to update dash_stream->current_offset */
  }

  /* We're actually running in key-units trick mode */
  if (dash_stream->active_stream->mimeType == GST_STREAM_VIDEO
      && dash_stream->moof_sync_samples
      && GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (stream->demux)) {
    if (dash_stream->current_sync_sample == -1) {
      /* We're doing chunked downloading and wait for finishing the current
       * chunk so we can jump to the first keyframe */
      dash_stream->current_offset += gst_buffer_get_size (buffer);
      gst_buffer_unref (buffer);
      return GST_FLOW_OK;
    } else {
      GstDashStreamSyncSample *sync_sample =
          &g_array_index (dash_stream->moof_sync_samples,
          GstDashStreamSyncSample, dash_stream->current_sync_sample);
      guint64 end_offset =
          dash_stream->current_offset + gst_buffer_get_size (buffer);

      /* Make sure to not download too much, this should only happen for
       * the very first keyframe if it follows the moof */
      if (dash_stream->current_offset >= sync_sample->end_offset + 1) {
        dash_stream->current_offset += gst_buffer_get_size (buffer);
        gst_buffer_unref (buffer);
        return GST_FLOW_OK;
      } else if (end_offset > sync_sample->end_offset + 1) {
        guint64 remaining =
            sync_sample->end_offset + 1 - dash_stream->current_offset;
        GstBuffer *sub = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0,
            remaining);
        gst_buffer_unref (buffer);
        buffer = sub;
      }
    }
  }

  GST_BUFFER_OFFSET (buffer) = dash_stream->current_offset;
  dash_stream->current_offset += gst_buffer_get_size (buffer);
  GST_BUFFER_OFFSET_END (buffer) = dash_stream->current_offset;

  ret = gst_adaptive_demux_stream_push_buffer (stream, buffer);
  if (ret != GST_FLOW_OK)
    return ret;

  if (sidx_advance) {
    ret =
        gst_adaptive_demux_stream_advance_fragment (demux, stream,
        SIDX_CURRENT_ENTRY (dash_stream)->duration);
    if (ret != GST_FLOW_OK)
      return ret;

    /* If we still have data available, recurse and use it up if possible */
    if (gst_adapter_available (dash_stream->adapter) > 0)
      return gst_dash_demux_handle_isobmff (demux, stream);
  }

  return ret;
}

static GstFlowReturn
gst_dash_demux_data_received (GstAdaptiveDemux * demux,
    GstAdaptiveDemuxStream * stream, GstBuffer * buffer)
{
  GstDashDemuxStream *dash_stream = (GstDashDemuxStream *) stream;
  GstFlowReturn ret = GST_FLOW_OK;
  guint index_header_or_data;

  if (stream->downloading_index)
    index_header_or_data = 1;
  else if (stream->downloading_header)
    index_header_or_data = 2;
  else
    index_header_or_data = 3;

  if (dash_stream->current_index_header_or_data != index_header_or_data) {
    /* Clear pending data */
    if (gst_adapter_available (dash_stream->adapter) != 0)
      GST_ERROR_OBJECT (stream->pad,
          "Had pending SIDX data after switch between index/header/data");
    gst_adapter_clear (dash_stream->adapter);
    dash_stream->current_index_header_or_data = index_header_or_data;
    dash_stream->current_offset = -1;
  }

  if (dash_stream->current_offset == -1)
    dash_stream->current_offset =
        GST_BUFFER_OFFSET_IS_VALID (buffer) ? GST_BUFFER_OFFSET (buffer) : 0;

  gst_adapter_push (dash_stream->adapter, buffer);
  buffer = NULL;

  if (dash_stream->is_isobmff || stream->downloading_index) {
    /* SIDX index is also ISOBMMF */
    ret = gst_dash_demux_handle_isobmff (demux, stream);
  } else if (dash_stream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
    gsize available;

    /* Not ISOBMFF but had a SIDX index. Does this even exist or work? */
    while (ret == GST_FLOW_OK
        && ((available = gst_adapter_available (dash_stream->adapter)) > 0)) {
      gboolean advance = FALSE;
      guint64 sidx_end_offset =
          dash_stream->sidx_base_offset +
          SIDX_CURRENT_ENTRY (dash_stream)->offset +
          SIDX_CURRENT_ENTRY (dash_stream)->size;
      gboolean has_next = gst_dash_demux_stream_has_next_subfragment (stream);

      if (dash_stream->current_offset + available < sidx_end_offset) {
        buffer = gst_adapter_take_buffer (dash_stream->adapter, available);
      } else {
        if (!has_next && sidx_end_offset <= dash_stream->current_offset) {
          /* Drain all bytes, since there might be trailing bytes at the end of subfragment */
          buffer = gst_adapter_take_buffer (dash_stream->adapter, available);
        } else {
          if (sidx_end_offset <= dash_stream->current_offset) {
            /* This means a corrupted stream or a bug: ignoring bugs, it
             * should only happen if the SIDX index is corrupt */
            GST_ERROR_OBJECT (stream->pad, "Invalid SIDX state");
            gst_adapter_clear (dash_stream->adapter);
            ret = GST_FLOW_ERROR;
            break;
          } else {
            buffer =
                gst_adapter_take_buffer (dash_stream->adapter,
                sidx_end_offset - dash_stream->current_offset);
            advance = TRUE;
          }
        }
      }

      GST_BUFFER_OFFSET (buffer) = dash_stream->current_offset;
      GST_BUFFER_OFFSET_END (buffer) =
          GST_BUFFER_OFFSET (buffer) + gst_buffer_get_size (buffer);
      dash_stream->current_offset = GST_BUFFER_OFFSET_END (buffer);

      ret = gst_adaptive_demux_stream_push_buffer (stream, buffer);

      if (advance) {
        if (has_next) {
          GstFlowReturn new_ret;
          new_ret =
              gst_adaptive_demux_stream_advance_fragment (demux, stream,
              SIDX_CURRENT_ENTRY (dash_stream)->duration);

          /* only overwrite if it was OK before */
          if (ret == GST_FLOW_OK)
            ret = new_ret;
        } else {
          break;
        }
      }
    }
  } else {
    /* this should be the main header, just push it all */
    buffer = gst_adapter_take_buffer (dash_stream->adapter,
        gst_adapter_available (dash_stream->adapter));

    GST_BUFFER_OFFSET (buffer) = dash_stream->current_offset;
    GST_BUFFER_OFFSET_END (buffer) =
        GST_BUFFER_OFFSET (buffer) + gst_buffer_get_size (buffer);
    dash_stream->current_offset = GST_BUFFER_OFFSET_END (buffer);

    ret = gst_adaptive_demux_stream_push_buffer (stream, buffer);
  }

  return ret;
}

static void
gst_dash_demux_stream_free (GstAdaptiveDemuxStream * stream)
{
  GstDashDemuxStream *dash_stream = (GstDashDemuxStream *) stream;

  gst_isoff_sidx_parser_clear (&dash_stream->sidx_parser);
  if (dash_stream->adapter)
    g_object_unref (dash_stream->adapter);
  if (dash_stream->moof)
    gst_isoff_moof_box_free (dash_stream->moof);
  if (dash_stream->moof_sync_samples)
    g_array_free (dash_stream->moof_sync_samples, TRUE);
}

static GstDashDemuxClockDrift *
gst_dash_demux_clock_drift_new (GstDashDemux * demux)
{
  GstDashDemuxClockDrift *clock_drift;

  clock_drift = g_slice_new0 (GstDashDemuxClockDrift);
  g_mutex_init (&clock_drift->clock_lock);
  clock_drift->next_update =
      GST_TIME_AS_USECONDS (gst_adaptive_demux_get_monotonic_time
      (GST_ADAPTIVE_DEMUX_CAST (demux)));
  return clock_drift;
}

static void
gst_dash_demux_clock_drift_free (GstDashDemuxClockDrift * clock_drift)
{
  if (clock_drift) {
    g_mutex_lock (&clock_drift->clock_lock);
    if (clock_drift->ntp_clock)
      g_object_unref (clock_drift->ntp_clock);
    g_mutex_unlock (&clock_drift->clock_lock);
    g_mutex_clear (&clock_drift->clock_lock);
    g_slice_free (GstDashDemuxClockDrift, clock_drift);
  }
}

/*
 * The value attribute of the UTCTiming element contains a white-space
 * separated list of servers that are recommended to be used in
 * combination with the NTP protocol as defined in IETF RFC 5905 for
 * getting the appropriate time.
 *
 * The DASH standard does not specify which version of NTP. This
 * function only works with NTPv4 servers.
*/
static GstDateTime *
gst_dash_demux_poll_ntp_server (GstDashDemuxClockDrift * clock_drift,
    gchar ** urls)
{
  GstClockTime ntp_clock_time;
  GDateTime *dt, *dt2;

  if (!clock_drift->ntp_clock) {
    GResolver *resolver;
    GList *inet_addrs;
    GError *err;
    gchar *ip_addr;

    resolver = g_resolver_get_default ();
    /* We don't round-robin NTP servers. If the manifest specifies multiple
       NTP time servers, select one at random */
    clock_drift->selected_url = g_random_int_range (0, g_strv_length (urls));
    GST_DEBUG ("Connecting to NTP time server %s",
        urls[clock_drift->selected_url]);
    inet_addrs = g_resolver_lookup_by_name (resolver,
        urls[clock_drift->selected_url], NULL, &err);
    g_object_unref (resolver);
    if (!inet_addrs || g_list_length (inet_addrs) == 0) {
      GST_ERROR ("Failed to resolve hostname of NTP server: %s",
          err ? (err->message) : "unknown error");
      if (inet_addrs)
        g_resolver_free_addresses (inet_addrs);
      if (err)
        g_error_free (err);
      return NULL;
    }
    ip_addr =
        g_inet_address_to_string ((GInetAddress
            *) (g_list_first (inet_addrs)->data));
    clock_drift->ntp_clock = gst_ntp_clock_new ("dashntp", ip_addr, 123, 0);
    g_free (ip_addr);
    g_resolver_free_addresses (inet_addrs);
    if (!clock_drift->ntp_clock) {
      GST_ERROR ("Failed to create NTP clock");
      return NULL;
    }
    if (!gst_clock_wait_for_sync (clock_drift->ntp_clock, 5 * GST_SECOND)) {
      g_object_unref (clock_drift->ntp_clock);
      clock_drift->ntp_clock = NULL;
      GST_ERROR ("Failed to lock to NTP clock");
      return NULL;
    }
  }
  ntp_clock_time = gst_clock_get_time (clock_drift->ntp_clock);
  if (ntp_clock_time == GST_CLOCK_TIME_NONE) {
    GST_ERROR ("Failed to get time from NTP clock");
    return NULL;
  }
  ntp_clock_time -= NTP_TO_UNIX_EPOCH * GST_SECOND;
  dt = g_date_time_new_from_unix_utc (ntp_clock_time / GST_SECOND);
  if (!dt) {
    GST_ERROR ("Failed to create GstDateTime");
    return NULL;
  }
  ntp_clock_time =
      gst_util_uint64_scale (ntp_clock_time % GST_SECOND, 1000000, GST_SECOND);
  dt2 = g_date_time_add (dt, ntp_clock_time);
  g_date_time_unref (dt);
  return gst_date_time_new_from_g_date_time (dt2);
}

struct Rfc5322TimeZone
{
  const gchar *name;
  gfloat tzoffset;
};

/*
 Parse an RFC5322 (section 3.3) date-time from the Date: field in the
 HTTP response. 
 See https://tools.ietf.org/html/rfc5322#section-3.3
*/
static GstDateTime *
gst_dash_demux_parse_http_head (GstDashDemuxClockDrift * clock_drift,
    GstFragment * download)
{
  static const gchar *months[] = { NULL, "Jan", "Feb", "Mar", "Apr",
    "May", "Jun", "Jul", "Aug",
    "Sep", "Oct", "Nov", "Dec", NULL
  };
  static const struct Rfc5322TimeZone timezones[] = {
    {"Z", 0},
    {"UT", 0},
    {"GMT", 0},
    {"BST", 1},
    {"EST", -5},
    {"EDT", -4},
    {"CST", -6},
    {"CDT", -5},
    {"MST", -7},
    {"MDT", -6},
    {"PST", -8},
    {"PDT", -7},
    {NULL, 0}
  };
  GstDateTime *value = NULL;
  const GstStructure *response_headers;
  const gchar *http_date;
  const GValue *val;
  gint ret;
  const gchar *pos;
  gint year = -1, month = -1, day = -1, hour = -1, minute = -1, second = -1;
  gchar zone[6];
  gchar monthstr[4];
  gfloat tzoffset = 0;
  gboolean parsed_tz = FALSE;

  g_return_val_if_fail (download != NULL, NULL);
  g_return_val_if_fail (download->headers != NULL, NULL);

  val = gst_structure_get_value (download->headers, "response-headers");
  if (!val) {
    return NULL;
  }
  response_headers = gst_value_get_structure (val);
  http_date = gst_structure_get_string (response_headers, "Date");
  if (!http_date) {
    return NULL;
  }

  /* skip optional text version of day of the week */
  pos = strchr (http_date, ',');
  if (pos)
    pos++;
  else
    pos = http_date;
  ret =
      sscanf (pos, "%02d %3s %04d %02d:%02d:%02d %5s", &day, monthstr, &year,
      &hour, &minute, &second, zone);
  if (ret == 7) {
    gchar *z = zone;
    gint i;

    for (i = 1; months[i]; ++i) {
      if (g_ascii_strncasecmp (months[i], monthstr, strlen (months[i])) == 0) {
        month = i;
        break;
      }
    }
    for (i = 0; timezones[i].name && !parsed_tz; ++i) {
      if (g_ascii_strncasecmp (timezones[i].name, z,
              strlen (timezones[i].name)) == 0) {
        tzoffset = timezones[i].tzoffset;
        parsed_tz = TRUE;
      }
    }
    if (!parsed_tz) {
      gint hh, mm;
      gboolean neg = FALSE;
      /* check if it is in the form +-HHMM */
      if (*z == '+' || *z == '-') {
        if (*z == '+')
          ++z;
        else if (*z == '-') {
          ++z;
          neg = TRUE;
        }
        ret = sscanf (z, "%02d%02d", &hh, &mm);
        if (ret == 2) {
          tzoffset = hh;
          tzoffset += mm / 60.0;
          if (neg)
            tzoffset = -tzoffset;
          parsed_tz = TRUE;
        }
      }
    }
    /* Accept year in both 2 digit or 4 digit format */
    if (year < 100)
      year += 2000;
  }
  if (month > 0 && parsed_tz) {
    value = gst_date_time_new (tzoffset,
        year, month, day, hour, minute, second);
  }
  return value;
}

/*
   The timing information is contained in the message body of the HTTP
   response and contains a time value formatted according to NTP timestamp
   format in IETF RFC 5905.

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                            Seconds                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                            Fraction                           |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                             NTP Timestamp Format
*/
static GstDateTime *
gst_dash_demux_parse_http_ntp (GstDashDemuxClockDrift * clock_drift,
    GstBuffer * buffer)
{
  gint64 seconds;
  guint64 fraction;
  GDateTime *dt, *dt2;
  GstMapInfo mapinfo;

  /* See https://tools.ietf.org/html/rfc5905#page-12 for details of
     the NTP Timestamp Format */
  gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
  if (mapinfo.size != 8) {
    gst_buffer_unmap (buffer, &mapinfo);
    return NULL;
  }
  seconds = GST_READ_UINT32_BE (mapinfo.data);
  fraction = GST_READ_UINT32_BE (mapinfo.data + 4);
  gst_buffer_unmap (buffer, &mapinfo);
  fraction = gst_util_uint64_scale (fraction, 1000000,
      G_GUINT64_CONSTANT (1) << 32);
  /* subtract constant to convert from 1900 based time to 1970 based time */
  seconds -= NTP_TO_UNIX_EPOCH;
  dt = g_date_time_new_from_unix_utc (seconds);
  dt2 = g_date_time_add (dt, fraction);
  g_date_time_unref (dt);
  return gst_date_time_new_from_g_date_time (dt2);
}

/*
  The timing information is contained in the message body of the
  HTTP response and contains a time value formatted according to
  xs:dateTime as defined in W3C XML Schema Part 2: Datatypes specification.
*/
static GstDateTime *
gst_dash_demux_parse_http_xsdate (GstDashDemuxClockDrift * clock_drift,
    GstBuffer * buffer)
{
  GstDateTime *value = NULL;
  GstMapInfo mapinfo;

  /* the string from the server might not be zero terminated */
  if (gst_buffer_map (buffer, &mapinfo, GST_MAP_READ)) {
    gchar *str;
    str = g_strndup ((const gchar *) mapinfo.data, mapinfo.size);
    gst_buffer_unmap (buffer, &mapinfo);
    value = gst_date_time_new_from_iso8601_string (str);
    g_free (str);
  }
  return value;
}

static gboolean
gst_dash_demux_poll_clock_drift (GstDashDemux * demux)
{
  GstDashDemuxClockDrift *clock_drift;
  GDateTime *start = NULL, *end;
  GstBuffer *buffer = NULL;
  GstDateTime *value = NULL;
  gboolean ret = FALSE;
  gint64 now;
  GstMPDUTCTimingType method;
  gchar **urls;

  g_return_val_if_fail (demux != NULL, FALSE);
  g_return_val_if_fail (demux->clock_drift != NULL, FALSE);
  clock_drift = demux->clock_drift;
  now =
      GST_TIME_AS_USECONDS (gst_adaptive_demux_get_monotonic_time
      (GST_ADAPTIVE_DEMUX_CAST (demux)));
  if (now < clock_drift->next_update) {
    /*TODO: If a fragment fails to download in adaptivedemux, it waits
       for a manifest reload before another attempt to fetch a fragment.
       Section 10.8.6 of the DVB-DASH standard states that the DASH client
       shall refresh the manifest and resynchronise to one of the time sources.

       Currently the fact that the manifest refresh follows a download failure
       does not make it into dashdemux. */
    return TRUE;
  }
  urls = gst_mpd_client_get_utc_timing_sources (demux->client,
      SUPPORTED_CLOCK_FORMATS, &method);
  if (!urls) {
    return FALSE;
  }
  /* Update selected_url just in case the number of URLs in the UTCTiming
     element has shrunk since the last poll */
  clock_drift->selected_url = clock_drift->selected_url % g_strv_length (urls);
  g_mutex_lock (&clock_drift->clock_lock);

  if (method == GST_MPD_UTCTIMING_TYPE_NTP) {
    value = gst_dash_demux_poll_ntp_server (clock_drift, urls);
    if (!value) {
      GST_ERROR_OBJECT (demux, "Failed to fetch time from NTP server %s",
          urls[clock_drift->selected_url]);
      g_mutex_unlock (&clock_drift->clock_lock);
      goto quit;
    }
  }
  start =
      gst_adaptive_demux_get_client_now_utc (GST_ADAPTIVE_DEMUX_CAST (demux));
  if (!value) {
    GstFragment *download;
    gint64 range_start = 0, range_end = -1;
    GST_DEBUG_OBJECT (demux, "Fetching current time from %s",
        urls[clock_drift->selected_url]);
    if (method == GST_MPD_UTCTIMING_TYPE_HTTP_HEAD) {
      range_start = -1;
    }
    download =
        gst_uri_downloader_fetch_uri_with_range (GST_ADAPTIVE_DEMUX_CAST
        (demux)->downloader, urls[clock_drift->selected_url], NULL, TRUE, TRUE,
        TRUE, range_start, range_end, NULL);
    if (download) {
      if (method == GST_MPD_UTCTIMING_TYPE_HTTP_HEAD && download->headers) {
        value = gst_dash_demux_parse_http_head (clock_drift, download);
      } else {
        buffer = gst_fragment_get_buffer (download);
      }
      g_object_unref (download);
    }
  }
  g_mutex_unlock (&clock_drift->clock_lock);
  if (!value && !buffer) {
    GST_ERROR_OBJECT (demux, "Failed to fetch time from %s",
        urls[clock_drift->selected_url]);
    goto quit;
  }
  end = gst_adaptive_demux_get_client_now_utc (GST_ADAPTIVE_DEMUX_CAST (demux));
  if (!value && method == GST_MPD_UTCTIMING_TYPE_HTTP_NTP) {
    value = gst_dash_demux_parse_http_ntp (clock_drift, buffer);
  } else if (!value) {
    /* GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE or GST_MPD_UTCTIMING_TYPE_HTTP_ISO */
    value = gst_dash_demux_parse_http_xsdate (clock_drift, buffer);
  }
  if (buffer)
    gst_buffer_unref (buffer);
  if (value) {
    GTimeSpan download_duration = g_date_time_difference (end, start);
    GDateTime *client_now, *server_now;
    /* We don't know when the server sampled its clock, but we know
       it must have been before "end" and probably after "start".
       A reasonable estimate is to use (start+end)/2
     */
    client_now = g_date_time_add (start, download_duration / 2);
    server_now = gst_date_time_to_g_date_time (value);
    /* If gst_date_time_new_from_iso8601_string is given an unsupported
       ISO 8601 format, it can return a GstDateTime that is not valid,
       which causes gst_date_time_to_g_date_time to return NULL */
    if (server_now) {
      g_mutex_lock (&clock_drift->clock_lock);
      clock_drift->clock_compensation =
          g_date_time_difference (server_now, client_now);
      g_mutex_unlock (&clock_drift->clock_lock);
      GST_DEBUG_OBJECT (demux,
          "Difference between client and server clocks is %lfs",
          ((double) clock_drift->clock_compensation) / 1000000.0);
      g_date_time_unref (server_now);
      ret = TRUE;
    } else {
      GST_ERROR_OBJECT (demux, "Failed to parse DateTime from server");
    }
    g_date_time_unref (client_now);
    gst_date_time_unref (value);
  } else {
    GST_ERROR_OBJECT (demux, "Failed to parse DateTime from server");
  }
  g_date_time_unref (end);
quit:
  if (start)
    g_date_time_unref (start);
  /* if multiple URLs were specified, use a simple round-robin to
     poll each server */
  g_mutex_lock (&clock_drift->clock_lock);
  if (method == GST_MPD_UTCTIMING_TYPE_NTP) {
    clock_drift->next_update = now + FAST_CLOCK_UPDATE_INTERVAL;
  } else {
    clock_drift->selected_url =
        (1 + clock_drift->selected_url) % g_strv_length (urls);
    if (ret) {
      clock_drift->next_update = now + SLOW_CLOCK_UPDATE_INTERVAL;
    } else {
      clock_drift->next_update = now + FAST_CLOCK_UPDATE_INTERVAL;
    }
  }
  g_mutex_unlock (&clock_drift->clock_lock);
  return ret;
}

static GTimeSpan
gst_dash_demux_get_clock_compensation (GstDashDemux * demux)
{
  GTimeSpan rv = 0;
  if (demux->clock_drift) {
    g_mutex_lock (&demux->clock_drift->clock_lock);
    rv = demux->clock_drift->clock_compensation;
    g_mutex_unlock (&demux->clock_drift->clock_lock);
  }
  GST_LOG_OBJECT (demux, "Clock drift %" GST_STIME_FORMAT, GST_STIME_ARGS (rv));
  return rv;
}

static GDateTime *
gst_dash_demux_get_server_now_utc (GstDashDemux * demux)
{
  GDateTime *client_now;
  GDateTime *server_now;

  client_now =
      gst_adaptive_demux_get_client_now_utc (GST_ADAPTIVE_DEMUX_CAST (demux));
  server_now =
      g_date_time_add (client_now,
      gst_dash_demux_get_clock_compensation (demux));
  g_date_time_unref (client_now);
  return server_now;
}
