/*
 * DASH MPD parsing library
 *
 * gstmpdparser.c
 *
 * Copyright (C) 2012 STMicroelectronics
 *
 * Authors:
 *   Gianluca Gennari <gennarone@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2.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.
 */

#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include "gstmpdparser.h"
#include "gstdash_debug.h"

#define GST_CAT_DEFAULT gst_dash_demux_debug

/* Property parsing */
static gboolean gst_mpdparser_get_xml_prop_validated_string (xmlNode * a_node,
    const gchar * property_name, gchar ** property_value,
    gboolean (*validator) (const char *));
static gboolean gst_mpdparser_get_xml_prop_string (xmlNode * a_node,
    const gchar * property_name, gchar ** property_value);
static gboolean gst_mpdparser_get_xml_prop_string_stripped (xmlNode * a_node,
    const gchar * property_name, gchar ** property_value);
static gboolean gst_mpdparser_get_xml_ns_prop_string (xmlNode * a_node,
    const gchar * ns_name, const gchar * property_name,
    gchar ** property_value);
static gboolean gst_mpdparser_get_xml_prop_string_vector_type (xmlNode * a_node,
    const gchar * property_name, gchar *** property_value);
static gboolean gst_mpdparser_get_xml_prop_signed_integer (xmlNode * a_node,
    const gchar * property_name, gint default_val, gint * property_value);
static gboolean gst_mpdparser_get_xml_prop_unsigned_integer (xmlNode * a_node,
    const gchar * property_name, guint default_val, guint * property_value);
static gboolean gst_mpdparser_get_xml_prop_unsigned_integer_64 (xmlNode *
    a_node, const gchar * property_name, guint64 default_val,
    guint64 * property_value);
static gboolean gst_mpdparser_get_xml_prop_uint_vector_type (xmlNode * a_node,
    const gchar * property_name, guint ** property_value, guint * value_size);
static gboolean gst_mpdparser_get_xml_prop_double (xmlNode * a_node,
    const gchar * property_name, gdouble * property_value);
static gboolean gst_mpdparser_get_xml_prop_boolean (xmlNode * a_node,
    const gchar * property_name, gboolean default_val,
    gboolean * property_value);
static gboolean gst_mpdparser_get_xml_prop_type (xmlNode * a_node,
    const gchar * property_name, GstMPDFileType * property_value);
static gboolean gst_mpdparser_get_xml_prop_SAP_type (xmlNode * a_node,
    const gchar * property_name, GstSAPType * property_value);
static gboolean gst_mpdparser_get_xml_prop_range (xmlNode * a_node,
    const gchar * property_name, GstRange ** property_value);
static gboolean gst_mpdparser_get_xml_prop_ratio (xmlNode * a_node,
    const gchar * property_name, GstRatio ** property_value);
static gboolean gst_mpdparser_get_xml_prop_framerate (xmlNode * a_node,
    const gchar * property_name, GstFrameRate ** property_value);
static gboolean gst_mpdparser_get_xml_prop_cond_uint (xmlNode * a_node,
    const gchar * property_name, GstConditionalUintType ** property_value);
static gboolean gst_mpdparser_get_xml_prop_dateTime (xmlNode * a_node,
    const gchar * property_name, GstDateTime ** property_value);
static gboolean gst_mpdparser_get_xml_prop_duration (xmlNode * a_node,
    const gchar * property_name, guint64 default_value,
    guint64 * property_value);
static gboolean gst_mpdparser_get_xml_node_content (xmlNode * a_node,
    gchar ** content);
static gchar *gst_mpdparser_get_xml_node_namespace (xmlNode * a_node,
    const gchar * prefix);
static gboolean gst_mpdparser_get_xml_node_as_string (xmlNode * a_node,
    gchar ** content);

/* XML node parsing */
static void gst_mpdparser_parse_baseURL_node (GList ** list, xmlNode * a_node);
static void gst_mpdparser_parse_descriptor_type_node (GList ** list,
    xmlNode * a_node);
static void gst_mpdparser_parse_content_component_node (GList ** list,
    xmlNode * a_node);
static void gst_mpdparser_parse_location_node (GList ** list, xmlNode * a_node);
static void gst_mpdparser_parse_subrepresentation_node (GList ** list,
    xmlNode * a_node);
static void gst_mpdparser_parse_segment_url_node (GList ** list,
    xmlNode * a_node);
static void gst_mpdparser_parse_url_type_node (GstURLType ** pointer,
    xmlNode * a_node);
static void gst_mpdparser_parse_seg_base_type_ext (GstSegmentBaseType **
    pointer, xmlNode * a_node, GstSegmentBaseType * parent);
static void gst_mpdparser_parse_s_node (GQueue * queue, xmlNode * a_node);
static void gst_mpdparser_parse_segment_timeline_node (GstSegmentTimelineNode **
    pointer, xmlNode * a_node);
static gboolean
gst_mpdparser_parse_mult_seg_base_type_ext (GstMultSegmentBaseType ** pointer,
    xmlNode * a_node, GstMultSegmentBaseType * parent);
static gboolean gst_mpdparser_parse_segment_list_node (GstSegmentListNode **
    pointer, xmlNode * a_node, GstSegmentListNode * parent);
static void
gst_mpdparser_parse_representation_base_type (GstRepresentationBaseType **
    pointer, xmlNode * a_node);
static gboolean gst_mpdparser_parse_representation_node (GList ** list,
    xmlNode * a_node, GstAdaptationSetNode * parent,
    GstPeriodNode * period_node);
static gboolean gst_mpdparser_parse_adaptation_set_node (GList ** list,
    xmlNode * a_node, GstPeriodNode * parent);
static void gst_mpdparser_parse_subset_node (GList ** list, xmlNode * a_node);
static gboolean
gst_mpdparser_parse_segment_template_node (GstSegmentTemplateNode ** pointer,
    xmlNode * a_node, GstSegmentTemplateNode * parent);
static gboolean gst_mpdparser_parse_period_node (GList ** list,
    xmlNode * a_node);
static void gst_mpdparser_parse_program_info_node (GList ** list,
    xmlNode * a_node);
static void gst_mpdparser_parse_metrics_range_node (GList ** list,
    xmlNode * a_node);
static void gst_mpdparser_parse_metrics_node (GList ** list, xmlNode * a_node);
static gboolean gst_mpdparser_parse_root_node (GstMPDNode ** pointer,
    xmlNode * a_node);
static void gst_mpdparser_parse_utctiming_node (GList ** list,
    xmlNode * a_node);

/* Helper functions */
static guint convert_to_millisecs (guint decimals, gint pos);
static int strncmp_ext (const char *s1, const char *s2);
static GstStreamPeriod *gst_mpdparser_get_stream_period (GstMpdClient * client);
static GstSNode *gst_mpdparser_clone_s_node (GstSNode * pointer);
static GstSegmentTimelineNode
    * gst_mpdparser_clone_segment_timeline (GstSegmentTimelineNode * pointer);
static GstRange *gst_mpdparser_clone_range (GstRange * range);
static GstURLType *gst_mpdparser_clone_URL (GstURLType * url);
static gchar *gst_mpdparser_parse_baseURL (GstMpdClient * client,
    GstActiveStream * stream, gchar ** query);
static GstSegmentURLNode *gst_mpdparser_clone_segment_url (GstSegmentURLNode *
    seg_url);
static gchar *gst_mpdparser_get_mediaURL (GstActiveStream * stream,
    GstSegmentURLNode * segmentURL);
static const gchar *gst_mpdparser_get_initializationURL (GstActiveStream *
    stream, GstURLType * InitializationURL);
static gchar *gst_mpdparser_build_URL_from_template (const gchar * url_template,
    const gchar * id, guint number, guint bandwidth, guint64 time);
static gboolean gst_mpd_client_add_media_segment (GstActiveStream * stream,
    GstSegmentURLNode * url_node, guint number, gint repeat,
    guint64 scale_start, guint64 scale_duration, GstClockTime start,
    GstClockTime duration);
static const gchar *gst_mpdparser_mimetype_to_caps (const gchar * mimeType);
static GstClockTime gst_mpd_client_get_segment_duration (GstMpdClient * client,
    GstActiveStream * stream, guint64 * scale_duration);
static GstDateTime *gst_mpd_client_get_availability_start_time (GstMpdClient *
    client);

/* Representation */
static GstRepresentationNode *gst_mpdparser_get_lowest_representation (GList *
    Representations);
#if 0
static GstRepresentationNode *gst_mpdparser_get_highest_representation (GList *
    Representations);
static GstRepresentationNode
    * gst_mpdparser_get_representation_with_max_bandwidth (GList *
    Representations, gint max_bandwidth);
#endif
static GstSegmentBaseType *gst_mpdparser_get_segment_base (GstPeriodNode *
    Period, GstAdaptationSetNode * AdaptationSet,
    GstRepresentationNode * Representation);
static GstSegmentListNode *gst_mpdparser_get_segment_list (GstMpdClient *
    client, GstPeriodNode * Period, GstAdaptationSetNode * AdaptationSet,
    GstRepresentationNode * Representation);

/* Segments */
static guint gst_mpd_client_get_segments_counts (GstMpdClient * client,
    GstActiveStream * stream);

/* Memory management */
static GstSegmentTimelineNode *gst_mpdparser_segment_timeline_node_new (void);
static void gst_mpdparser_free_mpd_node (GstMPDNode * mpd_node);
static void gst_mpdparser_free_prog_info_node (GstProgramInformationNode *
    prog_info_node);
static void gst_mpdparser_free_metrics_node (GstMetricsNode * metrics_node);
static void gst_mpdparser_free_metrics_range_node (GstMetricsRangeNode *
    metrics_range_node);
static void gst_mpdparser_free_period_node (GstPeriodNode * period_node);
static void gst_mpdparser_free_subset_node (GstSubsetNode * subset_node);
static void gst_mpdparser_free_segment_template_node (GstSegmentTemplateNode *
    segment_template_node);
static void
gst_mpdparser_free_representation_base_type (GstRepresentationBaseType *
    representation_base);
static void gst_mpdparser_free_adaptation_set_node (GstAdaptationSetNode *
    adaptation_set_node);
static void gst_mpdparser_free_representation_node (GstRepresentationNode *
    representation_node);
static void gst_mpdparser_free_subrepresentation_node (GstSubRepresentationNode
    * subrep_node);
static void gst_mpdparser_free_s_node (GstSNode * s_node);
static void gst_mpdparser_free_segment_timeline_node (GstSegmentTimelineNode *
    seg_timeline);
static void gst_mpdparser_free_url_type_node (GstURLType * url_type_node);
static void gst_mpdparser_free_seg_base_type_ext (GstSegmentBaseType *
    seg_base_type);
static void gst_mpdparser_free_mult_seg_base_type_ext (GstMultSegmentBaseType *
    mult_seg_base_type);
static void gst_mpdparser_free_segment_list_node (GstSegmentListNode *
    segment_list_node);
static void gst_mpdparser_free_segment_url_node (GstSegmentURLNode *
    segment_url);
static void gst_mpdparser_free_base_url_node (GstBaseURL * base_url_node);
static void gst_mpdparser_free_descriptor_type_node (GstDescriptorType *
    descriptor_type);
static void gst_mpdparser_free_content_component_node (GstContentComponentNode *
    content_component_node);
static void gst_mpdparser_free_utctiming_node (GstUTCTimingNode * timing_type);
static void gst_mpdparser_free_stream_period (GstStreamPeriod * stream_period);
static void gst_mpdparser_free_media_segment (GstMediaSegment * media_segment);
static void gst_mpdparser_free_active_stream (GstActiveStream * active_stream);

static GstUri *combine_urls (GstUri * base, GList * list, gchar ** query,
    guint idx);

static GList *gst_mpd_client_fetch_external_period (GstMpdClient * client,
    GstPeriodNode * period_node);
static GList *gst_mpd_client_fetch_external_adaptation_set (GstMpdClient *
    client, GstPeriodNode * period, GstAdaptationSetNode * adapt_set);

struct GstMpdParserUtcTimingMethod
{
  const gchar *name;
  GstMPDUTCTimingType method;
};

static const struct GstMpdParserUtcTimingMethod
    gst_mpdparser_utc_timing_methods[] = {
  {"urn:mpeg:dash:utc:ntp:2014", GST_MPD_UTCTIMING_TYPE_NTP},
  {"urn:mpeg:dash:utc:sntp:2014", GST_MPD_UTCTIMING_TYPE_SNTP},
  {"urn:mpeg:dash:utc:http-head:2014", GST_MPD_UTCTIMING_TYPE_HTTP_HEAD},
  {"urn:mpeg:dash:utc:http-xsdate:2014", GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE},
  {"urn:mpeg:dash:utc:http-iso:2014", GST_MPD_UTCTIMING_TYPE_HTTP_ISO},
  {"urn:mpeg:dash:utc:http-ntp:2014", GST_MPD_UTCTIMING_TYPE_HTTP_NTP},
  {"urn:mpeg:dash:utc:direct:2014", GST_MPD_UTCTIMING_TYPE_DIRECT},
  /*
   * Early working drafts used the :2012 namespace and this namespace is
   * used by some DASH packagers. To work-around these packagers, we also
   * accept the early draft scheme names.
   */
  {"urn:mpeg:dash:utc:ntp:2012", GST_MPD_UTCTIMING_TYPE_NTP},
  {"urn:mpeg:dash:utc:sntp:2012", GST_MPD_UTCTIMING_TYPE_SNTP},
  {"urn:mpeg:dash:utc:http-head:2012", GST_MPD_UTCTIMING_TYPE_HTTP_HEAD},
  {"urn:mpeg:dash:utc:http-xsdate:2012", GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE},
  {"urn:mpeg:dash:utc:http-iso:2012", GST_MPD_UTCTIMING_TYPE_HTTP_ISO},
  {"urn:mpeg:dash:utc:http-ntp:2012", GST_MPD_UTCTIMING_TYPE_HTTP_NTP},
  {"urn:mpeg:dash:utc:direct:2012", GST_MPD_UTCTIMING_TYPE_DIRECT},
  {NULL, 0}
};

/* functions to parse node namespaces, content and properties */
static gboolean
gst_mpdparser_get_xml_prop_validated_string (xmlNode * a_node,
    const gchar * property_name, gchar ** property_value,
    gboolean (*validate) (const char *))
{
  xmlChar *prop_string;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    if (validate && !(*validate) ((const char *) prop_string)) {
      GST_WARNING ("Validation failure: %s", prop_string);
      xmlFree (prop_string);
      return FALSE;
    }
    *property_value = (gchar *) prop_string;
    exists = TRUE;
    GST_LOG (" - %s: %s", property_name, prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_ns_prop_string (xmlNode * a_node,
    const gchar * ns_name, const gchar * property_name, gchar ** property_value)
{
  xmlChar *prop_string;
  gboolean exists = FALSE;

  prop_string =
      xmlGetNsProp (a_node, (const xmlChar *) property_name,
      (const xmlChar *) ns_name);
  if (prop_string) {
    *property_value = (gchar *) prop_string;
    exists = TRUE;
    GST_LOG (" - %s:%s: %s", ns_name, property_name, prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_string (xmlNode * a_node,
    const gchar * property_name, gchar ** property_value)
{
  return gst_mpdparser_get_xml_prop_validated_string (a_node, property_name,
      property_value, NULL);
}

static gboolean
gst_mpdparser_get_xml_prop_string_stripped (xmlNode * a_node,
    const gchar * property_name, gchar ** property_value)
{
  gboolean ret;
  ret =
      gst_mpdparser_get_xml_prop_string (a_node, property_name, property_value);
  if (ret)
    *property_value = g_strstrip (*property_value);
  return ret;
}

static gboolean
gst_mpdparser_validate_no_whitespace (const char *s)
{
  return !strpbrk (s, "\r\n\t ");
}

static gboolean
gst_mpdparser_get_xml_prop_string_no_whitespace (xmlNode * a_node,
    const gchar * property_name, gchar ** property_value)
{
  return gst_mpdparser_get_xml_prop_validated_string (a_node, property_name,
      property_value, gst_mpdparser_validate_no_whitespace);
}

static gboolean
gst_mpdparser_get_xml_prop_string_vector_type (xmlNode * a_node,
    const gchar * property_name, gchar *** property_value)
{
  xmlChar *prop_string;
  gchar **prop_string_vector = NULL;
  guint i = 0;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    prop_string_vector = g_strsplit ((gchar *) prop_string, " ", -1);
    if (prop_string_vector) {
      exists = TRUE;
      *property_value = prop_string_vector;
      GST_LOG (" - %s:", property_name);
      while (prop_string_vector[i]) {
        GST_LOG ("    %s", prop_string_vector[i]);
        i++;
      }
    } else {
      GST_WARNING ("Scan of string vector property failed!");
    }
    xmlFree (prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_signed_integer (xmlNode * a_node,
    const gchar * property_name, gint default_val, gint * property_value)
{
  xmlChar *prop_string;
  gboolean exists = FALSE;

  *property_value = default_val;
  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    if (sscanf ((const gchar *) prop_string, "%d", property_value) == 1) {
      exists = TRUE;
      GST_LOG (" - %s: %d", property_name, *property_value);
    } else {
      GST_WARNING
          ("failed to parse signed integer property %s from xml string %s",
          property_name, prop_string);
    }
    xmlFree (prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_unsigned_integer (xmlNode * a_node,
    const gchar * property_name, guint default_val, guint * property_value)
{
  xmlChar *prop_string;
  gboolean exists = FALSE;

  *property_value = default_val;
  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    if (sscanf ((gchar *) prop_string, "%u", property_value) == 1 &&
        strstr ((gchar *) prop_string, "-") == NULL) {
      exists = TRUE;
      GST_LOG (" - %s: %u", property_name, *property_value);
    } else {
      GST_WARNING
          ("failed to parse unsigned integer property %s from xml string %s",
          property_name, prop_string);
      /* sscanf might have written to *property_value. Restore to default */
      *property_value = default_val;
    }
    xmlFree (prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_unsigned_integer_64 (xmlNode * a_node,
    const gchar * property_name, guint64 default_val, guint64 * property_value)
{
  xmlChar *prop_string;
  gboolean exists = FALSE;

  *property_value = default_val;
  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    if (sscanf ((gchar *) prop_string, "%" G_GUINT64_FORMAT,
            property_value) == 1 &&
        strstr ((gchar *) prop_string, "-") == NULL) {
      exists = TRUE;
      GST_LOG (" - %s: %" G_GUINT64_FORMAT, property_name, *property_value);
    } else {
      GST_WARNING
          ("failed to parse unsigned integer property %s from xml string %s",
          property_name, prop_string);
      /* sscanf might have written to *property_value. Restore to default */
      *property_value = default_val;
    }
    xmlFree (prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_uint_vector_type (xmlNode * a_node,
    const gchar * property_name, guint ** property_value, guint * value_size)
{
  xmlChar *prop_string;
  gchar **str_vector;
  guint *prop_uint_vector = NULL, i;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    str_vector = g_strsplit ((gchar *) prop_string, " ", -1);
    if (str_vector) {
      *value_size = g_strv_length (str_vector);
      prop_uint_vector = g_malloc (*value_size * sizeof (guint));
      if (prop_uint_vector) {
        exists = TRUE;
        GST_LOG (" - %s:", property_name);
        for (i = 0; i < *value_size; i++) {
          if (sscanf ((gchar *) str_vector[i], "%u", &prop_uint_vector[i]) == 1
              && strstr (str_vector[i], "-") == NULL) {
            GST_LOG ("    %u", prop_uint_vector[i]);
          } else {
            GST_WARNING
                ("failed to parse uint vector type property %s from xml string %s",
                property_name, str_vector[i]);
            /* there is no special value to put in prop_uint_vector[i] to
             * signal it is invalid, so we just clean everything and return
             * FALSE
             */
            g_free (prop_uint_vector);
            prop_uint_vector = NULL;
            exists = FALSE;
            break;
          }
        }
        *property_value = prop_uint_vector;
      } else {
        GST_WARNING ("Array allocation failed!");
      }
    } else {
      GST_WARNING ("Scan of uint vector property failed!");
    }
    xmlFree (prop_string);
    g_strfreev (str_vector);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_double (xmlNode * a_node,
    const gchar * property_name, gdouble * property_value)
{
  xmlChar *prop_string;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    if (sscanf ((gchar *) prop_string, "%lf", property_value) == 1) {
      exists = TRUE;
      GST_LOG (" - %s: %lf", property_name, *property_value);
    } else {
      GST_WARNING ("failed to parse double property %s from xml string %s",
          property_name, prop_string);
    }
    xmlFree (prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_boolean (xmlNode * a_node,
    const gchar * property_name, gboolean default_val,
    gboolean * property_value)
{
  xmlChar *prop_string;
  gboolean exists = FALSE;

  *property_value = default_val;
  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    if (xmlStrcmp (prop_string, (xmlChar *) "false") == 0) {
      exists = TRUE;
      *property_value = FALSE;
      GST_LOG (" - %s: false", property_name);
    } else if (xmlStrcmp (prop_string, (xmlChar *) "true") == 0) {
      exists = TRUE;
      *property_value = TRUE;
      GST_LOG (" - %s: true", property_name);
    } else {
      GST_WARNING ("failed to parse boolean property %s from xml string %s",
          property_name, prop_string);
    }
    xmlFree (prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_type (xmlNode * a_node,
    const gchar * property_name, GstMPDFileType * property_value)
{
  xmlChar *prop_string;
  gboolean exists = FALSE;

  *property_value = GST_MPD_FILE_TYPE_STATIC;   /* default */
  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    if (xmlStrcmp (prop_string, (xmlChar *) "OnDemand") == 0
        || xmlStrcmp (prop_string, (xmlChar *) "static") == 0) {
      exists = TRUE;
      *property_value = GST_MPD_FILE_TYPE_STATIC;
      GST_LOG (" - %s: static", property_name);
    } else if (xmlStrcmp (prop_string, (xmlChar *) "Live") == 0
        || xmlStrcmp (prop_string, (xmlChar *) "dynamic") == 0) {
      exists = TRUE;
      *property_value = GST_MPD_FILE_TYPE_DYNAMIC;
      GST_LOG (" - %s: dynamic", property_name);
    } else {
      GST_WARNING ("failed to parse MPD type property %s from xml string %s",
          property_name, prop_string);
    }
    xmlFree (prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_SAP_type (xmlNode * a_node,
    const gchar * property_name, GstSAPType * property_value)
{
  xmlChar *prop_string;
  guint prop_SAP_type = 0;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    if (sscanf ((gchar *) prop_string, "%u", &prop_SAP_type) == 1
        && prop_SAP_type <= 6) {
      exists = TRUE;
      *property_value = (GstSAPType) prop_SAP_type;
      GST_LOG (" - %s: %u", property_name, prop_SAP_type);
    } else {
      GST_WARNING
          ("failed to parse unsigned integer property %s from xml string %s",
          property_name, prop_string);
    }
    xmlFree (prop_string);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_prop_range (xmlNode * a_node, const gchar * property_name,
    GstRange ** property_value)
{
  xmlChar *prop_string;
  guint64 first_byte_pos = 0, last_byte_pos = -1;
  guint len, pos;
  gchar *str;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    len = xmlStrlen (prop_string);
    str = (gchar *) prop_string;
    GST_TRACE ("range: %s, len %d", str, len);

    /* read "-" */
    pos = strcspn (str, "-");
    if (pos >= len) {
      GST_TRACE ("pos %d >= len %d", pos, len);
      goto error;
    }
    /* read first_byte_pos */
    if (pos != 0) {
      /* replace str[pos] with '\0' to allow sscanf to not be confused by
       * the minus sign (eg " -1" (observe the space before -) would otherwise
       * be interpreted as range -1 to 1)
       */
      str[pos] = 0;
      if (sscanf (str, "%" G_GUINT64_FORMAT, &first_byte_pos) != 1 ||
          strstr (str, "-") != NULL) {
        /* sscanf failed or it found a negative number */
        /* restore the '-' sign */
        str[pos] = '-';
        goto error;
      }
      /* restore the '-' sign */
      str[pos] = '-';
    }
    /* read last_byte_pos */
    if (pos < (len - 1)) {
      if (sscanf (str + pos + 1, "%" G_GUINT64_FORMAT, &last_byte_pos) != 1 ||
          strstr (str + pos + 1, "-") != NULL) {
        goto error;
      }
    }
    /* malloc return data structure */
    *property_value = g_slice_new0 (GstRange);
    exists = TRUE;
    (*property_value)->first_byte_pos = first_byte_pos;
    (*property_value)->last_byte_pos = last_byte_pos;
    xmlFree (prop_string);
    GST_LOG (" - %s: %" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT,
        property_name, first_byte_pos, last_byte_pos);
  }

  return exists;

error:
  GST_WARNING ("failed to parse property %s from xml string %s", property_name,
      prop_string);
  xmlFree (prop_string);
  return FALSE;
}

static gboolean
gst_mpdparser_get_xml_prop_ratio (xmlNode * a_node,
    const gchar * property_name, GstRatio ** property_value)
{
  xmlChar *prop_string;
  guint num = 0, den = 1;
  guint len, pos;
  gchar *str;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    len = xmlStrlen (prop_string);
    str = (gchar *) prop_string;
    GST_TRACE ("ratio: %s, len %d", str, len);

    /* read ":" */
    pos = strcspn (str, ":");
    if (pos >= len) {
      GST_TRACE ("pos %d >= len %d", pos, len);
      goto error;
    }
    /* search for negative sign */
    if (strstr (str, "-") != NULL) {
      goto error;
    }
    /* read num */
    if (pos != 0) {
      if (sscanf (str, "%u", &num) != 1) {
        goto error;
      }
    }
    /* read den */
    if (pos < (len - 1)) {
      if (sscanf (str + pos + 1, "%u", &den) != 1) {
        goto error;
      }
    }
    /* malloc return data structure */
    *property_value = g_slice_new0 (GstRatio);
    exists = TRUE;
    (*property_value)->num = num;
    (*property_value)->den = den;
    xmlFree (prop_string);
    GST_LOG (" - %s: %u:%u", property_name, num, den);
  }

  return exists;

error:
  GST_WARNING ("failed to parse property %s from xml string %s", property_name,
      prop_string);
  xmlFree (prop_string);
  return FALSE;
}

static gboolean
gst_mpdparser_get_xml_prop_framerate (xmlNode * a_node,
    const gchar * property_name, GstFrameRate ** property_value)
{
  xmlChar *prop_string;
  guint num = 0, den = 1;
  guint len, pos;
  gchar *str;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    len = xmlStrlen (prop_string);
    str = (gchar *) prop_string;
    GST_TRACE ("framerate: %s, len %d", str, len);

    /* search for negative sign */
    if (strstr (str, "-") != NULL) {
      goto error;
    }

    /* read "/" if available */
    pos = strcspn (str, "/");
    /* read num */
    if (pos != 0) {
      if (sscanf (str, "%u", &num) != 1) {
        goto error;
      }
    }
    /* read den (if available) */
    if (pos < (len - 1)) {
      if (sscanf (str + pos + 1, "%u", &den) != 1) {
        goto error;
      }
    }
    /* alloc return data structure */
    *property_value = g_slice_new0 (GstFrameRate);
    exists = TRUE;
    (*property_value)->num = num;
    (*property_value)->den = den;
    xmlFree (prop_string);
    if (den == 1)
      GST_LOG (" - %s: %u", property_name, num);
    else
      GST_LOG (" - %s: %u/%u", property_name, num, den);
  }

  return exists;

error:
  GST_WARNING ("failed to parse property %s from xml string %s", property_name,
      prop_string);
  xmlFree (prop_string);
  return FALSE;
}

static gboolean
gst_mpdparser_get_xml_prop_cond_uint (xmlNode * a_node,
    const gchar * property_name, GstConditionalUintType ** property_value)
{
  xmlChar *prop_string;
  gchar *str;
  gboolean flag;
  guint val;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    str = (gchar *) prop_string;
    GST_TRACE ("conditional uint: %s", str);

    if (strcmp (str, "false") == 0) {
      flag = FALSE;
      val = 0;
    } else if (strcmp (str, "true") == 0) {
      flag = TRUE;
      val = 0;
    } else {
      flag = TRUE;
      if (sscanf (str, "%u", &val) != 1 || strstr (str, "-") != NULL)
        goto error;
    }

    /* alloc return data structure */
    *property_value = g_slice_new0 (GstConditionalUintType);
    exists = TRUE;
    (*property_value)->flag = flag;
    (*property_value)->value = val;
    xmlFree (prop_string);
    GST_LOG (" - %s: flag=%s val=%u", property_name, flag ? "true" : "false",
        val);
  }

  return exists;

error:
  GST_WARNING ("failed to parse property %s from xml string %s", property_name,
      prop_string);
  xmlFree (prop_string);
  return FALSE;
}

/*
  DateTime Data Type

  The dateTime data type is used to specify a date and a time.

  The dateTime is specified in the following form "YYYY-MM-DDThh:mm:ss" where:

    * YYYY indicates the year
    * MM indicates the month
    * DD indicates the day
    * T indicates the start of the required time section
    * hh indicates the hour
    * mm indicates the minute
    * ss indicates the second

  Note: All components are required!
*/
static gboolean
gst_mpdparser_get_xml_prop_dateTime (xmlNode * a_node,
    const gchar * property_name, GstDateTime ** property_value)
{
  xmlChar *prop_string;
  gchar *str;
  gint ret, pos;
  gint year, month, day, hour, minute;
  gdouble second;
  gboolean exists = FALSE;

  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    str = (gchar *) prop_string;
    GST_TRACE ("dateTime: %s, len %d", str, xmlStrlen (prop_string));
    /* parse year */
    ret = sscanf (str, "%d", &year);
    if (ret != 1 || year <= 0)
      goto error;
    pos = strcspn (str, "-");
    str += (pos + 1);
    GST_TRACE (" - year %d", year);
    /* parse month */
    ret = sscanf (str, "%d", &month);
    if (ret != 1 || month <= 0)
      goto error;
    pos = strcspn (str, "-");
    str += (pos + 1);
    GST_TRACE (" - month %d", month);
    /* parse day */
    ret = sscanf (str, "%d", &day);
    if (ret != 1 || day <= 0)
      goto error;
    pos = strcspn (str, "T");
    str += (pos + 1);
    GST_TRACE (" - day %d", day);
    /* parse hour */
    ret = sscanf (str, "%d", &hour);
    if (ret != 1 || hour < 0)
      goto error;
    pos = strcspn (str, ":");
    str += (pos + 1);
    GST_TRACE (" - hour %d", hour);
    /* parse minute */
    ret = sscanf (str, "%d", &minute);
    if (ret != 1 || minute < 0)
      goto error;
    pos = strcspn (str, ":");
    str += (pos + 1);
    GST_TRACE (" - minute %d", minute);
    /* parse second */
    ret = sscanf (str, "%lf", &second);
    if (ret != 1 || second < 0)
      goto error;
    GST_TRACE (" - second %lf", second);

    GST_LOG (" - %s: %4d/%02d/%02d %02d:%02d:%09.6lf", property_name,
        year, month, day, hour, minute, second);

    exists = TRUE;
    *property_value =
        gst_date_time_new (0, year, month, day, hour, minute, second);
    xmlFree (prop_string);
  }

  return exists;

error:
  GST_WARNING ("failed to parse property %s from xml string %s", property_name,
      prop_string);
  xmlFree (prop_string);
  return FALSE;
}

/*
  Duration Data Type

  The duration data type is used to specify a time interval.

  The time interval is specified in the following form "-PnYnMnDTnHnMnS" where:

    * - indicates the negative sign (optional)
    * P indicates the period (required)
    * nY indicates the number of years
    * nM indicates the number of months
    * nD indicates the number of days
    * T indicates the start of a time section (required if you are going to specify hours, minutes, or seconds)
    * nH indicates the number of hours
    * nM indicates the number of minutes
    * nS indicates the number of seconds
*/

/* this function computes decimals * 10 ^ (3 - pos) */
static guint
convert_to_millisecs (guint decimals, gint pos)
{
  guint num = 1, den = 1;
  gint i = 3 - pos;

  while (i < 0) {
    den *= 10;
    i++;
  }
  while (i > 0) {
    num *= 10;
    i--;
  }
  /* if i == 0 we have exactly 3 decimals and nothing to do */
  return decimals * num / den;
}

static gboolean
accumulate (guint64 * v, guint64 mul, guint64 add)
{
  guint64 tmp;

  if (*v > G_MAXUINT64 / mul)
    return FALSE;
  tmp = *v * mul;
  if (tmp > G_MAXUINT64 - add)
    return FALSE;
  *v = tmp + add;
  return TRUE;
}

static gboolean
gst_mpdparser_parse_duration (const char *str, guint64 * value)
{
  gint ret, len, pos, posT;
  gint years = -1, months = -1, days = -1, hours = -1, minutes = -1, seconds =
      -1, decimals = -1, read;
  gboolean have_ms = FALSE;
  guint64 tmp_value;

  len = strlen (str);
  GST_TRACE ("duration: %s, len %d", str, len);
  if (strspn (str, "PT0123456789., \tHMDSY") < len) {
    GST_WARNING ("Invalid character found: '%s'", str);
    goto error;
  }
  /* skip leading/trailing whitespace */
  while (g_ascii_isspace (str[0])) {
    str++;
    len--;
  }
  while (len > 0 && g_ascii_isspace (str[len - 1]))
    --len;

  /* read "P" for period */
  if (str[0] != 'P') {
    GST_WARNING ("P not found at the beginning of the string!");
    goto error;
  }
  str++;
  len--;

  /* read "T" for time (if present) */
  posT = strcspn (str, "T");
  len -= posT;
  if (posT > 0) {
    /* there is some room between P and T, so there must be a period section */
    /* read years, months, days */
    do {
      GST_TRACE ("parsing substring %s", str);
      pos = strcspn (str, "YMD");
      ret = sscanf (str, "%u", &read);
      if (ret != 1) {
        GST_WARNING ("can not read integer value from string %s!", str);
        goto error;
      }
      switch (str[pos]) {
        case 'Y':
          if (years != -1 || months != -1 || days != -1) {
            GST_WARNING ("year, month or day was already set");
            goto error;
          }
          years = read;
          break;
        case 'M':
          if (months != -1 || days != -1) {
            GST_WARNING ("month or day was already set");
            goto error;
          }
          months = read;
          if (months >= 12) {
            GST_WARNING ("Month out of range");
            goto error;
          }
          break;
        case 'D':
          if (days != -1) {
            GST_WARNING ("day was already set");
            goto error;
          }
          days = read;
          if (days >= 31) {
            GST_WARNING ("Day out of range");
            goto error;
          }
          break;
        default:
          GST_WARNING ("unexpected char %c!", str[pos]);
          goto error;
          break;
      }
      GST_TRACE ("read number %u type %c", read, str[pos]);
      str += (pos + 1);
      posT -= (pos + 1);
    } while (posT > 0);
  }

  if (years == -1)
    years = 0;
  if (months == -1)
    months = 0;
  if (days == -1)
    days = 0;

  GST_TRACE ("Y:M:D=%d:%d:%d", years, months, days);

  /* read "T" for time (if present) */
  /* here T is at pos == 0 */
  str++;
  len--;
  pos = 0;
  if (pos < len) {
    /* T found, there is a time section */
    /* read hours, minutes, seconds, hundredths of second */
    do {
      GST_TRACE ("parsing substring %s", str);
      pos = strcspn (str, "HMS,.");
      ret = sscanf (str, "%u", &read);
      if (ret != 1) {
        GST_WARNING ("can not read integer value from string %s!", str);
        goto error;
      }
      switch (str[pos]) {
        case 'H':
          if (hours != -1 || minutes != -1 || seconds != -1) {
            GST_WARNING ("hour, minute or second was already set");
            goto error;
          }
          hours = read;
          if (hours >= 24) {
            GST_WARNING ("Hour out of range");
            goto error;
          }
          break;
        case 'M':
          if (minutes != -1 || seconds != -1) {
            GST_WARNING ("minute or second was already set");
            goto error;
          }
          minutes = read;
          if (minutes >= 60) {
            GST_WARNING ("Minute out of range");
            goto error;
          }
          break;
        case 'S':
          if (have_ms) {
            /* we have read the decimal part of the seconds */
            decimals = convert_to_millisecs (read, pos);
            GST_TRACE ("decimal number %u (%d digits) -> %d ms", read, pos,
                decimals);
          } else {
            if (seconds != -1) {
              GST_WARNING ("second was already set");
              goto error;
            }
            /* no decimals */
            seconds = read;
          }
          break;
        case '.':
        case ',':
          /* we have read the integer part of a decimal number in seconds */
          if (seconds != -1) {
            GST_WARNING ("second was already set");
            goto error;
          }
          seconds = read;
          have_ms = TRUE;
          break;
        default:
          GST_WARNING ("unexpected char %c!", str[pos]);
          goto error;
          break;
      }
      GST_TRACE ("read number %u type %c", read, str[pos]);
      str += pos + 1;
      len -= (pos + 1);
    } while (len > 0);
  }

  if (hours == -1)
    hours = 0;
  if (minutes == -1)
    minutes = 0;
  if (seconds == -1)
    seconds = 0;
  if (decimals == -1)
    decimals = 0;
  GST_TRACE ("H:M:S.MS=%d:%d:%d.%03d", hours, minutes, seconds, decimals);

  tmp_value = 0;
  if (!accumulate (&tmp_value, 1, years)
      || !accumulate (&tmp_value, 365, months * 30)
      || !accumulate (&tmp_value, 1, days)
      || !accumulate (&tmp_value, 24, hours)
      || !accumulate (&tmp_value, 60, minutes)
      || !accumulate (&tmp_value, 60, seconds)
      || !accumulate (&tmp_value, 1000, decimals))
    goto error;

  /* ensure it can be converted from milliseconds to nanoseconds */
  if (tmp_value > G_MAXUINT64 / 1000000)
    goto error;

  *value = tmp_value;
  return TRUE;

error:
  return FALSE;
}

static gboolean
gst_mpdparser_get_xml_prop_duration (xmlNode * a_node,
    const gchar * property_name, guint64 default_value,
    guint64 * property_value)
{
  xmlChar *prop_string;
  gchar *str;
  gboolean exists = FALSE;

  *property_value = default_value;
  prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
  if (prop_string) {
    str = (gchar *) prop_string;
    if (!gst_mpdparser_parse_duration (str, property_value))
      goto error;
    GST_LOG (" - %s: %" G_GUINT64_FORMAT, property_name, *property_value);
    xmlFree (prop_string);
    exists = TRUE;
  }
  return exists;

error:
  xmlFree (prop_string);
  return FALSE;
}

static gboolean
gst_mpdparser_get_xml_node_content (xmlNode * a_node, gchar ** content)
{
  xmlChar *node_content = NULL;
  gboolean exists = FALSE;

  node_content = xmlNodeGetContent (a_node);
  if (node_content) {
    exists = TRUE;
    *content = (gchar *) node_content;
    GST_LOG (" - %s: %s", a_node->name, *content);
  }

  return exists;
}

static gboolean
gst_mpdparser_get_xml_node_as_string (xmlNode * a_node, gchar ** content)
{
  gboolean exists = FALSE;
  const char *txt_encoding;
  xmlOutputBufferPtr out_buf;

  txt_encoding = (const char *) a_node->doc->encoding;
  out_buf = xmlAllocOutputBuffer (NULL);
  g_assert (out_buf != NULL);
  xmlNodeDumpOutput (out_buf, a_node->doc, a_node, 0, 0, txt_encoding);
  xmlOutputBufferFlush (out_buf);
#ifdef LIBXML2_NEW_BUFFER
  if (xmlOutputBufferGetSize (out_buf) > 0) {
    *content =
        (gchar *) xmlStrndup (xmlOutputBufferGetContent (out_buf),
        xmlOutputBufferGetSize (out_buf));
    exists = TRUE;
  }
#else
  if (out_buf->conv && out_buf->conv->use > 0) {
    *content =
        (gchar *) xmlStrndup (out_buf->conv->content, out_buf->conv->use);
    exists = TRUE;
  } else if (out_buf->buffer && out_buf->buffer->use > 0) {
    *content =
        (gchar *) xmlStrndup (out_buf->buffer->content, out_buf->buffer->use);
    exists = TRUE;
  }
#endif // LIBXML2_NEW_BUFFER
  (void) xmlOutputBufferClose (out_buf);

  if (exists) {
    GST_LOG (" - %s: %s", a_node->name, *content);
  }
  return exists;
}

static gchar *
gst_mpdparser_get_xml_node_namespace (xmlNode * a_node, const gchar * prefix)
{
  xmlNs *curr_ns;
  gchar *namespace = NULL;

  if (prefix == NULL) {
    /* return the default namespace */
    if (a_node->ns) {
      namespace = xmlMemStrdup ((const gchar *) a_node->ns->href);
      if (namespace) {
        GST_LOG (" - default namespace: %s", namespace);
      }
    }
  } else {
    /* look for the specified prefix in the namespace list */
    for (curr_ns = a_node->ns; curr_ns; curr_ns = curr_ns->next) {
      if (xmlStrcmp (curr_ns->prefix, (xmlChar *) prefix) == 0) {
        namespace = xmlMemStrdup ((const gchar *) curr_ns->href);
        if (namespace) {
          GST_LOG (" - %s namespace: %s", curr_ns->prefix, curr_ns->href);
        }
      }
    }
  }

  return namespace;
}

static void
gst_mpdparser_parse_baseURL_node (GList ** list, xmlNode * a_node)
{
  GstBaseURL *new_base_url;

  new_base_url = g_slice_new0 (GstBaseURL);
  *list = g_list_append (*list, new_base_url);

  GST_LOG ("content of BaseURL node:");
  gst_mpdparser_get_xml_node_content (a_node, &new_base_url->baseURL);

  GST_LOG ("attributes of BaseURL node:");
  gst_mpdparser_get_xml_prop_string (a_node, "serviceLocation",
      &new_base_url->serviceLocation);
  gst_mpdparser_get_xml_prop_string (a_node, "byteRange",
      &new_base_url->byteRange);
}

static void
gst_mpdparser_parse_descriptor_type_node (GList ** list, xmlNode * a_node)
{
  GstDescriptorType *new_descriptor;

  new_descriptor = g_slice_new0 (GstDescriptorType);
  *list = g_list_append (*list, new_descriptor);

  GST_LOG ("attributes of %s node:", a_node->name);
  gst_mpdparser_get_xml_prop_string_stripped (a_node, "schemeIdUri",
      &new_descriptor->schemeIdUri);
  if (!gst_mpdparser_get_xml_prop_string (a_node, "value",
          &new_descriptor->value)) {
    /* if no value attribute, use XML string representation of the node */
    gst_mpdparser_get_xml_node_as_string (a_node, &new_descriptor->value);
  }
}

static void
gst_mpdparser_parse_content_component_node (GList ** list, xmlNode * a_node)
{
  xmlNode *cur_node;
  GstContentComponentNode *new_content_component;

  new_content_component = g_slice_new0 (GstContentComponentNode);
  *list = g_list_append (*list, new_content_component);

  GST_LOG ("attributes of ContentComponent node:");
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "id", 0,
      &new_content_component->id);
  gst_mpdparser_get_xml_prop_string (a_node, "lang",
      &new_content_component->lang);
  gst_mpdparser_get_xml_prop_string (a_node, "contentType",
      &new_content_component->contentType);
  gst_mpdparser_get_xml_prop_ratio (a_node, "par", &new_content_component->par);

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "Accessibility") == 0) {
        gst_mpdparser_parse_descriptor_type_node
            (&new_content_component->Accessibility, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Role") == 0) {
        gst_mpdparser_parse_descriptor_type_node (&new_content_component->Role,
            cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Rating") == 0) {
        gst_mpdparser_parse_descriptor_type_node
            (&new_content_component->Rating, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Viewpoint") == 0) {
        gst_mpdparser_parse_descriptor_type_node
            (&new_content_component->Viewpoint, cur_node);
      }
    }
  }
}

static void
gst_mpdparser_parse_location_node (GList ** list, xmlNode * a_node)
{
  gchar *location = NULL;

  GST_LOG ("content of Location node:");
  if (gst_mpdparser_get_xml_node_content (a_node, &location))
    *list = g_list_append (*list, location);
}

static void
gst_mpdparser_parse_subrepresentation_node (GList ** list, xmlNode * a_node)
{
  GstSubRepresentationNode *new_subrep;

  new_subrep = g_slice_new0 (GstSubRepresentationNode);
  *list = g_list_append (*list, new_subrep);

  GST_LOG ("attributes of SubRepresentation node:");
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "level", 0,
      &new_subrep->level);
  gst_mpdparser_get_xml_prop_uint_vector_type (a_node, "dependencyLevel",
      &new_subrep->dependencyLevel, &new_subrep->size);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "bandwidth", 0,
      &new_subrep->bandwidth);
  gst_mpdparser_get_xml_prop_string_vector_type (a_node,
      "contentComponent", &new_subrep->contentComponent);

  /* RepresentationBase extension */
  gst_mpdparser_parse_representation_base_type (&new_subrep->RepresentationBase,
      a_node);
}

static GstSegmentURLNode *
gst_mpdparser_clone_segment_url (GstSegmentURLNode * seg_url)
{
  GstSegmentURLNode *clone = NULL;

  if (seg_url) {
    clone = g_slice_new0 (GstSegmentURLNode);
    clone->media = xmlMemStrdup (seg_url->media);
    clone->mediaRange = gst_mpdparser_clone_range (seg_url->mediaRange);
    clone->index = xmlMemStrdup (seg_url->index);
    clone->indexRange = gst_mpdparser_clone_range (seg_url->indexRange);
  }

  return clone;
}

static void
gst_mpdparser_parse_segment_url_node (GList ** list, xmlNode * a_node)
{
  GstSegmentURLNode *new_segment_url;

  new_segment_url = g_slice_new0 (GstSegmentURLNode);
  *list = g_list_append (*list, new_segment_url);

  GST_LOG ("attributes of SegmentURL node:");
  gst_mpdparser_get_xml_prop_string (a_node, "media", &new_segment_url->media);
  gst_mpdparser_get_xml_prop_range (a_node, "mediaRange",
      &new_segment_url->mediaRange);
  gst_mpdparser_get_xml_prop_string (a_node, "index", &new_segment_url->index);
  gst_mpdparser_get_xml_prop_range (a_node, "indexRange",
      &new_segment_url->indexRange);
}

static void
gst_mpdparser_parse_url_type_node (GstURLType ** pointer, xmlNode * a_node)
{
  GstURLType *new_url_type;

  gst_mpdparser_free_url_type_node (*pointer);
  *pointer = new_url_type = g_slice_new0 (GstURLType);

  GST_LOG ("attributes of URLType node:");
  gst_mpdparser_get_xml_prop_string (a_node, "sourceURL",
      &new_url_type->sourceURL);
  gst_mpdparser_get_xml_prop_range (a_node, "range", &new_url_type->range);
}

static void
gst_mpdparser_parse_seg_base_type_ext (GstSegmentBaseType ** pointer,
    xmlNode * a_node, GstSegmentBaseType * parent)
{
  xmlNode *cur_node;
  GstSegmentBaseType *seg_base_type;
  guint intval;
  guint64 int64val;
  gboolean boolval;
  GstRange *rangeval;

  gst_mpdparser_free_seg_base_type_ext (*pointer);
  *pointer = seg_base_type = g_slice_new0 (GstSegmentBaseType);

  /* Initialize values that have defaults */
  seg_base_type->indexRangeExact = FALSE;
  seg_base_type->timescale = 1;

  /* Inherit attribute values from parent */
  if (parent) {
    seg_base_type->timescale = parent->timescale;
    seg_base_type->presentationTimeOffset = parent->presentationTimeOffset;
    seg_base_type->indexRange = gst_mpdparser_clone_range (parent->indexRange);
    seg_base_type->indexRangeExact = parent->indexRangeExact;
    seg_base_type->Initialization =
        gst_mpdparser_clone_URL (parent->Initialization);
    seg_base_type->RepresentationIndex =
        gst_mpdparser_clone_URL (parent->RepresentationIndex);
  }

  /* We must retrieve each value first to see if it exists.  If it does not
   * exist, we do not want to overwrite an inherited value */
  GST_LOG ("attributes of SegmentBaseType extension:");
  if (gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "timescale", 1,
          &intval)) {
    seg_base_type->timescale = intval;
  }
  if (gst_mpdparser_get_xml_prop_unsigned_integer_64 (a_node,
          "presentationTimeOffset", 0, &int64val)) {
    seg_base_type->presentationTimeOffset = int64val;
  }
  if (gst_mpdparser_get_xml_prop_range (a_node, "indexRange", &rangeval)) {
    if (seg_base_type->indexRange) {
      g_slice_free (GstRange, seg_base_type->indexRange);
    }
    seg_base_type->indexRange = rangeval;
  }
  if (gst_mpdparser_get_xml_prop_boolean (a_node, "indexRangeExact",
          FALSE, &boolval)) {
    seg_base_type->indexRangeExact = boolval;
  }

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "Initialization") == 0 ||
          xmlStrcmp (cur_node->name, (xmlChar *) "Initialisation") == 0) {
        /* parse will free the previous pointer to create a new one */
        gst_mpdparser_parse_url_type_node (&seg_base_type->Initialization,
            cur_node);
      } else if (xmlStrcmp (cur_node->name,
              (xmlChar *) "RepresentationIndex") == 0) {
        /* parse will free the previous pointer to create a new one */
        gst_mpdparser_parse_url_type_node (&seg_base_type->RepresentationIndex,
            cur_node);
      }
    }
  }
}

static GstSNode *
gst_mpdparser_clone_s_node (GstSNode * pointer)
{
  GstSNode *clone = NULL;

  if (pointer) {
    clone = g_slice_new0 (GstSNode);
    clone->t = pointer->t;
    clone->d = pointer->d;
    clone->r = pointer->r;
  }

  return clone;
}

static void
gst_mpdparser_parse_s_node (GQueue * queue, xmlNode * a_node)
{
  GstSNode *new_s_node;

  new_s_node = g_slice_new0 (GstSNode);
  g_queue_push_tail (queue, new_s_node);

  GST_LOG ("attributes of S node:");
  gst_mpdparser_get_xml_prop_unsigned_integer_64 (a_node, "t", 0,
      &new_s_node->t);
  gst_mpdparser_get_xml_prop_unsigned_integer_64 (a_node, "d", 0,
      &new_s_node->d);
  gst_mpdparser_get_xml_prop_signed_integer (a_node, "r", 0, &new_s_node->r);
}

static GstSegmentTimelineNode *
gst_mpdparser_clone_segment_timeline (GstSegmentTimelineNode * pointer)
{
  GstSegmentTimelineNode *clone = NULL;

  if (pointer) {
    clone = gst_mpdparser_segment_timeline_node_new ();
    if (clone) {
      GList *list;
      for (list = g_queue_peek_head_link (&pointer->S); list;
          list = g_list_next (list)) {
        GstSNode *s_node;
        s_node = (GstSNode *) list->data;
        if (s_node) {
          g_queue_push_tail (&clone->S, gst_mpdparser_clone_s_node (s_node));
        }
      }
    } else {
      GST_WARNING ("Allocation of SegmentTimeline node failed!");
    }
  }

  return clone;
}

static void
gst_mpdparser_parse_segment_timeline_node (GstSegmentTimelineNode ** pointer,
    xmlNode * a_node)
{
  xmlNode *cur_node;
  GstSegmentTimelineNode *new_seg_timeline;

  gst_mpdparser_free_segment_timeline_node (*pointer);
  *pointer = new_seg_timeline = gst_mpdparser_segment_timeline_node_new ();
  if (new_seg_timeline == NULL) {
    GST_WARNING ("Allocation of SegmentTimeline node failed!");
    return;
  }

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "S") == 0) {
        gst_mpdparser_parse_s_node (&new_seg_timeline->S, cur_node);
      }
    }
  }
}

static gboolean
gst_mpdparser_parse_mult_seg_base_type_ext (GstMultSegmentBaseType ** pointer,
    xmlNode * a_node, GstMultSegmentBaseType * parent)
{
  xmlNode *cur_node;
  GstMultSegmentBaseType *mult_seg_base_type;
  guint intval;
  gboolean has_timeline = FALSE, has_duration = FALSE;

  gst_mpdparser_free_mult_seg_base_type_ext (*pointer);
  mult_seg_base_type = g_slice_new0 (GstMultSegmentBaseType);

  mult_seg_base_type->duration = 0;
  mult_seg_base_type->startNumber = 1;

  /* Inherit attribute values from parent */
  if (parent) {
    mult_seg_base_type->duration = parent->duration;
    mult_seg_base_type->startNumber = parent->startNumber;
    mult_seg_base_type->SegmentTimeline =
        gst_mpdparser_clone_segment_timeline (parent->SegmentTimeline);
    mult_seg_base_type->BitstreamSwitching =
        gst_mpdparser_clone_URL (parent->BitstreamSwitching);
  }

  GST_LOG ("attributes of MultipleSegmentBaseType extension:");
  if (gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "duration", 0,
          &intval)) {
    mult_seg_base_type->duration = intval;
  }

  /* duration might be specified from parent */
  if (mult_seg_base_type->duration)
    has_duration = TRUE;

  if (gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "startNumber", 1,
          &intval)) {
    mult_seg_base_type->startNumber = intval;
  }

  GST_LOG ("extension of MultipleSegmentBaseType extension:");
  gst_mpdparser_parse_seg_base_type_ext (&mult_seg_base_type->SegBaseType,
      a_node, (parent ? parent->SegBaseType : NULL));

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentTimeline") == 0) {
        /* parse frees the segmenttimeline if any */
        gst_mpdparser_parse_segment_timeline_node
            (&mult_seg_base_type->SegmentTimeline, cur_node);
      } else if (xmlStrcmp (cur_node->name,
              (xmlChar *) "BitstreamSwitching") == 0) {
        /* parse frees the old url before setting the new one */
        gst_mpdparser_parse_url_type_node
            (&mult_seg_base_type->BitstreamSwitching, cur_node);
      }
    }
  }

  has_timeline = mult_seg_base_type->SegmentTimeline != NULL;

  /* Checking duration and timeline only at Representation's child level */
  if (xmlStrcmp (a_node->parent->name, (xmlChar *) "Representation") == 0
      && !has_duration && !has_timeline) {
    GST_ERROR ("segment has neither duration nor timeline");
    goto error;
  }

  *pointer = mult_seg_base_type;
  return TRUE;

error:
  gst_mpdparser_free_mult_seg_base_type_ext (mult_seg_base_type);
  return FALSE;
}

static gboolean
gst_mpdparser_parse_segment_list_node (GstSegmentListNode ** pointer,
    xmlNode * a_node, GstSegmentListNode * parent)
{
  xmlNode *cur_node;
  GstSegmentListNode *new_segment_list;
  gchar *actuate;
  gboolean segment_urls_inherited_from_parent = FALSE;

  gst_mpdparser_free_segment_list_node (*pointer);
  new_segment_list = g_slice_new0 (GstSegmentListNode);

  /* Inherit attribute values from parent */
  if (parent) {
    GList *list;
    GstSegmentURLNode *seg_url;
    for (list = g_list_first (parent->SegmentURL); list;
        list = g_list_next (list)) {
      seg_url = (GstSegmentURLNode *) list->data;
      new_segment_list->SegmentURL =
          g_list_append (new_segment_list->SegmentURL,
          gst_mpdparser_clone_segment_url (seg_url));
      segment_urls_inherited_from_parent = TRUE;
    }
  }

  new_segment_list->actuate = GST_XLINK_ACTUATE_ON_REQUEST;
  if (gst_mpdparser_get_xml_ns_prop_string (a_node,
          "http://www.w3.org/1999/xlink", "href", &new_segment_list->xlink_href)
      && gst_mpdparser_get_xml_ns_prop_string (a_node,
          "http://www.w3.org/1999/xlink", "actuate", &actuate)) {
    if (strcmp (actuate, "onLoad") == 0)
      new_segment_list->actuate = GST_XLINK_ACTUATE_ON_LOAD;
    xmlFree (actuate);
  }

  GST_LOG ("extension of SegmentList node:");
  if (!gst_mpdparser_parse_mult_seg_base_type_ext
      (&new_segment_list->MultSegBaseType, a_node,
          (parent ? parent->MultSegBaseType : NULL)))
    goto error;

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentURL") == 0) {
        if (segment_urls_inherited_from_parent) {
          /*
           * SegmentBase, SegmentTemplate and SegmentList shall inherit
           * attributes and elements from the same element on a higher level.
           * If the same attribute or element is present on both levels,
           * the one on the lower level shall take precedence over the one
           * on the higher level.
           */

          /* Clear the list of inherited segment URLs */
          g_list_free_full (new_segment_list->SegmentURL,
              (GDestroyNotify) gst_mpdparser_free_segment_url_node);
          new_segment_list->SegmentURL = NULL;

          /* mark the fact that we cleared the list, so that it is not tried again */
          segment_urls_inherited_from_parent = FALSE;
        }
        gst_mpdparser_parse_segment_url_node (&new_segment_list->SegmentURL,
            cur_node);
      }
    }
  }

  *pointer = new_segment_list;
  return TRUE;

error:
  gst_mpdparser_free_segment_list_node (new_segment_list);
  return FALSE;
}

static void
gst_mpdparser_parse_content_protection_node (GList ** list, xmlNode * a_node)
{
  gchar *value = NULL;
  if (gst_mpdparser_get_xml_prop_string (a_node, "value", &value)) {
    if (!g_strcmp0 (value, "MSPR 2.0")) {
      xmlNode *cur_node;
      for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
        if (cur_node->type == XML_ELEMENT_NODE) {
          if (xmlStrcmp (cur_node->name, (xmlChar *) "pro") == 0) {
            GstDescriptorType *new_descriptor;
            new_descriptor = g_slice_new0 (GstDescriptorType);
            *list = g_list_append (*list, new_descriptor);

            gst_mpdparser_get_xml_prop_string_stripped (a_node, "schemeIdUri",
                &new_descriptor->schemeIdUri);

            gst_mpdparser_get_xml_node_content (cur_node,
                &new_descriptor->value);
            goto beach;
          }
        }
      }
    } else {
      gst_mpdparser_parse_descriptor_type_node (list, a_node);
    }
  } else {
    gst_mpdparser_parse_descriptor_type_node (list, a_node);
  }
beach:
  if (value)
    g_free (value);
}

static void
gst_mpdparser_parse_representation_base_type (GstRepresentationBaseType **
    pointer, xmlNode * a_node)
{
  xmlNode *cur_node;
  GstRepresentationBaseType *representation_base;

  gst_mpdparser_free_representation_base_type (*pointer);
  *pointer = representation_base = g_slice_new0 (GstRepresentationBaseType);

  GST_LOG ("attributes of RepresentationBaseType extension:");
  gst_mpdparser_get_xml_prop_string (a_node, "profiles",
      &representation_base->profiles);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "width", 0,
      &representation_base->width);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "height", 0,
      &representation_base->height);
  gst_mpdparser_get_xml_prop_ratio (a_node, "sar", &representation_base->sar);
  gst_mpdparser_get_xml_prop_framerate (a_node, "frameRate",
      &representation_base->frameRate);
  gst_mpdparser_get_xml_prop_framerate (a_node, "minFrameRate",
      &representation_base->minFrameRate);
  gst_mpdparser_get_xml_prop_framerate (a_node, "maxFrameRate",
      &representation_base->maxFrameRate);
  gst_mpdparser_get_xml_prop_string (a_node, "audioSamplingRate",
      &representation_base->audioSamplingRate);
  gst_mpdparser_get_xml_prop_string (a_node, "mimeType",
      &representation_base->mimeType);
  gst_mpdparser_get_xml_prop_string (a_node, "segmentProfiles",
      &representation_base->segmentProfiles);
  gst_mpdparser_get_xml_prop_string (a_node, "codecs",
      &representation_base->codecs);
  gst_mpdparser_get_xml_prop_double (a_node, "maximumSAPPeriod",
      &representation_base->maximumSAPPeriod);
  gst_mpdparser_get_xml_prop_SAP_type (a_node, "startWithSAP",
      &representation_base->startWithSAP);
  gst_mpdparser_get_xml_prop_double (a_node, "maxPlayoutRate",
      &representation_base->maxPlayoutRate);
  gst_mpdparser_get_xml_prop_boolean (a_node, "codingDependency",
      FALSE, &representation_base->codingDependency);
  gst_mpdparser_get_xml_prop_string (a_node, "scanType",
      &representation_base->scanType);

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "FramePacking") == 0) {
        gst_mpdparser_parse_descriptor_type_node
            (&representation_base->FramePacking, cur_node);
      } else if (xmlStrcmp (cur_node->name,
              (xmlChar *) "AudioChannelConfiguration") == 0) {
        gst_mpdparser_parse_descriptor_type_node
            (&representation_base->AudioChannelConfiguration, cur_node);
      } else if (xmlStrcmp (cur_node->name,
              (xmlChar *) "ContentProtection") == 0) {
        gst_mpdparser_parse_content_protection_node
            (&representation_base->ContentProtection, cur_node);
      }
    }
  }
}

static gboolean
gst_mpdparser_parse_representation_node (GList ** list, xmlNode * a_node,
    GstAdaptationSetNode * parent, GstPeriodNode * period_node)
{
  xmlNode *cur_node;
  GstRepresentationNode *new_representation;

  new_representation = g_slice_new0 (GstRepresentationNode);

  GST_LOG ("attributes of Representation node:");
  if (!gst_mpdparser_get_xml_prop_string_no_whitespace (a_node, "id",
          &new_representation->id)) {
    GST_ERROR ("Cannot parse Representation id, invalid manifest");
    goto error;
  }
  if (!gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "bandwidth", 0,
          &new_representation->bandwidth)) {
    GST_ERROR ("Cannot parse Representation bandwidth, invalid manifest");
    goto error;
  }
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "qualityRanking", 0,
      &new_representation->qualityRanking);
  gst_mpdparser_get_xml_prop_string_vector_type (a_node, "dependencyId",
      &new_representation->dependencyId);
  gst_mpdparser_get_xml_prop_string_vector_type (a_node,
      "mediaStreamStructureId", &new_representation->mediaStreamStructureId);

  /* RepresentationBase extension */
  gst_mpdparser_parse_representation_base_type
      (&new_representation->RepresentationBase, a_node);

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentBase") == 0) {
        gst_mpdparser_parse_seg_base_type_ext (&new_representation->SegmentBase,
            cur_node, parent->SegmentBase ?
            parent->SegmentBase : period_node->SegmentBase);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentTemplate") == 0) {
        if (!gst_mpdparser_parse_segment_template_node
            (&new_representation->SegmentTemplate, cur_node,
                parent->SegmentTemplate ?
                parent->SegmentTemplate : period_node->SegmentTemplate))
          goto error;
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentList") == 0) {
        if (!gst_mpdparser_parse_segment_list_node
            (&new_representation->SegmentList, cur_node,
                parent->SegmentList ? parent->
                SegmentList : period_node->SegmentList))
          goto error;
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "BaseURL") == 0) {
        gst_mpdparser_parse_baseURL_node (&new_representation->BaseURLs,
            cur_node);
      } else if (xmlStrcmp (cur_node->name,
              (xmlChar *) "SubRepresentation") == 0) {
        gst_mpdparser_parse_subrepresentation_node
            (&new_representation->SubRepresentations, cur_node);
      }
    }
  }

  /* some sanity checking */

  *list = g_list_append (*list, new_representation);
  return TRUE;

error:
  gst_mpdparser_free_representation_node (new_representation);
  return FALSE;
}

static gboolean
gst_mpdparser_parse_adaptation_set_node (GList ** list, xmlNode * a_node,
    GstPeriodNode * parent)
{
  xmlNode *cur_node;
  GstAdaptationSetNode *new_adap_set;
  gchar *actuate;

  new_adap_set = g_slice_new0 (GstAdaptationSetNode);

  GST_LOG ("attributes of AdaptationSet node:");

  new_adap_set->actuate = GST_XLINK_ACTUATE_ON_REQUEST;
  if (gst_mpdparser_get_xml_ns_prop_string (a_node,
          "http://www.w3.org/1999/xlink", "href", &new_adap_set->xlink_href)
      && gst_mpdparser_get_xml_ns_prop_string (a_node,
          "http://www.w3.org/1999/xlink", "actuate", &actuate)) {
    if (strcmp (actuate, "onLoad") == 0)
      new_adap_set->actuate = GST_XLINK_ACTUATE_ON_LOAD;
    xmlFree (actuate);
  }

  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "id", 0,
      &new_adap_set->id);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "group", 0,
      &new_adap_set->group);
  gst_mpdparser_get_xml_prop_string (a_node, "lang", &new_adap_set->lang);
  gst_mpdparser_get_xml_prop_string (a_node, "contentType",
      &new_adap_set->contentType);
  gst_mpdparser_get_xml_prop_ratio (a_node, "par", &new_adap_set->par);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "minBandwidth", 0,
      &new_adap_set->minBandwidth);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "maxBandwidth", 0,
      &new_adap_set->maxBandwidth);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "minWidth", 0,
      &new_adap_set->minWidth);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "maxWidth", 0,
      &new_adap_set->maxWidth);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "minHeight", 0,
      &new_adap_set->minHeight);
  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "maxHeight", 0,
      &new_adap_set->maxHeight);
  gst_mpdparser_get_xml_prop_cond_uint (a_node, "segmentAlignment",
      &new_adap_set->segmentAlignment);
  gst_mpdparser_get_xml_prop_boolean (a_node, "bitstreamSwitching",
      parent->bitstreamSwitching, &new_adap_set->bitstreamSwitching);
  if (parent->bitstreamSwitching && !new_adap_set->bitstreamSwitching) {
    /* according to the standard, if the Period's bitstreamSwitching attribute
     * is true, the AdaptationSet should not have the bitstreamSwitching
     * attribute set to false.
     * We should return a parsing error, but we are generous and ignore the
     * standard violation.
     */
    new_adap_set->bitstreamSwitching = parent->bitstreamSwitching;
  }
  gst_mpdparser_get_xml_prop_cond_uint (a_node, "subsegmentAlignment",
      &new_adap_set->subsegmentAlignment);
  gst_mpdparser_get_xml_prop_SAP_type (a_node, "subsegmentStartsWithSAP",
      &new_adap_set->subsegmentStartsWithSAP);

  /* RepresentationBase extension */
  gst_mpdparser_parse_representation_base_type
      (&new_adap_set->RepresentationBase, a_node);

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "Accessibility") == 0) {
        gst_mpdparser_parse_descriptor_type_node (&new_adap_set->Accessibility,
            cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Role") == 0) {
        gst_mpdparser_parse_descriptor_type_node (&new_adap_set->Role,
            cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Rating") == 0) {
        gst_mpdparser_parse_descriptor_type_node (&new_adap_set->Rating,
            cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Viewpoint") == 0) {
        gst_mpdparser_parse_descriptor_type_node (&new_adap_set->Viewpoint,
            cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "BaseURL") == 0) {
        gst_mpdparser_parse_baseURL_node (&new_adap_set->BaseURLs, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentBase") == 0) {
        gst_mpdparser_parse_seg_base_type_ext (&new_adap_set->SegmentBase,
            cur_node, parent->SegmentBase);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentList") == 0) {
        if (!gst_mpdparser_parse_segment_list_node (&new_adap_set->SegmentList,
                cur_node, parent->SegmentList))
          goto error;
      } else if (xmlStrcmp (cur_node->name,
              (xmlChar *) "ContentComponent") == 0) {
        gst_mpdparser_parse_content_component_node
            (&new_adap_set->ContentComponents, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentTemplate") == 0) {
        if (!gst_mpdparser_parse_segment_template_node
            (&new_adap_set->SegmentTemplate, cur_node, parent->SegmentTemplate))
          goto error;
      }
    }
  }

  /* We must parse Representation after everything else in the AdaptationSet
   * has been parsed because certain Representation child elements can inherit
   * attributes specified by the same element in the AdaptationSet
   */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "Representation") == 0) {
        if (!gst_mpdparser_parse_representation_node
            (&new_adap_set->Representations, cur_node, new_adap_set, parent))
          goto error;
      }
    }
  }

  *list = g_list_append (*list, new_adap_set);
  return TRUE;

error:
  gst_mpdparser_free_adaptation_set_node (new_adap_set);
  return FALSE;
}

static void
gst_mpdparser_parse_subset_node (GList ** list, xmlNode * a_node)
{
  GstSubsetNode *new_subset;

  new_subset = g_slice_new0 (GstSubsetNode);
  *list = g_list_append (*list, new_subset);

  GST_LOG ("attributes of Subset node:");
  gst_mpdparser_get_xml_prop_uint_vector_type (a_node, "contains",
      &new_subset->contains, &new_subset->size);
}

static gboolean
gst_mpdparser_parse_segment_template_node (GstSegmentTemplateNode ** pointer,
    xmlNode * a_node, GstSegmentTemplateNode * parent)
{
  GstSegmentTemplateNode *new_segment_template;
  gchar *strval;

  gst_mpdparser_free_segment_template_node (*pointer);
  new_segment_template = g_slice_new0 (GstSegmentTemplateNode);

  GST_LOG ("extension of SegmentTemplate node:");
  if (!gst_mpdparser_parse_mult_seg_base_type_ext
      (&new_segment_template->MultSegBaseType, a_node,
          (parent ? parent->MultSegBaseType : NULL)))
    goto error;

  /* Inherit attribute values from parent when the value isn't found */
  GST_LOG ("attributes of SegmentTemplate node:");
  if (gst_mpdparser_get_xml_prop_string (a_node, "media", &strval)) {
    new_segment_template->media = strval;
  } else if (parent) {
    new_segment_template->media = xmlMemStrdup (parent->media);
  }

  if (gst_mpdparser_get_xml_prop_string (a_node, "index", &strval)) {
    new_segment_template->index = strval;
  } else if (parent) {
    new_segment_template->index = xmlMemStrdup (parent->index);
  }

  if (gst_mpdparser_get_xml_prop_string (a_node, "initialization", &strval)) {
    new_segment_template->initialization = strval;
  } else if (parent) {
    new_segment_template->initialization =
        xmlMemStrdup (parent->initialization);
  }

  if (gst_mpdparser_get_xml_prop_string (a_node, "bitstreamSwitching", &strval)) {
    new_segment_template->bitstreamSwitching = strval;
  } else if (parent) {
    new_segment_template->bitstreamSwitching =
        xmlMemStrdup (parent->bitstreamSwitching);
  }

  *pointer = new_segment_template;
  return TRUE;

error:
  gst_mpdparser_free_segment_template_node (new_segment_template);
  return FALSE;
}

static gboolean
gst_mpdparser_parse_period_node (GList ** list, xmlNode * a_node)
{
  xmlNode *cur_node;
  GstPeriodNode *new_period;
  gchar *actuate;

  new_period = g_slice_new0 (GstPeriodNode);

  GST_LOG ("attributes of Period node:");

  new_period->actuate = GST_XLINK_ACTUATE_ON_REQUEST;
  if (gst_mpdparser_get_xml_ns_prop_string (a_node,
          "http://www.w3.org/1999/xlink", "href", &new_period->xlink_href)
      && gst_mpdparser_get_xml_ns_prop_string (a_node,
          "http://www.w3.org/1999/xlink", "actuate", &actuate)) {
    if (strcmp (actuate, "onLoad") == 0)
      new_period->actuate = GST_XLINK_ACTUATE_ON_LOAD;
    xmlFree (actuate);
  }

  gst_mpdparser_get_xml_prop_string (a_node, "id", &new_period->id);
  gst_mpdparser_get_xml_prop_duration (a_node, "start", GST_MPD_DURATION_NONE,
      &new_period->start);
  gst_mpdparser_get_xml_prop_duration (a_node, "duration",
      GST_MPD_DURATION_NONE, &new_period->duration);
  gst_mpdparser_get_xml_prop_boolean (a_node, "bitstreamSwitching", FALSE,
      &new_period->bitstreamSwitching);

  /* explore children nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentBase") == 0) {
        gst_mpdparser_parse_seg_base_type_ext (&new_period->SegmentBase,
            cur_node, NULL);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentList") == 0) {
        if (!gst_mpdparser_parse_segment_list_node (&new_period->SegmentList,
                cur_node, NULL))
          goto error;
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentTemplate") == 0) {
        if (!gst_mpdparser_parse_segment_template_node
            (&new_period->SegmentTemplate, cur_node, NULL))
          goto error;
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Subset") == 0) {
        gst_mpdparser_parse_subset_node (&new_period->Subsets, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "BaseURL") == 0) {
        gst_mpdparser_parse_baseURL_node (&new_period->BaseURLs, cur_node);
      }
    }
  }

  /* We must parse AdaptationSet after everything else in the Period has been
   * parsed because certain AdaptationSet child elements can inherit attributes
   * specified by the same element in the Period
   */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "AdaptationSet") == 0) {
        if (!gst_mpdparser_parse_adaptation_set_node
            (&new_period->AdaptationSets, cur_node, new_period))
          goto error;
      }
    }
  }

  *list = g_list_append (*list, new_period);
  return TRUE;

error:
  gst_mpdparser_free_period_node (new_period);
  return FALSE;
}

static void
gst_mpdparser_parse_program_info_node (GList ** list, xmlNode * a_node)
{
  xmlNode *cur_node;
  GstProgramInformationNode *new_prog_info;

  new_prog_info = g_slice_new0 (GstProgramInformationNode);
  *list = g_list_append (*list, new_prog_info);

  GST_LOG ("attributes of ProgramInformation node:");
  gst_mpdparser_get_xml_prop_string (a_node, "lang", &new_prog_info->lang);
  gst_mpdparser_get_xml_prop_string (a_node, "moreInformationURL",
      &new_prog_info->moreInformationURL);

  /* explore children nodes */
  GST_LOG ("children of ProgramInformation node:");
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "Title") == 0) {
        gst_mpdparser_get_xml_node_content (cur_node, &new_prog_info->Title);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Source") == 0) {
        gst_mpdparser_get_xml_node_content (cur_node, &new_prog_info->Source);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Copyright") == 0) {
        gst_mpdparser_get_xml_node_content (cur_node,
            &new_prog_info->Copyright);
      }
    }
  }
}

static void
gst_mpdparser_parse_metrics_range_node (GList ** list, xmlNode * a_node)
{
  GstMetricsRangeNode *new_metrics_range;

  new_metrics_range = g_slice_new0 (GstMetricsRangeNode);
  *list = g_list_append (*list, new_metrics_range);

  GST_LOG ("attributes of Metrics Range node:");
  gst_mpdparser_get_xml_prop_duration (a_node, "starttime",
      GST_MPD_DURATION_NONE, &new_metrics_range->starttime);
  gst_mpdparser_get_xml_prop_duration (a_node, "duration",
      GST_MPD_DURATION_NONE, &new_metrics_range->duration);
}

static void
gst_mpdparser_parse_metrics_node (GList ** list, xmlNode * a_node)
{
  xmlNode *cur_node;
  GstMetricsNode *new_metrics;

  new_metrics = g_slice_new0 (GstMetricsNode);
  *list = g_list_append (*list, new_metrics);

  GST_LOG ("attributes of Metrics node:");
  gst_mpdparser_get_xml_prop_string (a_node, "metrics", &new_metrics->metrics);

  /* explore children nodes */
  GST_LOG ("children of Metrics node:");
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "Range") == 0) {
        gst_mpdparser_parse_metrics_range_node (&new_metrics->MetricsRanges,
            cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Reporting") == 0) {
        /* No reporting scheme is specified in this part of ISO/IEC 23009.
         * It is expected that external specifications may define formats
         * and delivery for the reporting data. */
        GST_LOG (" - Reporting node found (unknown structure)");
      }
    }
  }
}

/* The UTCTiming element is defined in
 * ISO/IEC 23009-1:2014/PDAM 1 "Information technology — Dynamic adaptive streaming over HTTP (DASH) — Part 1: Media presentation description and segment formats / Amendment 1: High Profile and Availability Time Synchronization"
 */
static void
gst_mpdparser_parse_utctiming_node (GList ** list, xmlNode * a_node)
{
  GstUTCTimingNode *new_timing;
  gchar *method = NULL;
  gchar *value = NULL;

  new_timing = g_slice_new0 (GstUTCTimingNode);

  GST_LOG ("attributes of UTCTiming node:");
  if (gst_mpdparser_get_xml_prop_string (a_node, "schemeIdUri", &method)) {
    int i;

    for (i = 0; gst_mpdparser_utc_timing_methods[i].name; ++i) {
      if (g_ascii_strncasecmp (gst_mpdparser_utc_timing_methods[i].name,
              method, strlen (gst_mpdparser_utc_timing_methods[i].name)) == 0) {
        new_timing->method = gst_mpdparser_utc_timing_methods[i].method;
        break;
      }
    }
    xmlFree (method);
  }

  if (gst_mpdparser_get_xml_prop_string (a_node, "value", &value)) {
    int max_tokens = 0;
    if (GST_MPD_UTCTIMING_TYPE_DIRECT == new_timing->method) {
      /* The GST_MPD_UTCTIMING_TYPE_DIRECT method is a special case
       * that is not a space separated list.
       */
      max_tokens = 1;
    }
    new_timing->urls = g_strsplit (value, " ", max_tokens);
    xmlFree (value);
  }

  /* append to list only if both method and urls were set */
  if (new_timing->method != 0 && new_timing->urls != NULL &&
      g_strv_length (new_timing->urls) != 0) {
    *list = g_list_append (*list, new_timing);
  } else {
    gst_mpdparser_free_utctiming_node (new_timing);
  }
}

static gboolean
gst_mpdparser_parse_root_node (GstMPDNode ** pointer, xmlNode * a_node)
{
  xmlNode *cur_node;
  GstMPDNode *new_mpd;

  gst_mpdparser_free_mpd_node (*pointer);
  *pointer = NULL;
  new_mpd = g_slice_new0 (GstMPDNode);

  GST_LOG ("namespaces of root MPD node:");
  new_mpd->default_namespace =
      gst_mpdparser_get_xml_node_namespace (a_node, NULL);
  new_mpd->namespace_xsi = gst_mpdparser_get_xml_node_namespace (a_node, "xsi");
  new_mpd->namespace_ext = gst_mpdparser_get_xml_node_namespace (a_node, "ext");

  GST_LOG ("attributes of root MPD node:");
  gst_mpdparser_get_xml_prop_string (a_node, "schemaLocation",
      &new_mpd->schemaLocation);
  gst_mpdparser_get_xml_prop_string (a_node, "id", &new_mpd->id);
  gst_mpdparser_get_xml_prop_string (a_node, "profiles", &new_mpd->profiles);
  gst_mpdparser_get_xml_prop_type (a_node, "type", &new_mpd->type);
  gst_mpdparser_get_xml_prop_dateTime (a_node, "availabilityStartTime",
      &new_mpd->availabilityStartTime);
  gst_mpdparser_get_xml_prop_dateTime (a_node, "availabilityEndTime",
      &new_mpd->availabilityEndTime);
  gst_mpdparser_get_xml_prop_duration (a_node, "mediaPresentationDuration",
      GST_MPD_DURATION_NONE, &new_mpd->mediaPresentationDuration);
  gst_mpdparser_get_xml_prop_duration (a_node, "minimumUpdatePeriod",
      GST_MPD_DURATION_NONE, &new_mpd->minimumUpdatePeriod);
  gst_mpdparser_get_xml_prop_duration (a_node, "minBufferTime",
      GST_MPD_DURATION_NONE, &new_mpd->minBufferTime);
  gst_mpdparser_get_xml_prop_duration (a_node, "timeShiftBufferDepth",
      GST_MPD_DURATION_NONE, &new_mpd->timeShiftBufferDepth);
  gst_mpdparser_get_xml_prop_duration (a_node, "suggestedPresentationDelay",
      GST_MPD_DURATION_NONE, &new_mpd->suggestedPresentationDelay);
  gst_mpdparser_get_xml_prop_duration (a_node, "maxSegmentDuration",
      GST_MPD_DURATION_NONE, &new_mpd->maxSegmentDuration);
  gst_mpdparser_get_xml_prop_duration (a_node, "maxSubsegmentDuration",
      GST_MPD_DURATION_NONE, &new_mpd->maxSubsegmentDuration);

  /* explore children Period nodes */
  for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
    if (cur_node->type == XML_ELEMENT_NODE) {
      if (xmlStrcmp (cur_node->name, (xmlChar *) "Period") == 0) {
        if (!gst_mpdparser_parse_period_node (&new_mpd->Periods, cur_node))
          goto error;
      } else if (xmlStrcmp (cur_node->name,
              (xmlChar *) "ProgramInformation") == 0) {
        gst_mpdparser_parse_program_info_node (&new_mpd->ProgramInfo, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "BaseURL") == 0) {
        gst_mpdparser_parse_baseURL_node (&new_mpd->BaseURLs, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Location") == 0) {
        gst_mpdparser_parse_location_node (&new_mpd->Locations, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "Metrics") == 0) {
        gst_mpdparser_parse_metrics_node (&new_mpd->Metrics, cur_node);
      } else if (xmlStrcmp (cur_node->name, (xmlChar *) "UTCTiming") == 0) {
        gst_mpdparser_parse_utctiming_node (&new_mpd->UTCTiming, cur_node);
      }
    }
  }

  *pointer = new_mpd;
  return TRUE;

error:
  gst_mpdparser_free_mpd_node (new_mpd);
  return FALSE;
}

/* comparison functions */
static int
strncmp_ext (const char *s1, const char *s2)
{
  if (s1 == NULL && s2 == NULL)
    return 0;
  if (s1 == NULL && s2 != NULL)
    return 1;
  if (s2 == NULL && s1 != NULL)
    return 1;
  return strncmp (s1, s2, strlen (s2));
}

/* navigation functions */
static GstStreamMimeType
gst_mpdparser_representation_get_mimetype (GstAdaptationSetNode * adapt_set,
    GstRepresentationNode * rep)
{
  gchar *mime = NULL;
  if (rep->RepresentationBase)
    mime = rep->RepresentationBase->mimeType;
  if (mime == NULL && adapt_set->RepresentationBase) {
    mime = adapt_set->RepresentationBase->mimeType;
  }

  if (strncmp_ext (mime, "audio") == 0)
    return GST_STREAM_AUDIO;
  if (strncmp_ext (mime, "video") == 0)
    return GST_STREAM_VIDEO;
  if (strncmp_ext (mime, "application") == 0)
    return GST_STREAM_APPLICATION;

  return GST_STREAM_UNKNOWN;
}

static GstRepresentationNode *
gst_mpdparser_get_lowest_representation (GList * Representations)
{
  GList *list = NULL;
  GstRepresentationNode *rep = NULL;
  GstRepresentationNode *lowest = NULL;

  if (Representations == NULL)
    return NULL;

  for (list = g_list_first (Representations); list; list = g_list_next (list)) {
    rep = (GstRepresentationNode *) list->data;
    if (rep && (!lowest || rep->bandwidth < lowest->bandwidth)) {
      lowest = rep;
    }
  }

  return lowest;
}

#if 0
static GstRepresentationNode *
gst_mpdparser_get_highest_representation (GList * Representations)
{
  GList *list = NULL;

  if (Representations == NULL)
    return NULL;

  list = g_list_last (Representations);

  return list ? (GstRepresentationNode *) list->data : NULL;
}

static GstRepresentationNode *
gst_mpdparser_get_representation_with_max_bandwidth (GList * Representations,
    gint max_bandwidth)
{
  GList *list = NULL;
  GstRepresentationNode *representation, *best_rep = NULL;

  if (Representations == NULL)
    return NULL;

  if (max_bandwidth <= 0)       /* 0 => get highest representation available */
    return gst_mpdparser_get_highest_representation (Representations);

  for (list = g_list_first (Representations); list; list = g_list_next (list)) {
    representation = (GstRepresentationNode *) list->data;
    if (representation && representation->bandwidth <= max_bandwidth) {
      best_rep = representation;
    }
  }

  return best_rep;
}
#endif

static GstSegmentBaseType *
gst_mpdparser_get_segment_base (GstPeriodNode * Period,
    GstAdaptationSetNode * AdaptationSet,
    GstRepresentationNode * Representation)
{
  GstSegmentBaseType *SegmentBase = NULL;

  if (Representation && Representation->SegmentBase) {
    SegmentBase = Representation->SegmentBase;
  } else if (AdaptationSet && AdaptationSet->SegmentBase) {
    SegmentBase = AdaptationSet->SegmentBase;
  } else if (Period && Period->SegmentBase) {
    SegmentBase = Period->SegmentBase;
  }
  /* the SegmentBase element could be encoded also inside a SegmentList element */
  if (SegmentBase == NULL) {
    if (Representation && Representation->SegmentList
        && Representation->SegmentList->MultSegBaseType
        && Representation->SegmentList->MultSegBaseType->SegBaseType) {
      SegmentBase = Representation->SegmentList->MultSegBaseType->SegBaseType;
    } else if (AdaptationSet && AdaptationSet->SegmentList
        && AdaptationSet->SegmentList->MultSegBaseType
        && AdaptationSet->SegmentList->MultSegBaseType->SegBaseType) {
      SegmentBase = AdaptationSet->SegmentList->MultSegBaseType->SegBaseType;
    } else if (Period && Period->SegmentList
        && Period->SegmentList->MultSegBaseType
        && Period->SegmentList->MultSegBaseType->SegBaseType) {
      SegmentBase = Period->SegmentList->MultSegBaseType->SegBaseType;
    }
  }

  return SegmentBase;
}

gint
gst_mpdparser_get_rep_idx_with_min_bandwidth (GList * Representations)
{
  GList *list = NULL, *lowest = NULL;
  GstRepresentationNode *rep = NULL;
  gint lowest_bandwidth = -1;

  if (Representations == NULL)
    return -1;

  for (list = g_list_first (Representations); list; list = g_list_next (list)) {
    rep = (GstRepresentationNode *) list->data;
    if (rep && (!lowest || rep->bandwidth < lowest_bandwidth)) {
      lowest = list;
      lowest_bandwidth = rep->bandwidth;
    }
  }

  return lowest ? g_list_position (Representations, lowest) : -1;
}

gint
gst_mpdparser_get_rep_idx_with_max_bandwidth (GList * Representations,
    gint max_bandwidth, gint max_video_width, gint max_video_height, gint
    max_video_framerate_n, gint max_video_framerate_d)
{
  GList *list = NULL, *best = NULL;
  GstRepresentationNode *representation;
  gint best_bandwidth = 0;

  GST_DEBUG ("max_bandwidth = %i", max_bandwidth);

  if (Representations == NULL)
    return -1;

  if (max_bandwidth <= 0)       /* 0 => get lowest representation available */
    return gst_mpdparser_get_rep_idx_with_min_bandwidth (Representations);

  for (list = g_list_first (Representations); list; list = g_list_next (list)) {
    GstFrameRate *framerate = NULL;

    representation = (GstRepresentationNode *) list->data;

    /* FIXME: Really? */
    if (!representation)
      continue;

    framerate = representation->RepresentationBase->frameRate;
    if (!framerate)
      framerate = representation->RepresentationBase->maxFrameRate;

    if (framerate && max_video_framerate_n > 0) {
      if (gst_util_fraction_compare (framerate->num, framerate->den,
              max_video_framerate_n, max_video_framerate_d) > 0)
        continue;
    }

    if (max_video_width > 0
        && representation->RepresentationBase->width > max_video_width)
      continue;
    if (max_video_height > 0
        && representation->RepresentationBase->height > max_video_height)
      continue;

    if (representation->bandwidth <= max_bandwidth &&
        representation->bandwidth > best_bandwidth) {
      best = list;
      best_bandwidth = representation->bandwidth;
    }
  }

  return best ? g_list_position (Representations, best) : -1;
}

static GstSegmentListNode *
gst_mpd_client_fetch_external_segment_list (GstMpdClient * client,
    GstPeriodNode * Period,
    GstAdaptationSetNode * AdaptationSet,
    GstRepresentationNode * Representation,
    GstSegmentListNode * parent, GstSegmentListNode * segment_list)
{
  GstFragment *download;
  GstBuffer *segment_list_buffer;
  GstMapInfo map;
  GError *err = NULL;
  xmlDocPtr doc = NULL;
  GstUri *base_uri, *uri;
  gchar *query = NULL;
  gchar *uri_string;
  GstSegmentListNode *new_segment_list = NULL;

  /* ISO/IEC 23009-1:2014 5.5.3 4)
   * Remove nodes that resolve to nothing when resolving
   */
  if (strcmp (segment_list->xlink_href,
          "urn:mpeg:dash:resolve-to-zero:2013") == 0) {
    return NULL;
  }

  if (!client->downloader) {
    return NULL;
  }

  /* Build absolute URI */

  /* Get base URI at the MPD level */
  base_uri =
      gst_uri_from_string (client->
      mpd_base_uri ? client->mpd_base_uri : client->mpd_uri);

  /* combine a BaseURL at the MPD level with the current base url */
  base_uri = combine_urls (base_uri, client->mpd_node->BaseURLs, &query, 0);

  /* combine a BaseURL at the Period level with the current base url */
  base_uri = combine_urls (base_uri, Period->BaseURLs, &query, 0);

  if (AdaptationSet) {
    /* combine a BaseURL at the AdaptationSet level with the current base url */
    base_uri = combine_urls (base_uri, AdaptationSet->BaseURLs, &query, 0);

    if (Representation) {
      /* combine a BaseURL at the Representation level with the current base url */
      base_uri = combine_urls (base_uri, Representation->BaseURLs, &query, 0);
    }
  }

  uri = gst_uri_from_string_with_base (base_uri, segment_list->xlink_href);
  if (query)
    gst_uri_set_query_string (uri, query);
  g_free (query);
  uri_string = gst_uri_to_string (uri);
  gst_uri_unref (base_uri);
  gst_uri_unref (uri);

  download =
      gst_uri_downloader_fetch_uri (client->downloader,
      uri_string, client->mpd_uri, TRUE, FALSE, TRUE, &err);
  g_free (uri_string);

  if (!download) {
    GST_ERROR ("Failed to download external SegmentList node at '%s': %s",
        segment_list->xlink_href, err->message);
    g_clear_error (&err);
    return NULL;
  }

  segment_list_buffer = gst_fragment_get_buffer (download);
  g_object_unref (download);

  gst_buffer_map (segment_list_buffer, &map, GST_MAP_READ);

  doc =
      xmlReadMemory ((const gchar *) map.data, map.size, "noname.xml", NULL,
      XML_PARSE_NONET);

  gst_buffer_unmap (segment_list_buffer, &map);
  gst_buffer_unref (segment_list_buffer);

  /* NOTE: ISO/IEC 23009-1:2014 5.3.9.3.2 is saying that one or multiple SegmentList
   * in external xml is allowed, however, multiple SegmentList does not make sense
   * because Period/AdaptationSet/Representation allow only one SegmentList */
  if (doc) {
    xmlNode *root_element = xmlDocGetRootElement (doc);

    if (root_element->type != XML_ELEMENT_NODE ||
        xmlStrcmp (root_element->name, (xmlChar *) "SegmentList") != 0) {
      goto error;
    }

    gst_mpdparser_parse_segment_list_node (&new_segment_list, root_element,
        parent);
  } else {
    goto error;
  }

done:
  if (doc)
    xmlFreeDoc (doc);

  return new_segment_list;

error:
  GST_ERROR ("Failed to parse segment list node XML");
  goto done;
}

static GstSegmentListNode *
gst_mpdparser_get_segment_list (GstMpdClient * client, GstPeriodNode * Period,
    GstAdaptationSetNode * AdaptationSet,
    GstRepresentationNode * Representation)
{
  GstSegmentListNode **SegmentList;
  GstSegmentListNode *ParentSegmentList = NULL;

  if (Representation && Representation->SegmentList) {
    SegmentList = &Representation->SegmentList;
    ParentSegmentList = AdaptationSet->SegmentList;
  } else if (AdaptationSet && AdaptationSet->SegmentList) {
    SegmentList = &AdaptationSet->SegmentList;
    ParentSegmentList = Period->SegmentList;
    Representation = NULL;
  } else {
    Representation = NULL;
    AdaptationSet = NULL;
    SegmentList = &Period->SegmentList;
  }

  /* Resolve external segment list here. */
  if (*SegmentList && (*SegmentList)->xlink_href) {
    GstSegmentListNode *new_segment_list;

    /* TODO: Use SegmentList of parent if
     * - Parent has its own SegmentList
     * - Fail to get SegmentList from external xml
     */
    new_segment_list =
        gst_mpd_client_fetch_external_segment_list (client, Period,
        AdaptationSet, Representation, ParentSegmentList, *SegmentList);

    gst_mpdparser_free_segment_list_node (*SegmentList);
    *SegmentList = new_segment_list;
  }

  return *SegmentList;
}

/* memory management functions */
static void
gst_mpdparser_free_mpd_node (GstMPDNode * mpd_node)
{
  if (mpd_node) {
    if (mpd_node->default_namespace)
      xmlFree (mpd_node->default_namespace);
    if (mpd_node->namespace_xsi)
      xmlFree (mpd_node->namespace_xsi);
    if (mpd_node->namespace_ext)
      xmlFree (mpd_node->namespace_ext);
    if (mpd_node->schemaLocation)
      xmlFree (mpd_node->schemaLocation);
    if (mpd_node->id)
      xmlFree (mpd_node->id);
    if (mpd_node->profiles)
      xmlFree (mpd_node->profiles);
    if (mpd_node->availabilityStartTime)
      gst_date_time_unref (mpd_node->availabilityStartTime);
    if (mpd_node->availabilityEndTime)
      gst_date_time_unref (mpd_node->availabilityEndTime);
    g_list_free_full (mpd_node->ProgramInfo,
        (GDestroyNotify) gst_mpdparser_free_prog_info_node);
    g_list_free_full (mpd_node->BaseURLs,
        (GDestroyNotify) gst_mpdparser_free_base_url_node);
    g_list_free_full (mpd_node->Locations, (GDestroyNotify) xmlFree);
    g_list_free_full (mpd_node->Periods,
        (GDestroyNotify) gst_mpdparser_free_period_node);
    g_list_free_full (mpd_node->Metrics,
        (GDestroyNotify) gst_mpdparser_free_metrics_node);
    g_list_free_full (mpd_node->UTCTiming,
        (GDestroyNotify) gst_mpdparser_free_utctiming_node);
    g_slice_free (GstMPDNode, mpd_node);
  }
}

static void
gst_mpdparser_free_prog_info_node (GstProgramInformationNode * prog_info_node)
{
  if (prog_info_node) {
    if (prog_info_node->lang)
      xmlFree (prog_info_node->lang);
    if (prog_info_node->moreInformationURL)
      xmlFree (prog_info_node->moreInformationURL);
    if (prog_info_node->Title)
      xmlFree (prog_info_node->Title);
    if (prog_info_node->Source)
      xmlFree (prog_info_node->Source);
    if (prog_info_node->Copyright)
      xmlFree (prog_info_node->Copyright);
    g_slice_free (GstProgramInformationNode, prog_info_node);
  }
}

static void
gst_mpdparser_free_metrics_node (GstMetricsNode * metrics_node)
{
  if (metrics_node) {
    if (metrics_node->metrics)
      xmlFree (metrics_node->metrics);
    g_list_free_full (metrics_node->MetricsRanges,
        (GDestroyNotify) gst_mpdparser_free_metrics_range_node);
    g_slice_free (GstMetricsNode, metrics_node);
  }
}

static void
gst_mpdparser_free_metrics_range_node (GstMetricsRangeNode * metrics_range_node)
{
  if (metrics_range_node) {
    g_slice_free (GstMetricsRangeNode, metrics_range_node);
  }
}

static void
gst_mpdparser_free_period_node (GstPeriodNode * period_node)
{
  if (period_node) {
    if (period_node->id)
      xmlFree (period_node->id);
    gst_mpdparser_free_seg_base_type_ext (period_node->SegmentBase);
    gst_mpdparser_free_segment_list_node (period_node->SegmentList);
    gst_mpdparser_free_segment_template_node (period_node->SegmentTemplate);
    g_list_free_full (period_node->AdaptationSets,
        (GDestroyNotify) gst_mpdparser_free_adaptation_set_node);
    g_list_free_full (period_node->Subsets,
        (GDestroyNotify) gst_mpdparser_free_subset_node);
    g_list_free_full (period_node->BaseURLs,
        (GDestroyNotify) gst_mpdparser_free_base_url_node);
    if (period_node->xlink_href)
      xmlFree (period_node->xlink_href);
    g_slice_free (GstPeriodNode, period_node);
  }
}

static void
gst_mpdparser_free_subset_node (GstSubsetNode * subset_node)
{
  if (subset_node) {
    if (subset_node->contains)
      xmlFree (subset_node->contains);
    g_slice_free (GstSubsetNode, subset_node);
  }
}

static void
gst_mpdparser_free_segment_template_node (GstSegmentTemplateNode *
    segment_template_node)
{
  if (segment_template_node) {
    if (segment_template_node->media)
      xmlFree (segment_template_node->media);
    if (segment_template_node->index)
      xmlFree (segment_template_node->index);
    if (segment_template_node->initialization)
      xmlFree (segment_template_node->initialization);
    if (segment_template_node->bitstreamSwitching)
      xmlFree (segment_template_node->bitstreamSwitching);
    /* MultipleSegmentBaseType extension */
    gst_mpdparser_free_mult_seg_base_type_ext
        (segment_template_node->MultSegBaseType);
    g_slice_free (GstSegmentTemplateNode, segment_template_node);
  }
}

static void
gst_mpdparser_free_representation_base_type (GstRepresentationBaseType *
    representation_base)
{
  if (representation_base) {
    if (representation_base->profiles)
      xmlFree (representation_base->profiles);
    g_slice_free (GstRatio, representation_base->sar);
    g_slice_free (GstFrameRate, representation_base->frameRate);
    g_slice_free (GstFrameRate, representation_base->minFrameRate);
    g_slice_free (GstFrameRate, representation_base->maxFrameRate);
    if (representation_base->audioSamplingRate)
      xmlFree (representation_base->audioSamplingRate);
    if (representation_base->mimeType)
      xmlFree (representation_base->mimeType);
    if (representation_base->segmentProfiles)
      xmlFree (representation_base->segmentProfiles);
    if (representation_base->codecs)
      xmlFree (representation_base->codecs);
    if (representation_base->scanType)
      xmlFree (representation_base->scanType);
    g_list_free_full (representation_base->FramePacking,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_list_free_full (representation_base->AudioChannelConfiguration,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_list_free_full (representation_base->ContentProtection,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_slice_free (GstRepresentationBaseType, representation_base);
  }
}

static void
gst_mpdparser_free_adaptation_set_node (GstAdaptationSetNode *
    adaptation_set_node)
{
  if (adaptation_set_node) {
    if (adaptation_set_node->lang)
      xmlFree (adaptation_set_node->lang);
    if (adaptation_set_node->contentType)
      xmlFree (adaptation_set_node->contentType);
    g_slice_free (GstRatio, adaptation_set_node->par);
    g_slice_free (GstConditionalUintType,
        adaptation_set_node->segmentAlignment);
    g_slice_free (GstConditionalUintType,
        adaptation_set_node->subsegmentAlignment);
    g_list_free_full (adaptation_set_node->Accessibility,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_list_free_full (adaptation_set_node->Role,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_list_free_full (adaptation_set_node->Rating,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_list_free_full (adaptation_set_node->Viewpoint,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    gst_mpdparser_free_representation_base_type
        (adaptation_set_node->RepresentationBase);
    gst_mpdparser_free_seg_base_type_ext (adaptation_set_node->SegmentBase);
    gst_mpdparser_free_segment_list_node (adaptation_set_node->SegmentList);
    gst_mpdparser_free_segment_template_node
        (adaptation_set_node->SegmentTemplate);
    g_list_free_full (adaptation_set_node->BaseURLs,
        (GDestroyNotify) gst_mpdparser_free_base_url_node);
    g_list_free_full (adaptation_set_node->Representations,
        (GDestroyNotify) gst_mpdparser_free_representation_node);
    g_list_free_full (adaptation_set_node->ContentComponents,
        (GDestroyNotify) gst_mpdparser_free_content_component_node);
    if (adaptation_set_node->xlink_href)
      xmlFree (adaptation_set_node->xlink_href);
    g_slice_free (GstAdaptationSetNode, adaptation_set_node);
  }
}

static void
gst_mpdparser_free_representation_node (GstRepresentationNode *
    representation_node)
{
  if (representation_node) {
    if (representation_node->id)
      xmlFree (representation_node->id);
    g_strfreev (representation_node->dependencyId);
    g_strfreev (representation_node->mediaStreamStructureId);
    gst_mpdparser_free_representation_base_type
        (representation_node->RepresentationBase);
    g_list_free_full (representation_node->SubRepresentations,
        (GDestroyNotify) gst_mpdparser_free_subrepresentation_node);
    gst_mpdparser_free_seg_base_type_ext (representation_node->SegmentBase);
    gst_mpdparser_free_segment_template_node
        (representation_node->SegmentTemplate);
    gst_mpdparser_free_segment_list_node (representation_node->SegmentList);
    g_list_free_full (representation_node->BaseURLs,
        (GDestroyNotify) gst_mpdparser_free_base_url_node);
    g_slice_free (GstRepresentationNode, representation_node);
  }
}

static void
gst_mpdparser_free_subrepresentation_node (GstSubRepresentationNode *
    subrep_node)
{
  if (subrep_node) {
    gst_mpdparser_free_representation_base_type
        (subrep_node->RepresentationBase);
    if (subrep_node->dependencyLevel)
      xmlFree (subrep_node->dependencyLevel);
    g_strfreev (subrep_node->contentComponent);
    g_slice_free (GstSubRepresentationNode, subrep_node);
  }
}

static void
gst_mpdparser_free_s_node (GstSNode * s_node)
{
  if (s_node) {
    g_slice_free (GstSNode, s_node);
  }
}

static GstSegmentTimelineNode *
gst_mpdparser_segment_timeline_node_new (void)
{
  GstSegmentTimelineNode *node = g_slice_new0 (GstSegmentTimelineNode);

  g_queue_init (&node->S);

  return node;
}

static void
gst_mpdparser_free_segment_timeline_node (GstSegmentTimelineNode * seg_timeline)
{
  if (seg_timeline) {
    g_queue_foreach (&seg_timeline->S, (GFunc) gst_mpdparser_free_s_node, NULL);
    g_queue_clear (&seg_timeline->S);
    g_slice_free (GstSegmentTimelineNode, seg_timeline);
  }
}

static void
gst_mpdparser_free_url_type_node (GstURLType * url_type_node)
{
  if (url_type_node) {
    if (url_type_node->sourceURL)
      xmlFree (url_type_node->sourceURL);
    g_slice_free (GstRange, url_type_node->range);
    g_slice_free (GstURLType, url_type_node);
  }
}

static void
gst_mpdparser_free_seg_base_type_ext (GstSegmentBaseType * seg_base_type)
{
  if (seg_base_type) {
    if (seg_base_type->indexRange)
      g_slice_free (GstRange, seg_base_type->indexRange);
    gst_mpdparser_free_url_type_node (seg_base_type->Initialization);
    gst_mpdparser_free_url_type_node (seg_base_type->RepresentationIndex);
    g_slice_free (GstSegmentBaseType, seg_base_type);
  }
}

static void
gst_mpdparser_free_mult_seg_base_type_ext (GstMultSegmentBaseType *
    mult_seg_base_type)
{
  if (mult_seg_base_type) {
    /* SegmentBaseType extension */
    gst_mpdparser_free_seg_base_type_ext (mult_seg_base_type->SegBaseType);
    gst_mpdparser_free_segment_timeline_node
        (mult_seg_base_type->SegmentTimeline);
    gst_mpdparser_free_url_type_node (mult_seg_base_type->BitstreamSwitching);
    g_slice_free (GstMultSegmentBaseType, mult_seg_base_type);
  }
}

static void
gst_mpdparser_free_segment_list_node (GstSegmentListNode * segment_list_node)
{
  if (segment_list_node) {
    g_list_free_full (segment_list_node->SegmentURL,
        (GDestroyNotify) gst_mpdparser_free_segment_url_node);
    /* MultipleSegmentBaseType extension */
    gst_mpdparser_free_mult_seg_base_type_ext
        (segment_list_node->MultSegBaseType);
    if (segment_list_node->xlink_href)
      xmlFree (segment_list_node->xlink_href);
    g_slice_free (GstSegmentListNode, segment_list_node);
  }
}

static void
gst_mpdparser_free_segment_url_node (GstSegmentURLNode * segment_url)
{
  if (segment_url) {
    if (segment_url->media)
      xmlFree (segment_url->media);
    g_slice_free (GstRange, segment_url->mediaRange);
    if (segment_url->index)
      xmlFree (segment_url->index);
    g_slice_free (GstRange, segment_url->indexRange);
    g_slice_free (GstSegmentURLNode, segment_url);
  }
}

static void
gst_mpdparser_free_base_url_node (GstBaseURL * base_url_node)
{
  if (base_url_node) {
    if (base_url_node->baseURL)
      xmlFree (base_url_node->baseURL);
    if (base_url_node->serviceLocation)
      xmlFree (base_url_node->serviceLocation);
    if (base_url_node->byteRange)
      xmlFree (base_url_node->byteRange);
    g_slice_free (GstBaseURL, base_url_node);
  }
}

static void
gst_mpdparser_free_descriptor_type_node (GstDescriptorType * descriptor_type)
{
  if (descriptor_type) {
    if (descriptor_type->schemeIdUri)
      xmlFree (descriptor_type->schemeIdUri);
    if (descriptor_type->value)
      xmlFree (descriptor_type->value);
    g_slice_free (GstDescriptorType, descriptor_type);
  }
}

static void
gst_mpdparser_free_content_component_node (GstContentComponentNode *
    content_component_node)
{
  if (content_component_node) {
    if (content_component_node->lang)
      xmlFree (content_component_node->lang);
    if (content_component_node->contentType)
      xmlFree (content_component_node->contentType);
    g_slice_free (GstRatio, content_component_node->par);
    g_list_free_full (content_component_node->Accessibility,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_list_free_full (content_component_node->Role,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_list_free_full (content_component_node->Rating,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_list_free_full (content_component_node->Viewpoint,
        (GDestroyNotify) gst_mpdparser_free_descriptor_type_node);
    g_slice_free (GstContentComponentNode, content_component_node);
  }
}

static void
gst_mpdparser_free_utctiming_node (GstUTCTimingNode * timing_type)
{
  if (timing_type) {
    if (timing_type->urls)
      g_strfreev (timing_type->urls);
    g_slice_free (GstUTCTimingNode, timing_type);
  }
}

static void
gst_mpdparser_free_stream_period (GstStreamPeriod * stream_period)
{
  if (stream_period) {
    g_slice_free (GstStreamPeriod, stream_period);
  }
}

static void
gst_mpdparser_free_media_segment (GstMediaSegment * media_segment)
{
  if (media_segment) {
    g_slice_free (GstMediaSegment, media_segment);
  }
}

static void
gst_mpdparser_init_active_stream_segments (GstActiveStream * stream)
{
  g_assert (stream->segments == NULL);
  stream->segments = g_ptr_array_new ();
  g_ptr_array_set_free_func (stream->segments,
      (GDestroyNotify) gst_mpdparser_free_media_segment);
}

static void
gst_mpdparser_free_active_stream (GstActiveStream * active_stream)
{
  if (active_stream) {
    g_free (active_stream->baseURL);
    active_stream->baseURL = NULL;
    g_free (active_stream->queryURL);
    active_stream->queryURL = NULL;
    if (active_stream->segments)
      g_ptr_array_unref (active_stream->segments);
    g_slice_free (GstActiveStream, active_stream);
  }
}

static gchar *
gst_mpdparser_get_mediaURL (GstActiveStream * stream,
    GstSegmentURLNode * segmentURL)
{
  const gchar *url_prefix;

  g_return_val_if_fail (stream != NULL, NULL);
  g_return_val_if_fail (segmentURL != NULL, NULL);

  url_prefix = segmentURL->media ? segmentURL->media : stream->baseURL;
  g_return_val_if_fail (url_prefix != NULL, NULL);

  return segmentURL->media;
}

static const gchar *
gst_mpdparser_get_initializationURL (GstActiveStream * stream,
    GstURLType * InitializationURL)
{
  const gchar *url_prefix;

  g_return_val_if_fail (stream != NULL, NULL);

  url_prefix = (InitializationURL
      && InitializationURL->sourceURL) ? InitializationURL->
      sourceURL : stream->baseURL;

  return url_prefix;
}

/* ISO/IEC 23009-1:2004 5.3.9.4.4 */
static gboolean
validate_format (const gchar * format)
{
  const gchar *p = format;

  /* Check if it starts with % */
  if (!p || p[0] != '%')
    return FALSE;
  p++;

  /* the spec mandates a format like %0[width]d */
  /* Following the %, we must have a 0 */
  if (p[0] != '0')
    return FALSE;

  /* Following the % must be a number starting with 0
   */
  while (g_ascii_isdigit (*p))
    p++;

  /* After any 0 and alphanumeric values, there must be a d.
   */
  if (p[0] != 'd')
    return FALSE;
  p++;

  /* And then potentially more characters without any
   * further %, even if the spec does not mention this
   */
  p = strchr (p, '%');
  if (p)
    return FALSE;

  return TRUE;
}

static gchar *
promote_format_to_uint64 (const gchar * format)
{
  const gchar *p = format;
  gchar *promoted_format;

  /* Must be called with a validated format! */
  g_return_val_if_fail (validate_format (format), NULL);

  /* it starts with % */
  p++;

  /* Following the % must be a 0, or any of d, x or u.
   * x and u are not part of the spec, but don't hurt us
   */
  if (p[0] == '0') {
    p++;

    while (g_ascii_isdigit (*p))
      p++;
  }

  /* After any 0 and alphanumeric values, there must be a d.
   * Otherwise validation would have failed
   */
  g_assert (p[0] == 'd');

  promoted_format =
      g_strdup_printf ("%.*s" G_GINT64_MODIFIER "%s", (gint) (p - format),
      format, p);

  return promoted_format;
}

static gboolean
gst_mpdparser_validate_rfc1738_url (const char *s)
{
  while (*s) {
    if (!strchr
        (";:@&=aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789$-_.+!*'(),%/",
            *s))
      return FALSE;
    if (*s == '%') {
      /* g_ascii_isdigit returns FALSE for NUL, and || is a short circuiting
         operator, so this is safe for strings ending before two hex digits */
      if (!g_ascii_isxdigit (s[1]) || !g_ascii_isxdigit (s[2]))
        return FALSE;
      s += 2;
    }
    s++;
  }
  return TRUE;
}

static gchar *
gst_mpdparser_build_URL_from_template (const gchar * url_template,
    const gchar * id, guint number, guint bandwidth, guint64 time)
{
  static const gchar default_format[] = "%01d";
  gchar **tokens, *token, *ret;
  const gchar *format;
  gint i, num_tokens;

  g_return_val_if_fail (url_template != NULL, NULL);
  tokens = g_strsplit_set (url_template, "$", -1);
  if (!tokens) {
    GST_WARNING ("Scan of URL template failed!");
    return NULL;
  }
  num_tokens = g_strv_length (tokens);

  /*
   * each identifier is guarded by 2 $, which means that we must have an odd number of tokens
   * An even number of tokens means the string is not valid.
   */
  if ((num_tokens & 1) == 0) {
    GST_ERROR ("Invalid number of tokens (%d). url_template is '%s'",
        num_tokens, url_template);
    g_strfreev (tokens);
    return NULL;
  }

  for (i = 0; i < num_tokens; i++) {
    token = tokens[i];
    format = default_format;

    /* the tokens to replace must be provided between $ characters, eg $token$
     * For a string like token0$token1$token2$token3$token4, only the odd number
     * tokens (1,3,...) must be parsed.
     *
     * Skip even tokens
     */
    if ((i & 1) == 0)
      continue;

    if (!g_strcmp0 (token, "RepresentationID")) {
      if (!gst_mpdparser_validate_rfc1738_url (id))
        goto invalid_representation_id;

      tokens[i] = g_strdup_printf ("%s", id);
      g_free (token);
    } else if (!strncmp (token, "Number", 6)) {
      if (strlen (token) > 6) {
        format = token + 6;     /* format tag */
      }
      if (!validate_format (format))
        goto invalid_format;

      tokens[i] = g_strdup_printf (format, number);
      g_free (token);
    } else if (!strncmp (token, "Bandwidth", 9)) {
      if (strlen (token) > 9) {
        format = token + 9;     /* format tag */
      }
      if (!validate_format (format))
        goto invalid_format;

      tokens[i] = g_strdup_printf (format, bandwidth);
      g_free (token);
    } else if (!strncmp (token, "Time", 4)) {
      gchar *promoted_format;

      if (strlen (token) > 4) {
        format = token + 4;     /* format tag */
      }
      if (!validate_format (format))
        goto invalid_format;

      promoted_format = promote_format_to_uint64 (format);
      tokens[i] = g_strdup_printf (promoted_format, time);
      g_free (promoted_format);
      g_free (token);
    } else if (!g_strcmp0 (token, "")) {
      tokens[i] = g_strdup_printf ("%s", "$");
      g_free (token);
    } else {
      /* unexpected identifier found between $ signs
       *
       * "If the URL contains unescaped $ symbols which do not enclose a valid
       * identifier then the result of URL formation is undefined"
       */
      goto invalid_format;
    }
  }

  ret = g_strjoinv (NULL, tokens);

  g_strfreev (tokens);

  return ret;

invalid_format:
  {
    GST_ERROR ("Invalid format '%s' in '%s'", format, token);

    g_strfreev (tokens);

    return NULL;
  }
invalid_representation_id:
  {
    GST_ERROR
        ("Representation ID string '%s' has characters invalid in an RFC 1738 URL",
        id);

    g_strfreev (tokens);

    return NULL;
  }
}

guint
gst_mpd_client_get_period_index_at_time (GstMpdClient * client,
    GstDateTime * time)
{
  GList *iter;
  guint period_idx = G_MAXUINT;
  guint idx;
  gint64 time_offset;
  GstDateTime *avail_start =
      gst_mpd_client_get_availability_start_time (client);
  GstStreamPeriod *stream_period;

  if (avail_start == NULL)
    return 0;

  time_offset = gst_mpd_client_calculate_time_difference (avail_start, time);
  gst_date_time_unref (avail_start);

  if (time_offset < 0)
    return 0;

  if (!gst_mpd_client_setup_media_presentation (client, time_offset, -1, NULL))
    return 0;

  for (idx = 0, iter = client->periods; iter; idx++, iter = g_list_next (iter)) {
    stream_period = iter->data;
    if (stream_period->start <= time_offset
        && (!GST_CLOCK_TIME_IS_VALID (stream_period->duration)
            || stream_period->start + stream_period->duration > time_offset)) {
      period_idx = idx;
      break;
    }
  }

  return period_idx;
}

static GstStreamPeriod *
gst_mpdparser_get_stream_period (GstMpdClient * client)
{
  g_return_val_if_fail (client != NULL, NULL);
  g_return_val_if_fail (client->periods != NULL, NULL);

  return g_list_nth_data (client->periods, client->period_idx);
}

static GstRange *
gst_mpdparser_clone_range (GstRange * range)
{
  GstRange *clone = NULL;

  if (range) {
    clone = g_slice_new0 (GstRange);
    clone->first_byte_pos = range->first_byte_pos;
    clone->last_byte_pos = range->last_byte_pos;
  }

  return clone;
}

static GstURLType *
gst_mpdparser_clone_URL (GstURLType * url)
{

  GstURLType *clone = NULL;

  if (url) {
    clone = g_slice_new0 (GstURLType);
    if (url->sourceURL) {
      clone->sourceURL = xmlMemStrdup (url->sourceURL);
    }
    clone->range = gst_mpdparser_clone_range (url->range);
  }

  return clone;
}

/*
 * Combine a base url with the current stream base url from the list of
 * baseURLs. Takes ownership of base and returns a new base.
 */
static GstUri *
combine_urls (GstUri * base, GList * list, gchar ** query, guint idx)
{
  GstBaseURL *baseURL;
  GstUri *ret = base;

  if (list != NULL) {
    baseURL = g_list_nth_data (list, idx);
    if (!baseURL) {
      baseURL = list->data;
    }

    ret = gst_uri_from_string_with_base (base, baseURL->baseURL);
    gst_uri_unref (base);

    if (ret && query) {
      g_free (*query);
      *query = gst_uri_get_query_string (ret);
      if (*query) {
        ret = gst_uri_make_writable (ret);
        gst_uri_set_query_table (ret, NULL);
      }
    }
  }

  return ret;
}

/* select a stream and extract the baseURL (if present) */
static gchar *
gst_mpdparser_parse_baseURL (GstMpdClient * client, GstActiveStream * stream,
    gchar ** query)
{
  GstStreamPeriod *stream_period;
  static const gchar empty[] = "";
  gchar *ret = NULL;
  GstUri *abs_url;

  g_return_val_if_fail (stream != NULL, g_strdup (empty));
  stream_period = gst_mpdparser_get_stream_period (client);
  g_return_val_if_fail (stream_period != NULL, g_strdup (empty));
  g_return_val_if_fail (stream_period->period != NULL, g_strdup (empty));

  /* NULLify query return before we start */
  if (query)
    *query = NULL;

  /* initialise base url */
  abs_url =
      gst_uri_from_string (client->
      mpd_base_uri ? client->mpd_base_uri : client->mpd_uri);

  /* combine a BaseURL at the MPD level with the current base url */
  abs_url =
      combine_urls (abs_url, client->mpd_node->BaseURLs, query,
      stream->baseURL_idx);

  /* combine a BaseURL at the Period level with the current base url */
  abs_url =
      combine_urls (abs_url, stream_period->period->BaseURLs, query,
      stream->baseURL_idx);

  GST_DEBUG ("Current adaptation set id %i (%s)", stream->cur_adapt_set->id,
      stream->cur_adapt_set->contentType);
  /* combine a BaseURL at the AdaptationSet level with the current base url */
  abs_url =
      combine_urls (abs_url, stream->cur_adapt_set->BaseURLs, query,
      stream->baseURL_idx);

  /* combine a BaseURL at the Representation level with the current base url */
  abs_url =
      combine_urls (abs_url, stream->cur_representation->BaseURLs, query,
      stream->baseURL_idx);

  ret = gst_uri_to_string (abs_url);
  gst_uri_unref (abs_url);

  return ret;
}

static GstClockTime
gst_mpd_client_get_segment_duration (GstMpdClient * client,
    GstActiveStream * stream, guint64 * scale_dur)
{
  GstStreamPeriod *stream_period;
  GstMultSegmentBaseType *base = NULL;
  GstClockTime duration = 0;

  g_return_val_if_fail (stream != NULL, GST_CLOCK_TIME_NONE);
  stream_period = gst_mpdparser_get_stream_period (client);
  g_return_val_if_fail (stream_period != NULL, GST_CLOCK_TIME_NONE);

  if (stream->cur_segment_list) {
    base = stream->cur_segment_list->MultSegBaseType;
  } else if (stream->cur_seg_template) {
    base = stream->cur_seg_template->MultSegBaseType;
  }

  if (base == NULL || base->SegBaseType == NULL) {
    /* this may happen when we have a single segment */
    duration = stream_period->duration;
    if (scale_dur)
      *scale_dur = duration;
  } else {
    /* duration is guint so this cannot overflow */
    duration = base->duration * GST_SECOND;
    if (scale_dur)
      *scale_dur = duration;
    duration /= base->SegBaseType->timescale;
  }

  return duration;
}

/*****************************/
/******* API functions *******/
/*****************************/

GstMpdClient *
gst_mpd_client_new (void)
{
  GstMpdClient *client;

  client = g_new0 (GstMpdClient, 1);

  return client;
}

void
gst_active_streams_free (GstMpdClient * client)
{
  if (client->active_streams) {
    g_list_foreach (client->active_streams,
        (GFunc) gst_mpdparser_free_active_stream, NULL);
    g_list_free (client->active_streams);
    client->active_streams = NULL;
  }
}

void
gst_mpd_client_free (GstMpdClient * client)
{
  g_return_if_fail (client != NULL);

  if (client->mpd_node)
    gst_mpdparser_free_mpd_node (client->mpd_node);

  if (client->periods) {
    g_list_free_full (client->periods,
        (GDestroyNotify) gst_mpdparser_free_stream_period);
  }

  gst_active_streams_free (client);

  g_free (client->mpd_uri);
  client->mpd_uri = NULL;
  g_free (client->mpd_base_uri);
  client->mpd_base_uri = NULL;

  if (client->downloader)
    gst_object_unref (client->downloader);
  client->downloader = NULL;

  g_free (client);
}

void
gst_mpd_client_set_uri_downloader (GstMpdClient * client,
    GstUriDownloader * downloader)
{
  if (client->downloader)
    gst_object_unref (client->downloader);
  client->downloader = gst_object_ref (downloader);
}

static void
gst_mpd_client_check_profiles (GstMpdClient * client)
{
  GST_DEBUG ("Profiles: %s",
      client->mpd_node->profiles ? client->mpd_node->profiles : "<none>");

  if (!client->mpd_node->profiles)
    return;

  if (g_strstr_len (client->mpd_node->profiles, -1,
          "urn:mpeg:dash:profile:isoff-on-demand:2011")) {
    client->profile_isoff_ondemand = TRUE;
    GST_DEBUG ("Found ISOFF on demand profile (2011)");
  }
}

static void
gst_mpd_client_fetch_on_load_external_resources (GstMpdClient * client)
{
  GList *l;

  for (l = client->mpd_node->Periods; l; /* explicitly advanced below */ ) {
    GstPeriodNode *period = l->data;
    GList *m;

    if (period->xlink_href && period->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
      GList *new_periods, *prev, *next;

      new_periods = gst_mpd_client_fetch_external_period (client, period);

      prev = l->prev;
      client->mpd_node->Periods =
          g_list_delete_link (client->mpd_node->Periods, l);
      gst_mpdparser_free_period_node (period);
      period = NULL;

      /* Get new next node, we will insert before this */
      if (prev)
        next = prev->next;
      else
        next = client->mpd_node->Periods;

      while (new_periods) {
        client->mpd_node->Periods =
            g_list_insert_before (client->mpd_node->Periods, next,
            new_periods->data);
        new_periods = g_list_delete_link (new_periods, new_periods);
      }
      next = NULL;

      /* Update our iterator to the first new period if any, or the next */
      if (prev)
        l = prev->next;
      else
        l = client->mpd_node->Periods;

      continue;
    }

    if (period->SegmentList && period->SegmentList->xlink_href
        && period->SegmentList->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
      GstSegmentListNode *new_segment_list;

      new_segment_list =
          gst_mpd_client_fetch_external_segment_list (client, period, NULL,
          NULL, NULL, period->SegmentList);

      gst_mpdparser_free_segment_list_node (period->SegmentList);
      period->SegmentList = new_segment_list;
    }

    for (m = period->AdaptationSets; m; /* explicitly advanced below */ ) {
      GstAdaptationSetNode *adapt_set = m->data;
      GList *n;

      if (adapt_set->xlink_href
          && adapt_set->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
        GList *new_adapt_sets, *prev, *next;

        new_adapt_sets =
            gst_mpd_client_fetch_external_adaptation_set (client, period,
            adapt_set);

        prev = l->prev;
        period->AdaptationSets = g_list_delete_link (period->AdaptationSets, l);
        gst_mpdparser_free_adaptation_set_node (adapt_set);
        adapt_set = NULL;

        /* Get new next node, we will insert before this */
        if (prev)
          next = prev->next;
        else
          next = period->AdaptationSets;

        while (new_adapt_sets) {
          period->AdaptationSets =
              g_list_insert_before (period->AdaptationSets, next,
              new_adapt_sets->data);
          new_adapt_sets = g_list_delete_link (new_adapt_sets, new_adapt_sets);
        }
        next = NULL;

        /* Update our iterator to the first new adapt_set if any, or the next */
        if (prev)
          l = prev->next;
        else
          l = period->AdaptationSets;

        continue;
      }

      if (adapt_set->SegmentList && adapt_set->SegmentList->xlink_href
          && adapt_set->SegmentList->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
        GstSegmentListNode *new_segment_list;

        new_segment_list =
            gst_mpd_client_fetch_external_segment_list (client, period,
            adapt_set, NULL, period->SegmentList, adapt_set->SegmentList);

        gst_mpdparser_free_segment_list_node (adapt_set->SegmentList);
        adapt_set->SegmentList = new_segment_list;
      }

      for (n = adapt_set->Representations; n; n = n->next) {
        GstRepresentationNode *representation = n->data;

        if (representation->SegmentList
            && representation->SegmentList->xlink_href
            && representation->SegmentList->actuate ==
            GST_XLINK_ACTUATE_ON_LOAD) {

          GstSegmentListNode *new_segment_list;

          new_segment_list =
              gst_mpd_client_fetch_external_segment_list (client, period,
              adapt_set, representation, adapt_set->SegmentList,
              representation->SegmentList);

          gst_mpdparser_free_segment_list_node (representation->SegmentList);
          representation->SegmentList = new_segment_list;

        }
      }

      m = m->next;
    }

    l = l->next;
  }
}

gboolean
gst_mpd_parse (GstMpdClient * client, const gchar * data, gint size)
{
  gboolean ret = FALSE;

  if (data) {
    xmlDocPtr doc;
    xmlNode *root_element = NULL;

    GST_DEBUG ("MPD file fully buffered, start parsing...");

    /* parse the complete MPD file into a tree (using the libxml2 default parser API) */

    /* this initialize the library and check potential ABI mismatches
     * between the version it was compiled for and the actual shared
     * library used
     */
    LIBXML_TEST_VERSION;

    /* parse "data" into a document (which is a libxml2 tree structure xmlDoc) */
    doc = xmlReadMemory (data, size, "noname.xml", NULL, XML_PARSE_NONET);
    if (doc == NULL) {
      GST_ERROR ("failed to parse the MPD file");
      ret = FALSE;
    } else {
      /* get the root element node */
      root_element = xmlDocGetRootElement (doc);

      if (root_element->type != XML_ELEMENT_NODE
          || xmlStrcmp (root_element->name, (xmlChar *) "MPD") != 0) {
        GST_ERROR
            ("can not find the root element MPD, failed to parse the MPD file");
        ret = FALSE;            /* used to return TRUE before, but this seems wrong */
      } else {
        /* now we can parse the MPD root node and all children nodes, recursively */
        ret = gst_mpdparser_parse_root_node (&client->mpd_node, root_element);
      }
      /* free the document */
      xmlFreeDoc (doc);
    }

    if (ret) {
      gst_mpd_client_check_profiles (client);
      gst_mpd_client_fetch_on_load_external_resources (client);
    }
  }

  return ret;
}

const gchar *
gst_mpdparser_get_baseURL (GstMpdClient * client, guint indexStream)
{
  GstActiveStream *stream;

  g_return_val_if_fail (client != NULL, NULL);
  g_return_val_if_fail (client->active_streams != NULL, NULL);
  stream = g_list_nth_data (client->active_streams, indexStream);
  g_return_val_if_fail (stream != NULL, NULL);

  return stream->baseURL;
}

static GstClockTime
gst_mpdparser_get_segment_end_time (GstMpdClient * client, GPtrArray * segments,
    const GstMediaSegment * segment, gint index)
{
  const GstStreamPeriod *stream_period;
  GstClockTime end;

  if (segment->repeat >= 0)
    return segment->start + (segment->repeat + 1) * segment->duration;

  if (index < segments->len - 1) {
    const GstMediaSegment *next_segment =
        g_ptr_array_index (segments, index + 1);
    end = next_segment->start;
  } else {
    stream_period = gst_mpdparser_get_stream_period (client);
    end = stream_period->start + stream_period->duration;
  }
  return end;
}

static gboolean
gst_mpd_client_add_media_segment (GstActiveStream * stream,
    GstSegmentURLNode * url_node, guint number, gint repeat,
    guint64 scale_start, guint64 scale_duration,
    GstClockTime start, GstClockTime duration)
{
  GstMediaSegment *media_segment;

  g_return_val_if_fail (stream->segments != NULL, FALSE);

  media_segment = g_slice_new0 (GstMediaSegment);

  media_segment->SegmentURL = url_node;
  media_segment->number = number;
  media_segment->scale_start = scale_start;
  media_segment->scale_duration = scale_duration;
  media_segment->start = start;
  media_segment->duration = duration;
  media_segment->repeat = repeat;

  g_ptr_array_add (stream->segments, media_segment);
  GST_LOG ("Added new segment: number %d, repeat %d, "
      "ts: %" GST_TIME_FORMAT ", dur: %"
      GST_TIME_FORMAT, number, repeat,
      GST_TIME_ARGS (start), GST_TIME_ARGS (duration));

  return TRUE;
}

static void
gst_mpd_client_stream_update_presentation_time_offset (GstMpdClient * client,
    GstActiveStream * stream)
{
  GstSegmentBaseType *segbase = NULL;

  /* Find the used segbase */
  if (stream->cur_segment_list) {
    segbase = stream->cur_segment_list->MultSegBaseType->SegBaseType;
  } else if (stream->cur_seg_template) {
    segbase = stream->cur_seg_template->MultSegBaseType->SegBaseType;
  } else if (stream->cur_segment_base) {
    segbase = stream->cur_segment_base;
  }

  if (segbase) {
    /* Avoid overflows */
    stream->presentationTimeOffset =
        gst_util_uint64_scale (segbase->presentationTimeOffset, GST_SECOND,
        segbase->timescale);
  } else {
    stream->presentationTimeOffset = 0;
  }

  GST_LOG ("Setting stream's presentation time offset to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (stream->presentationTimeOffset));
}

gboolean
gst_mpd_client_setup_representation (GstMpdClient * client,
    GstActiveStream * stream, GstRepresentationNode * representation)
{
  GstStreamPeriod *stream_period;
  GList *rep_list;
  GstClockTime PeriodStart, PeriodEnd, start_time, duration;
  guint i;
  guint64 start;

  if (stream->cur_adapt_set == NULL) {
    GST_WARNING ("No valid AdaptationSet node in the MPD file, aborting...");
    return FALSE;
  }

  rep_list = stream->cur_adapt_set->Representations;
  stream->cur_representation = representation;
  stream->representation_idx = g_list_index (rep_list, representation);

  /* clean the old segment list, if any */
  if (stream->segments) {
    g_ptr_array_unref (stream->segments);
    stream->segments = NULL;
  }

  stream_period = gst_mpdparser_get_stream_period (client);
  g_return_val_if_fail (stream_period != NULL, FALSE);
  g_return_val_if_fail (stream_period->period != NULL, FALSE);

  PeriodStart = stream_period->start;
  if (GST_CLOCK_TIME_IS_VALID (stream_period->duration))
    PeriodEnd = stream_period->start + stream_period->duration;
  else
    PeriodEnd = GST_CLOCK_TIME_NONE;

  GST_LOG ("Building segment list for Period from %" GST_TIME_FORMAT " to %"
      GST_TIME_FORMAT, GST_TIME_ARGS (PeriodStart), GST_TIME_ARGS (PeriodEnd));

  if (representation->SegmentBase != NULL
      || representation->SegmentList != NULL) {
    GList *SegmentURL;

    /* We have a fixed list of segments for any of the cases here,
     * init the segments list */
    gst_mpdparser_init_active_stream_segments (stream);

    /* get the first segment_base of the selected representation */
    if ((stream->cur_segment_base =
            gst_mpdparser_get_segment_base (stream_period->period,
                stream->cur_adapt_set, representation)) == NULL) {
      GST_DEBUG ("No useful SegmentBase node for the current Representation");
    }

    /* get the first segment_list of the selected representation */
    if ((stream->cur_segment_list =
            gst_mpdparser_get_segment_list (client, stream_period->period,
                stream->cur_adapt_set, representation)) == NULL) {
      GST_DEBUG ("No useful SegmentList node for the current Representation");
      /* here we should have a single segment for each representation, whose URL is encoded in the baseURL element */
      if (!gst_mpd_client_add_media_segment (stream, NULL, 1, 0, 0,
              PeriodEnd - PeriodStart, 0, PeriodEnd - PeriodStart)) {
        return FALSE;
      }
    } else {
      /* build the list of GstMediaSegment nodes from the SegmentList node */
      SegmentURL = stream->cur_segment_list->SegmentURL;
      if (SegmentURL == NULL) {
        GST_WARNING
            ("No valid list of SegmentURL nodes in the MPD file, aborting...");
        return FALSE;
      }

      /* build segment list */
      i = stream->cur_segment_list->MultSegBaseType->startNumber;
      start = 0;
      start_time = 0;

      GST_LOG ("Building media segment list using a SegmentList node");
      if (stream->cur_segment_list->MultSegBaseType->SegmentTimeline) {
        GstSegmentTimelineNode *timeline;
        GstSNode *S;
        GList *list;

        timeline = stream->cur_segment_list->MultSegBaseType->SegmentTimeline;
        for (list = g_queue_peek_head_link (&timeline->S); list;
            list = g_list_next (list)) {
          guint timescale;

          S = (GstSNode *) list->data;
          GST_LOG ("Processing S node: d=%" G_GUINT64_FORMAT " r=%d t=%"
              G_GUINT64_FORMAT, S->d, S->r, S->t);
          timescale =
              stream->cur_segment_list->MultSegBaseType->SegBaseType->timescale;
          duration = gst_util_uint64_scale (S->d, GST_SECOND, timescale);

          if (S->t > 0) {
            start = S->t;
            start_time = gst_util_uint64_scale (S->t, GST_SECOND, timescale);
          }

          if (!SegmentURL) {
            GST_WARNING
                ("SegmentTimeline does not have a matching SegmentURL, aborting...");
            return FALSE;
          }

          if (!gst_mpd_client_add_media_segment (stream, SegmentURL->data, i,
                  S->r, start, S->d, start_time, duration)) {
            return FALSE;
          }
          i += S->r + 1;
          start_time += duration * (S->r + 1);
          start += S->d * (S->r + 1);
          SegmentURL = g_list_next (SegmentURL);
        }
      } else {
        guint64 scale_dur;

        duration =
            gst_mpd_client_get_segment_duration (client, stream, &scale_dur);
        if (!GST_CLOCK_TIME_IS_VALID (duration))
          return FALSE;

        while (SegmentURL) {
          if (!gst_mpd_client_add_media_segment (stream, SegmentURL->data, i,
                  0, start, scale_dur, start_time, duration)) {
            return FALSE;
          }
          i++;
          start += scale_dur;
          start_time += duration;
          SegmentURL = g_list_next (SegmentURL);
        }
      }
    }
  } else {
    if (representation->SegmentTemplate != NULL) {
      stream->cur_seg_template = representation->SegmentTemplate;
    } else if (stream->cur_adapt_set->SegmentTemplate != NULL) {
      stream->cur_seg_template = stream->cur_adapt_set->SegmentTemplate;
    } else if (stream_period->period->SegmentTemplate != NULL) {
      stream->cur_seg_template = stream_period->period->SegmentTemplate;
    }

    if (stream->cur_seg_template == NULL
        || stream->cur_seg_template->MultSegBaseType == NULL) {

      gst_mpdparser_init_active_stream_segments (stream);
      /* here we should have a single segment for each representation, whose URL is encoded in the baseURL element */
      if (!gst_mpd_client_add_media_segment (stream, NULL, 1, 0, 0,
              PeriodEnd - PeriodStart, 0, PeriodEnd - PeriodStart)) {
        return FALSE;
      }
    } else {
      GstMultSegmentBaseType *mult_seg =
          stream->cur_seg_template->MultSegBaseType;
      /* build segment list */
      i = mult_seg->startNumber;
      start = 0;
      start_time = 0;

      GST_LOG ("Building media segment list using this template: %s",
          stream->cur_seg_template->media);

      if (mult_seg->SegmentTimeline) {
        GstSegmentTimelineNode *timeline;
        GstSNode *S;
        GList *list;

        timeline = mult_seg->SegmentTimeline;
        gst_mpdparser_init_active_stream_segments (stream);
        for (list = g_queue_peek_head_link (&timeline->S); list;
            list = g_list_next (list)) {
          guint timescale;

          S = (GstSNode *) list->data;
          GST_LOG ("Processing S node: d=%" G_GUINT64_FORMAT " r=%u t=%"
              G_GUINT64_FORMAT, S->d, S->r, S->t);
          timescale = mult_seg->SegBaseType->timescale;
          duration = gst_util_uint64_scale (S->d, GST_SECOND, timescale);
          if (S->t > 0) {
            start = S->t;
            start_time = gst_util_uint64_scale (S->t, GST_SECOND, timescale);
          }

          if (!gst_mpd_client_add_media_segment (stream, NULL, i, S->r, start,
                  S->d, start_time, duration)) {
            return FALSE;
          }
          i += S->r + 1;
          start += S->d * (S->r + 1);
          start_time += duration * (S->r + 1);
        }
      } else {
        /* NOP - The segment is created on demand with the template, no need
         * to build a list */
      }
    }
  }

  /* clip duration of segments to stop at period end */
  if (stream->segments && stream->segments->len) {
    if (GST_CLOCK_TIME_IS_VALID (PeriodEnd)) {
      guint n;

      for (n = 0; n < stream->segments->len; ++n) {
        GstMediaSegment *media_segment =
            g_ptr_array_index (stream->segments, n);
        if (media_segment) {
          if (media_segment->start + media_segment->duration >
              PeriodEnd - PeriodStart) {
            GstClockTime stop = PeriodEnd - PeriodStart;
            if (n < stream->segments->len - 1) {
              GstMediaSegment *next_segment =
                  g_ptr_array_index (stream->segments, n + 1);
              if (next_segment && next_segment->start < PeriodEnd - PeriodStart)
                stop = next_segment->start;
            }
            media_segment->duration =
                media_segment->start > stop ? 0 : stop - media_segment->start;
            GST_LOG ("Fixed duration of segment %u: %" GST_TIME_FORMAT, n,
                GST_TIME_ARGS (media_segment->duration));

            /* If the segment was clipped entirely, we discard it and all
             * subsequent ones */
            if (media_segment->duration == 0) {
              GST_WARNING ("Discarding %u segments outside period",
                  stream->segments->len - n);
              /* _set_size should properly unref elements */
              g_ptr_array_set_size (stream->segments, n);
              break;
            }
          }
        }
      }
    }
#ifndef GST_DISABLE_GST_DEBUG
    if (stream->segments->len > 0) {
      GstMediaSegment *last_media_segment =
          g_ptr_array_index (stream->segments, stream->segments->len - 1);
      GST_LOG ("Built a list of %d segments", last_media_segment->number);
    } else {
      GST_LOG ("All media segments were clipped");
    }
#endif
  }

  g_free (stream->baseURL);
  g_free (stream->queryURL);
  stream->baseURL =
      gst_mpdparser_parse_baseURL (client, stream, &stream->queryURL);

  gst_mpd_client_stream_update_presentation_time_offset (client, stream);

  return TRUE;
}

#define CUSTOM_WRAPPER_START "<custom_wrapper>"
#define CUSTOM_WRAPPER_END "</custom_wrapper>"

static GList *
gst_mpd_client_fetch_external_period (GstMpdClient * client,
    GstPeriodNode * period_node)
{
  GstFragment *download;
  GstAdapter *adapter;
  GstBuffer *period_buffer;
  GError *err = NULL;
  xmlDocPtr doc = NULL;
  GstUri *base_uri, *uri;
  gchar *query = NULL;
  gchar *uri_string, *wrapper;
  GList *new_periods = NULL;
  const gchar *data;

  /* ISO/IEC 23009-1:2014 5.5.3 4)
   * Remove nodes that resolve to nothing when resolving
   */
  if (strcmp (period_node->xlink_href,
          "urn:mpeg:dash:resolve-to-zero:2013") == 0) {
    return NULL;
  }

  if (!client->downloader) {
    return NULL;
  }

  /* Build absolute URI */

  /* Get base URI at the MPD level */
  base_uri =
      gst_uri_from_string (client->
      mpd_base_uri ? client->mpd_base_uri : client->mpd_uri);

  /* combine a BaseURL at the MPD level with the current base url */
  base_uri = combine_urls (base_uri, client->mpd_node->BaseURLs, &query, 0);
  uri = gst_uri_from_string_with_base (base_uri, period_node->xlink_href);
  if (query)
    gst_uri_set_query_string (uri, query);
  g_free (query);
  uri_string = gst_uri_to_string (uri);
  gst_uri_unref (base_uri);
  gst_uri_unref (uri);

  download =
      gst_uri_downloader_fetch_uri (client->downloader,
      uri_string, client->mpd_uri, TRUE, FALSE, TRUE, &err);
  g_free (uri_string);

  if (!download) {
    GST_ERROR ("Failed to download external Period node at '%s': %s",
        period_node->xlink_href, err->message);
    g_clear_error (&err);
    return NULL;
  }

  period_buffer = gst_fragment_get_buffer (download);
  g_object_unref (download);

  /* external xml could have multiple period without root xmlNode.
   * To avoid xml parsing error caused by no root node, wrapping it with
   * custom root node */
  adapter = gst_adapter_new ();

  wrapper = g_new (gchar, strlen (CUSTOM_WRAPPER_START));
  memcpy (wrapper, CUSTOM_WRAPPER_START, strlen (CUSTOM_WRAPPER_START));
  gst_adapter_push (adapter,
      gst_buffer_new_wrapped (wrapper, strlen (CUSTOM_WRAPPER_START)));

  gst_adapter_push (adapter, period_buffer);

  wrapper = g_strdup (CUSTOM_WRAPPER_END);
  gst_adapter_push (adapter,
      gst_buffer_new_wrapped (wrapper, strlen (CUSTOM_WRAPPER_END) + 1));

  data = gst_adapter_map (adapter, gst_adapter_available (adapter));

  doc =
      xmlReadMemory (data, gst_adapter_available (adapter), "noname.xml", NULL,
      XML_PARSE_NONET);

  gst_adapter_unmap (adapter);
  gst_adapter_clear (adapter);
  gst_object_unref (adapter);

  if (doc) {
    xmlNode *root_element = xmlDocGetRootElement (doc);
    xmlNode *iter;

    if (root_element->type != XML_ELEMENT_NODE)
      goto error;

    for (iter = root_element->children; iter; iter = iter->next) {
      if (iter->type == XML_ELEMENT_NODE) {
        if (xmlStrcmp (iter->name, (xmlChar *) "Period") == 0) {
          gst_mpdparser_parse_period_node (&new_periods, iter);
        } else {
          goto error;
        }
      }
    }
  } else {
    goto error;
  }

done:
  if (doc)
    xmlFreeDoc (doc);

  return new_periods;

error:
  GST_ERROR ("Failed to parse period node XML");

  if (new_periods) {
    g_list_free_full (new_periods,
        (GDestroyNotify) gst_mpdparser_free_period_node);
    new_periods = NULL;
  }
  goto done;
}

gboolean
gst_mpd_client_setup_media_presentation (GstMpdClient * client,
    GstClockTime time, gint period_idx, const gchar * period_id)
{
  GstStreamPeriod *stream_period;
  GstClockTime start, duration;
  GList *list, *next;
  guint idx;
  gboolean ret = FALSE;

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

  /* Check if we set up the media presentation far enough already */
  for (list = client->periods; list; list = list->next) {
    GstStreamPeriod *stream_period = list->data;

    if ((time != GST_CLOCK_TIME_NONE
            && stream_period->duration != GST_CLOCK_TIME_NONE
            && stream_period->start + stream_period->duration >= time)
        || (time != GST_CLOCK_TIME_NONE && stream_period->start >= time))
      return TRUE;

    if (period_idx != -1 && stream_period->number >= period_idx)
      return TRUE;

    if (period_id != NULL && stream_period->period->id != NULL
        && strcmp (stream_period->period->id, period_id) == 0)
      return TRUE;

  }

  GST_DEBUG ("Building the list of Periods in the Media Presentation");
  /* clean the old period list, if any */
  /* TODO: In theory we could reuse the ones we have so far but that
   * seems more complicated than the overhead caused here
   */
  if (client->periods) {
    g_list_foreach (client->periods,
        (GFunc) gst_mpdparser_free_stream_period, NULL);
    g_list_free (client->periods);
    client->periods = NULL;
  }

  idx = 0;
  start = 0;
  duration = GST_CLOCK_TIME_NONE;

  if (client->mpd_node->mediaPresentationDuration <= 0 &&
      client->mpd_node->mediaPresentationDuration != -1) {
    /* Invalid MPD file: MPD duration is negative or zero */
    goto syntax_error;
  }

  for (list = client->mpd_node->Periods; list; /* explicitly advanced below */ ) {
    GstPeriodNode *period_node = list->data;
    GstPeriodNode *next_period_node = NULL;

    /* Download external period */
    if (period_node->xlink_href) {
      GList *new_periods;
      GList *prev;

      new_periods = gst_mpd_client_fetch_external_period (client, period_node);

      prev = list->prev;
      client->mpd_node->Periods =
          g_list_delete_link (client->mpd_node->Periods, list);
      gst_mpdparser_free_period_node (period_node);
      period_node = NULL;

      /* Get new next node, we will insert before this */
      if (prev)
        next = prev->next;
      else
        next = client->mpd_node->Periods;

      while (new_periods) {
        client->mpd_node->Periods =
            g_list_insert_before (client->mpd_node->Periods, next,
            new_periods->data);
        new_periods = g_list_delete_link (new_periods, new_periods);
      }
      next = NULL;

      /* Update our iterator to the first new period if any, or the next */
      if (prev)
        list = prev->next;
      else
        list = client->mpd_node->Periods;

      /* And try again */
      continue;
    }

    if (period_node->start != -1) {
      /* we have a regular period */
      /* start cannot be smaller than previous start */
      if (list != g_list_first (client->mpd_node->Periods)
          && start >= period_node->start * GST_MSECOND) {
        /* Invalid MPD file: duration would be negative or zero */
        goto syntax_error;
      }
      start = period_node->start * GST_MSECOND;
    } else if (duration != GST_CLOCK_TIME_NONE) {
      /* start time inferred from previous period, this is still a regular period */
      start += duration;
    } else if (idx == 0 && client->mpd_node->type == GST_MPD_FILE_TYPE_STATIC) {
      /* first period of a static MPD file, start time is 0 */
      start = 0;
    } else if (client->mpd_node->type == GST_MPD_FILE_TYPE_DYNAMIC) {
      /* this should be a live stream, let this pass */
    } else {
      /* this is an 'Early Available Period' */
      goto early;
    }

    /* compute duration.
       If there is a start time for the next period, or this is the last period
       and mediaPresentationDuration was set, those values will take precedence
       over a configured period duration in computing this period's duration

       ISO/IEC 23009-1:2014(E), chapter 5.3.2.1
       "The Period extends until the PeriodStart of the next Period, or until
       the end of the Media Presentation in the case of the last Period."
     */

    while ((next = g_list_next (list)) != NULL) {
      /* try to infer this period duration from the start time of the next period */
      next_period_node = next->data;

      if (next_period_node->xlink_href) {
        GList *new_periods;

        new_periods =
            gst_mpd_client_fetch_external_period (client, next_period_node);

        client->mpd_node->Periods =
            g_list_delete_link (client->mpd_node->Periods, next);
        gst_mpdparser_free_period_node (next_period_node);
        next_period_node = NULL;
        /* Get new next node, we will insert before this */
        next = g_list_next (list);
        while (new_periods) {
          client->mpd_node->Periods =
              g_list_insert_before (client->mpd_node->Periods, next,
              new_periods->data);
          new_periods = g_list_delete_link (new_periods, new_periods);
        }

        /* And try again, getting the next list element which is now our newly
         * inserted nodes. If any */
      } else {
        /* Got the next period and it doesn't have to be downloaded first */
        break;
      }
    }

    if (next_period_node) {
      if (next_period_node->start != -1) {
        if (start >= next_period_node->start * GST_MSECOND) {
          /* Invalid MPD file: duration would be negative or zero */
          goto syntax_error;
        }
        duration = next_period_node->start * GST_MSECOND - start;
      } else if (period_node->duration != -1) {
        if (period_node->duration <= 0) {
          /* Invalid MPD file: duration would be negative or zero */
          goto syntax_error;
        }
        duration = period_node->duration * GST_MSECOND;
      } else if (client->mpd_node->type == GST_MPD_FILE_TYPE_DYNAMIC) {
        /* might be a live file, ignore unspecified duration */
      } else {
        /* Invalid MPD file! */
        goto syntax_error;
      }
    } else if (client->mpd_node->mediaPresentationDuration != -1) {
      /* last Period of the Media Presentation */
      if (client->mpd_node->mediaPresentationDuration * GST_MSECOND <= start) {
        /* Invalid MPD file: duration would be negative or zero */
        goto syntax_error;
      }
      duration =
          client->mpd_node->mediaPresentationDuration * GST_MSECOND - start;
    } else if (period_node->duration != -1) {
      duration = period_node->duration * GST_MSECOND;
    } else if (client->mpd_node->type == GST_MPD_FILE_TYPE_DYNAMIC) {
      /* might be a live file, ignore unspecified duration */
    } else {
      /* Invalid MPD file! */
      goto syntax_error;
    }

    stream_period = g_slice_new0 (GstStreamPeriod);
    client->periods = g_list_append (client->periods, stream_period);
    stream_period->period = period_node;
    stream_period->number = idx++;
    stream_period->start = start;
    stream_period->duration = duration;
    ret = TRUE;
    GST_LOG (" - added Period %d start=%" GST_TIME_FORMAT " duration=%"
        GST_TIME_FORMAT, idx, GST_TIME_ARGS (start), GST_TIME_ARGS (duration));

    if ((time != GST_CLOCK_TIME_NONE
            && stream_period->duration != GST_CLOCK_TIME_NONE
            && stream_period->start + stream_period->duration >= time)
        || (time != GST_CLOCK_TIME_NONE && stream_period->start >= time))
      break;

    if (period_idx != -1 && stream_period->number >= period_idx)
      break;

    if (period_id != NULL && stream_period->period->id != NULL
        && strcmp (stream_period->period->id, period_id) == 0)
      break;

    list = list->next;
  }

  GST_DEBUG
      ("Found a total of %d valid Periods in the Media Presentation up to this point",
      idx);
  return ret;

early:
  GST_WARNING
      ("Found an Early Available Period, skipping the rest of the Media Presentation");
  return ret;

syntax_error:
  GST_WARNING
      ("Cannot get the duration of the Period %d, skipping the rest of the Media Presentation",
      idx);
  return ret;
}

static GList *
gst_mpd_client_fetch_external_adaptation_set (GstMpdClient * client,
    GstPeriodNode * period, GstAdaptationSetNode * adapt_set)
{
  GstFragment *download;
  GstBuffer *adapt_set_buffer;
  GstMapInfo map;
  GError *err = NULL;
  xmlDocPtr doc = NULL;
  GstUri *base_uri, *uri;
  gchar *query = NULL;
  gchar *uri_string;
  GList *new_adapt_sets = NULL;

  /* ISO/IEC 23009-1:2014 5.5.3 4)
   * Remove nodes that resolve to nothing when resolving
   */
  if (strcmp (adapt_set->xlink_href, "urn:mpeg:dash:resolve-to-zero:2013") == 0) {
    return NULL;
  }

  if (!client->downloader) {
    return NULL;
  }

  /* Build absolute URI */

  /* Get base URI at the MPD level */
  base_uri =
      gst_uri_from_string (client->
      mpd_base_uri ? client->mpd_base_uri : client->mpd_uri);

  /* combine a BaseURL at the MPD level with the current base url */
  base_uri = combine_urls (base_uri, client->mpd_node->BaseURLs, &query, 0);

  /* combine a BaseURL at the Period level with the current base url */
  base_uri = combine_urls (base_uri, period->BaseURLs, &query, 0);

  uri = gst_uri_from_string_with_base (base_uri, adapt_set->xlink_href);
  if (query)
    gst_uri_set_query_string (uri, query);
  g_free (query);
  uri_string = gst_uri_to_string (uri);
  gst_uri_unref (base_uri);
  gst_uri_unref (uri);

  download =
      gst_uri_downloader_fetch_uri (client->downloader,
      uri_string, client->mpd_uri, TRUE, FALSE, TRUE, &err);
  g_free (uri_string);

  if (!download) {
    GST_ERROR ("Failed to download external AdaptationSet node at '%s': %s",
        adapt_set->xlink_href, err->message);
    g_clear_error (&err);
    return NULL;
  }

  adapt_set_buffer = gst_fragment_get_buffer (download);
  g_object_unref (download);

  gst_buffer_map (adapt_set_buffer, &map, GST_MAP_READ);

  doc =
      xmlReadMemory ((const gchar *) map.data, map.size, "noname.xml", NULL,
      XML_PARSE_NONET);

  gst_buffer_unmap (adapt_set_buffer, &map);
  gst_buffer_unref (adapt_set_buffer);

  /* NOTE: ISO/IEC 23009-1:2014 5.3.3.2 is saying that exactly one AdaptationSet
   * in external xml is allowed */
  if (doc) {
    xmlNode *root_element = xmlDocGetRootElement (doc);

    if (root_element->type != XML_ELEMENT_NODE ||
        xmlStrcmp (root_element->name, (xmlChar *) "AdaptationSet") != 0) {
      goto error;
    }

    gst_mpdparser_parse_adaptation_set_node (&new_adapt_sets, root_element,
        period);
  } else {
    goto error;
  }

done:
  if (doc)
    xmlFreeDoc (doc);

  return new_adapt_sets;

error:
  GST_ERROR ("Failed to parse adaptation set node XML");
  goto done;
}

static GList *
gst_mpd_client_get_adaptation_sets_for_period (GstMpdClient * client,
    GstStreamPeriod * period)
{
  GList *list;

  g_return_val_if_fail (period != NULL, NULL);

  /* Resolve all external adaptation sets of this period. Every user of
   * the adaptation sets would need to know the content of all adaptation sets
   * to decide which one to use, so we have to resolve them all here
   */
  for (list = period->period->AdaptationSets; list;
      /* advanced explicitely below */ ) {
    GstAdaptationSetNode *adapt_set = (GstAdaptationSetNode *) list->data;
    GList *new_adapt_sets = NULL, *prev, *next;

    if (!adapt_set->xlink_href) {
      list = list->next;
      continue;
    }

    new_adapt_sets =
        gst_mpd_client_fetch_external_adaptation_set (client, period->period,
        adapt_set);

    prev = list->prev;
    period->period->AdaptationSets =
        g_list_delete_link (period->period->AdaptationSets, list);
    gst_mpdparser_free_adaptation_set_node (adapt_set);
    adapt_set = NULL;

    /* Get new next node, we will insert before this */
    if (prev)
      next = prev->next;
    else
      next = period->period->AdaptationSets;

    while (new_adapt_sets) {
      period->period->AdaptationSets =
          g_list_insert_before (period->period->AdaptationSets, next,
          new_adapt_sets->data);
      new_adapt_sets = g_list_delete_link (new_adapt_sets, new_adapt_sets);
    }

    /* Update our iterator to the first new adaptation set if any, or the next */
    if (prev)
      list = prev->next;
    else
      list = period->period->AdaptationSets;
  }

  return period->period->AdaptationSets;
}

GList *
gst_mpd_client_get_adaptation_sets (GstMpdClient * client)
{
  GstStreamPeriod *stream_period;

  stream_period = gst_mpdparser_get_stream_period (client);
  if (stream_period == NULL || stream_period->period == NULL) {
    GST_DEBUG ("No more Period nodes in the MPD file, terminating...");
    return NULL;
  }

  return gst_mpd_client_get_adaptation_sets_for_period (client, stream_period);
}

gboolean
gst_mpd_client_setup_streaming (GstMpdClient * client,
    GstAdaptationSetNode * adapt_set)
{
  GstRepresentationNode *representation;
  GList *rep_list = NULL;
  GstActiveStream *stream;

  rep_list = adapt_set->Representations;
  if (!rep_list) {
    GST_WARNING ("Can not retrieve any representation, aborting...");
    return FALSE;
  }

  stream = g_slice_new0 (GstActiveStream);
  gst_mpdparser_init_active_stream_segments (stream);

  stream->baseURL_idx = 0;
  stream->cur_adapt_set = adapt_set;

  GST_DEBUG ("0. Current stream %p", stream);

  /* retrieve representation list */
  if (stream->cur_adapt_set != NULL)
    rep_list = stream->cur_adapt_set->Representations;

#if 0
  /* fast start */
  representation =
      gst_mpdparser_get_representation_with_max_bandwidth (rep_list,
      stream->max_bandwidth);

  if (!representation) {
    GST_WARNING
        ("Can not retrieve a representation with the requested bandwidth");
    representation = gst_mpdparser_get_lowest_representation (rep_list);
  }
#else
  /* slow start */
  representation = gst_mpdparser_get_lowest_representation (rep_list);
#endif

  if (!representation) {
    GST_WARNING ("No valid representation in the MPD file, aborting...");
    g_slice_free (GstActiveStream, stream);
    return FALSE;
  }
  stream->mimeType =
      gst_mpdparser_representation_get_mimetype (adapt_set, representation);
  if (stream->mimeType == GST_STREAM_UNKNOWN) {
    GST_WARNING ("Unknown mime type in the representation, aborting...");
    g_slice_free (GstActiveStream, stream);
    return FALSE;
  }

  client->active_streams = g_list_append (client->active_streams, stream);
  if (!gst_mpd_client_setup_representation (client, stream, representation)) {
    GST_WARNING ("Failed to setup the representation, aborting...");
    return FALSE;
  }

  GST_INFO ("Successfully setup the download pipeline for mimeType %d",
      stream->mimeType);

  return TRUE;
}

gboolean
gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream,
    gboolean forward, GstSeekFlags flags, GstClockTime ts,
    GstClockTime * final_ts)
{
  gint index = 0;
  gint repeat_index = 0;
  GstMediaSegment *selectedChunk = NULL;

  g_return_val_if_fail (stream != NULL, 0);

  if (stream->segments) {
    for (index = 0; index < stream->segments->len; index++) {
      gboolean in_segment = FALSE;
      GstMediaSegment *segment = g_ptr_array_index (stream->segments, index);
      GstClockTime end_time;

      GST_DEBUG ("Looking at fragment sequence chunk %d / %d", index,
          stream->segments->len);

      end_time =
          gst_mpdparser_get_segment_end_time (client, stream->segments,
          segment, index);

      /* avoid downloading another fragment just for 1ns in reverse mode */
      if (forward)
        in_segment = ts < end_time;
      else
        in_segment = ts <= end_time;

      if (in_segment) {
        GstClockTime chunk_time;

        selectedChunk = segment;
        repeat_index = (ts - segment->start) / segment->duration;

        chunk_time = segment->start + segment->duration * repeat_index;

        /* At the end of a segment in reverse mode, start from the previous fragment */
        if (!forward && repeat_index > 0
            && ((ts - segment->start) % segment->duration == 0))
          repeat_index--;

        if ((flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST) {
          if (repeat_index + 1 < segment->repeat) {
            if (ts - chunk_time > chunk_time + segment->duration - ts)
              repeat_index++;
          } else if (index + 1 < stream->segments->len) {
            GstMediaSegment *next_segment =
                g_ptr_array_index (stream->segments, index + 1);

            if (ts - chunk_time > next_segment->start - ts) {
              repeat_index = 0;
              selectedChunk = next_segment;
              index++;
            }
          }
        } else if (((forward && flags & GST_SEEK_FLAG_SNAP_AFTER) ||
                (!forward && flags & GST_SEEK_FLAG_SNAP_BEFORE)) &&
            ts != chunk_time) {

          if (repeat_index + 1 < segment->repeat) {
            repeat_index++;
          } else {
            repeat_index = 0;
            if (index + 1 >= stream->segments->len) {
              selectedChunk = NULL;
            } else {
              selectedChunk = g_ptr_array_index (stream->segments, ++index);
            }
          }
        }
        break;
      }
    }

    if (selectedChunk == NULL) {
      stream->segment_index = stream->segments->len;
      stream->segment_repeat_index = 0;
      GST_DEBUG ("Seek to after last segment");
      return FALSE;
    }

    if (final_ts)
      *final_ts = selectedChunk->start + selectedChunk->duration * repeat_index;
  } else {
    GstClockTime duration =
        gst_mpd_client_get_segment_duration (client, stream, NULL);
    GstStreamPeriod *stream_period = gst_mpdparser_get_stream_period (client);
    guint segments_count = gst_mpd_client_get_segments_counts (client, stream);
    GstClockTime index_time;

    g_return_val_if_fail (stream->cur_seg_template->
        MultSegBaseType->SegmentTimeline == NULL, FALSE);
    if (!GST_CLOCK_TIME_IS_VALID (duration)) {
      return FALSE;
    }

    if (ts > stream_period->start)
      ts -= stream_period->start;
    else
      ts = 0;

    index = ts / duration;

    /* At the end of a segment in reverse mode, start from the previous fragment */
    if (!forward && index > 0 && ts % duration == 0)
      index--;

    index_time = index * duration;

    if ((flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST) {
      if (ts - index_time > index_time + duration - ts)
        index++;
    } else if (((forward && flags & GST_SEEK_FLAG_SNAP_AFTER) ||
            (!forward && flags & GST_SEEK_FLAG_SNAP_BEFORE))
        && ts != index_time) {
      index++;
    }

    if (segments_count > 0 && index >= segments_count) {
      stream->segment_index = segments_count;
      stream->segment_repeat_index = 0;
      GST_DEBUG ("Seek to after last segment");
      return FALSE;
    }
    if (final_ts)
      *final_ts = index * duration;
  }

  stream->segment_repeat_index = repeat_index;
  stream->segment_index = index;

  return TRUE;
}

gint64
gst_mpd_client_calculate_time_difference (const GstDateTime * t1,
    const GstDateTime * t2)
{
  GDateTime *gdt1, *gdt2;
  GTimeSpan diff;

  g_assert (t1 != NULL && t2 != NULL);
  gdt1 = gst_date_time_to_g_date_time ((GstDateTime *) t1);
  gdt2 = gst_date_time_to_g_date_time ((GstDateTime *) t2);
  diff = g_date_time_difference (gdt2, gdt1);
  g_date_time_unref (gdt1);
  g_date_time_unref (gdt2);
  return diff * GST_USECOND;
}

GstDateTime *
gst_mpd_client_add_time_difference (GstDateTime * t1, gint64 usecs)
{
  GDateTime *gdt;
  GDateTime *gdt2;
  GstDateTime *rv;

  g_assert (t1 != NULL);
  gdt = gst_date_time_to_g_date_time (t1);
  g_assert (gdt != NULL);
  gdt2 = g_date_time_add (gdt, usecs);
  g_assert (gdt2 != NULL);
  g_date_time_unref (gdt);
  rv = gst_date_time_new_from_g_date_time (gdt2);

  /* Don't g_date_time_unref(gdt2) because gst_date_time_new_from_g_date_time takes
   * ownership of the GDateTime pointer.
   */

  return rv;
}

static GstDateTime *
gst_mpd_client_get_availability_start_time (GstMpdClient * client)
{
  GstDateTime *start_time;

  if (client == NULL)
    return (GstDateTime *) NULL;

  start_time = client->mpd_node->availabilityStartTime;
  if (start_time)
    gst_date_time_ref (start_time);
  return start_time;
}

gboolean
gst_mpd_client_get_last_fragment_timestamp_end (GstMpdClient * client,
    guint stream_idx, GstClockTime * ts)
{
  GstActiveStream *stream;
  gint segment_idx;
  GstMediaSegment *currentChunk;
  GstStreamPeriod *stream_period;

  GST_DEBUG ("Stream index: %i", stream_idx);
  stream = g_list_nth_data (client->active_streams, stream_idx);
  g_return_val_if_fail (stream != NULL, 0);

  if (!stream->segments) {
    stream_period = gst_mpdparser_get_stream_period (client);
    *ts = stream_period->start + stream_period->duration;
  } else {
    segment_idx = gst_mpd_client_get_segments_counts (client, stream) - 1;
    currentChunk = g_ptr_array_index (stream->segments, segment_idx);

    if (currentChunk->repeat >= 0) {
      *ts =
          currentChunk->start + (currentChunk->duration * (1 +
              currentChunk->repeat));
    } else {
      /* 5.3.9.6.1: negative repeat means repeat till the end of the
       * period, or the next update of the MPD (which I think is
       * implicit, as this will all get deleted/recreated), or the
       * start of the next segment, if any. */
      stream_period = gst_mpdparser_get_stream_period (client);
      *ts = stream_period->start + stream_period->duration;
    }
  }

  return TRUE;
}

gboolean
gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client,
    guint stream_idx, GstClockTime * ts)
{
  GstActiveStream *stream;
  GstMediaSegment *currentChunk;

  GST_DEBUG ("Stream index: %i", stream_idx);
  stream = g_list_nth_data (client->active_streams, stream_idx);
  g_return_val_if_fail (stream != NULL, 0);

  if (stream->segments) {
    GST_DEBUG ("Looking for fragment sequence chunk %d / %d",
        stream->segment_index, stream->segments->len);
    if (stream->segment_index >= stream->segments->len)
      return FALSE;
    currentChunk = g_ptr_array_index (stream->segments, stream->segment_index);

    *ts =
        currentChunk->start +
        (currentChunk->duration * stream->segment_repeat_index);
  } else {
    GstClockTime duration =
        gst_mpd_client_get_segment_duration (client, stream, NULL);
    guint segments_count = gst_mpd_client_get_segments_counts (client, stream);

    g_return_val_if_fail (stream->cur_seg_template->
        MultSegBaseType->SegmentTimeline == NULL, FALSE);
    if (!GST_CLOCK_TIME_IS_VALID (duration) || (segments_count > 0
            && stream->segment_index >= segments_count)) {
      return FALSE;
    }
    *ts = stream->segment_index * duration;
  }

  return TRUE;
}

GstClockTime
gst_mpd_parser_get_stream_presentation_offset (GstMpdClient * client,
    guint stream_idx)
{
  GstActiveStream *stream = NULL;

  g_return_val_if_fail (client != NULL, 0);
  g_return_val_if_fail (client->active_streams != NULL, 0);
  stream = g_list_nth_data (client->active_streams, stream_idx);
  g_return_val_if_fail (stream != NULL, 0);

  return stream->presentationTimeOffset;
}

GstClockTime
gst_mpd_parser_get_period_start_time (GstMpdClient * client)
{
  GstStreamPeriod *stream_period = NULL;

  g_return_val_if_fail (client != NULL, 0);
  stream_period = gst_mpdparser_get_stream_period (client);
  g_return_val_if_fail (stream_period != NULL, 0);

  return stream_period->start;
}

/**
 * gst_mpd_client_get_utc_timing_sources:
 * @client: #GstMpdClient to check for UTCTiming elements
 * @methods: A bit mask of #GstMPDUTCTimingType that specifies the methods
 *     to search for.
 * @selected_method: (nullable): The selected method
 * Returns: (transfer none): A NULL terminated array of URLs of servers
 *     that use @selected_method to provide a realtime clock.
 *
 * Searches the UTCTiming elements found in the manifest for an element
 * that uses one of the UTC timing methods specified in @selected_method.
 * If multiple UTCTiming elements are present that support one of the
 * methods specified in @selected_method, the first one is returned.
 *
 * Since: 1.6
 */
gchar **
gst_mpd_client_get_utc_timing_sources (GstMpdClient * client,
    guint methods, GstMPDUTCTimingType * selected_method)
{
  GList *list;

  g_return_val_if_fail (client != NULL, NULL);
  g_return_val_if_fail (client->mpd_node != NULL, NULL);
  for (list = g_list_first (client->mpd_node->UTCTiming); list;
      list = g_list_next (list)) {
    const GstUTCTimingNode *node = (const GstUTCTimingNode *) list->data;
    if (node->method & methods) {
      if (selected_method) {
        *selected_method = node->method;
      }
      return node->urls;
    }
  }
  return NULL;
}

gboolean
gst_mpd_client_get_next_fragment (GstMpdClient * client,
    guint indexStream, GstMediaFragmentInfo * fragment)
{
  GstActiveStream *stream = NULL;
  GstMediaSegment *currentChunk;
  gchar *mediaURL = NULL;
  gchar *indexURL = NULL;
  GstUri *base_url, *frag_url;

  /* select stream */
  g_return_val_if_fail (client != NULL, FALSE);
  g_return_val_if_fail (client->active_streams != NULL, FALSE);
  stream = g_list_nth_data (client->active_streams, indexStream);
  g_return_val_if_fail (stream != NULL, FALSE);
  g_return_val_if_fail (stream->cur_representation != NULL, FALSE);

  if (stream->segments) {
    GST_DEBUG ("Looking for fragment sequence chunk %d / %d",
        stream->segment_index, stream->segments->len);
    if (stream->segment_index >= stream->segments->len)
      return FALSE;
  } else {
    GstClockTime duration = gst_mpd_client_get_segment_duration (client,
        stream, NULL);
    guint segments_count = gst_mpd_client_get_segments_counts (client, stream);

    g_return_val_if_fail (stream->cur_seg_template->
        MultSegBaseType->SegmentTimeline == NULL, FALSE);
    if (!GST_CLOCK_TIME_IS_VALID (duration) || (segments_count > 0
            && stream->segment_index >= segments_count)) {
      return FALSE;
    }
    fragment->duration = duration;
  }

  /* FIXME rework discont checking */
  /* fragment->discontinuity = segment_idx != currentChunk.number; */
  fragment->range_start = 0;
  fragment->range_end = -1;
  fragment->index_uri = NULL;
  fragment->index_range_start = 0;
  fragment->index_range_end = -1;

  if (stream->segments) {
    currentChunk = g_ptr_array_index (stream->segments, stream->segment_index);

    GST_DEBUG ("currentChunk->SegmentURL = %p", currentChunk->SegmentURL);
    if (currentChunk->SegmentURL != NULL) {
      mediaURL =
          g_strdup (gst_mpdparser_get_mediaURL (stream,
              currentChunk->SegmentURL));
      indexURL = g_strdup (currentChunk->SegmentURL->index);
    } else if (stream->cur_seg_template != NULL) {
      mediaURL =
          gst_mpdparser_build_URL_from_template (stream->
          cur_seg_template->media, stream->cur_representation->id,
          currentChunk->number + stream->segment_repeat_index,
          stream->cur_representation->bandwidth,
          currentChunk->scale_start +
          stream->segment_repeat_index * currentChunk->scale_duration);
      if (stream->cur_seg_template->index) {
        indexURL =
            gst_mpdparser_build_URL_from_template (stream->
            cur_seg_template->index, stream->cur_representation->id,
            currentChunk->number + stream->segment_repeat_index,
            stream->cur_representation->bandwidth,
            currentChunk->scale_start +
            stream->segment_repeat_index * currentChunk->scale_duration);
      }
    }
    GST_DEBUG ("mediaURL = %s", mediaURL);
    GST_DEBUG ("indexURL = %s", indexURL);

    fragment->timestamp =
        currentChunk->start +
        stream->segment_repeat_index * currentChunk->duration;
    fragment->duration = currentChunk->duration;
    if (currentChunk->SegmentURL) {
      if (currentChunk->SegmentURL->mediaRange) {
        fragment->range_start =
            currentChunk->SegmentURL->mediaRange->first_byte_pos;
        fragment->range_end =
            currentChunk->SegmentURL->mediaRange->last_byte_pos;
      }
      if (currentChunk->SegmentURL->indexRange) {
        fragment->index_range_start =
            currentChunk->SegmentURL->indexRange->first_byte_pos;
        fragment->index_range_end =
            currentChunk->SegmentURL->indexRange->last_byte_pos;
      }
    }
  } else {
    if (stream->cur_seg_template != NULL) {
      mediaURL =
          gst_mpdparser_build_URL_from_template (stream->
          cur_seg_template->media, stream->cur_representation->id,
          stream->segment_index +
          stream->cur_seg_template->MultSegBaseType->startNumber,
          stream->cur_representation->bandwidth,
          stream->segment_index * fragment->duration);
      if (stream->cur_seg_template->index) {
        indexURL =
            gst_mpdparser_build_URL_from_template (stream->
            cur_seg_template->index, stream->cur_representation->id,
            stream->segment_index +
            stream->cur_seg_template->MultSegBaseType->startNumber,
            stream->cur_representation->bandwidth,
            stream->segment_index * fragment->duration);
      }
    } else {
      return FALSE;
    }

    GST_DEBUG ("mediaURL = %s", mediaURL);
    GST_DEBUG ("indexURL = %s", indexURL);

    fragment->timestamp = stream->segment_index * fragment->duration;
  }

  base_url = gst_uri_from_string (stream->baseURL);
  frag_url = gst_uri_from_string_with_base (base_url, mediaURL);
  g_free (mediaURL);
  if (stream->queryURL) {
    frag_url = gst_uri_make_writable (frag_url);
    gst_uri_set_query_string (frag_url, stream->queryURL);
  }
  fragment->uri = gst_uri_to_string (frag_url);
  gst_uri_unref (frag_url);

  if (indexURL != NULL) {
    frag_url = gst_uri_make_writable (gst_uri_from_string_with_base (base_url,
            indexURL));
    gst_uri_set_query_string (frag_url, stream->queryURL);
    fragment->index_uri = gst_uri_to_string (frag_url);
    gst_uri_unref (frag_url);
    g_free (indexURL);
  } else if (indexURL == NULL && (fragment->index_range_start
          || fragment->index_range_end != -1)) {
    /* index has no specific URL but has a range, we should only use this if
     * the media also has a range, otherwise we are serving some data twice
     * (in the media fragment and again in the index) */
    if (!(fragment->range_start || fragment->range_end != -1)) {
      GST_WARNING ("Ignoring index ranges because there isn't a media range "
          "and URIs would be the same");
      /* removing index information */
      fragment->index_range_start = 0;
      fragment->index_range_end = -1;
    }
  }

  gst_uri_unref (base_url);

  GST_DEBUG ("Loading chunk with URL %s", fragment->uri);

  return TRUE;
}

gboolean
gst_mpd_client_has_next_segment (GstMpdClient * client,
    GstActiveStream * stream, gboolean forward)
{
  if (forward) {
    guint segments_count = gst_mpd_client_get_segments_counts (client, stream);

    if (segments_count > 0 && stream->segments
        && stream->segment_index + 1 == segments_count) {
      GstMediaSegment *segment;

      segment = g_ptr_array_index (stream->segments, stream->segment_index);
      if (segment->repeat >= 0
          && stream->segment_repeat_index >= segment->repeat)
        return FALSE;
    } else if (segments_count > 0
        && stream->segment_index + 1 >= segments_count) {
      return FALSE;
    }
  } else {
    if (stream->segment_index < 0)
      return FALSE;
  }

  return TRUE;
}

GstFlowReturn
gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream,
    gboolean forward)
{
  GstMediaSegment *segment;
  GstFlowReturn ret = GST_FLOW_OK;
  guint segments_count = gst_mpd_client_get_segments_counts (client, stream);

  GST_DEBUG ("Advancing segment. Current: %d / %d r:%d", stream->segment_index,
      segments_count, stream->segment_repeat_index);

  /* handle special cases first */
  if (forward) {
    if (segments_count > 0 && stream->segment_index >= segments_count) {
      ret = GST_FLOW_EOS;
      goto done;
    }

    if (stream->segments == NULL) {
      if (stream->segment_index < 0) {
        stream->segment_index = 0;
      } else {
        stream->segment_index++;
        if (segments_count > 0 && stream->segment_index >= segments_count) {
          ret = GST_FLOW_EOS;
        }
      }
      goto done;
    }

    /* special case for when playback direction is reverted right at *
     * the end of the segment list */
    if (stream->segment_index < 0) {
      stream->segment_index = 0;
      goto done;
    }
  } else {
    if (stream->segments == NULL)
      stream->segment_index--;
    if (stream->segment_index < 0) {
      stream->segment_index = -1;
      ret = GST_FLOW_EOS;
      goto done;
    }
    if (stream->segments == NULL)
      goto done;

    /* special case for when playback direction is reverted right at *
     * the end of the segment list */
    if (stream->segment_index >= segments_count) {
      stream->segment_index = segments_count - 1;
      segment = g_ptr_array_index (stream->segments, stream->segment_index);
      if (segment->repeat >= 0) {
        stream->segment_repeat_index = segment->repeat;
      } else {
        GstClockTime start = segment->start;
        GstClockTime end =
            gst_mpdparser_get_segment_end_time (client, stream->segments,
            segment,
            stream->segment_index);
        stream->segment_repeat_index =
            (guint) (end - start) / segment->duration;
      }
      goto done;
    }
  }

  /* for the normal cases we can get the segment safely here */
  segment = g_ptr_array_index (stream->segments, stream->segment_index);
  if (forward) {
    if (segment->repeat >= 0 && stream->segment_repeat_index >= segment->repeat) {
      stream->segment_repeat_index = 0;
      stream->segment_index++;
      if (segments_count > 0 && stream->segment_index >= segments_count) {
        ret = GST_FLOW_EOS;
        goto done;
      }
    } else {
      stream->segment_repeat_index++;
    }
  } else {
    if (stream->segment_repeat_index == 0) {
      stream->segment_index--;
      if (stream->segment_index < 0) {
        ret = GST_FLOW_EOS;
        goto done;
      }

      segment = g_ptr_array_index (stream->segments, stream->segment_index);
      /* negative repeats only seem to make sense at the end of a list,
       * so this one will probably not be. Needs some sanity checking
       * when loading the XML data. */
      if (segment->repeat >= 0) {
        stream->segment_repeat_index = segment->repeat;
      } else {
        GstClockTime start = segment->start;
        GstClockTime end =
            gst_mpdparser_get_segment_end_time (client, stream->segments,
            segment,
            stream->segment_index);
        stream->segment_repeat_index =
            (guint) (end - start) / segment->duration;
      }
    } else {
      stream->segment_repeat_index--;
    }
  }

done:
  GST_DEBUG ("Advanced to segment: %d / %d r:%d (ret: %s)",
      stream->segment_index, segments_count,
      stream->segment_repeat_index, gst_flow_get_name (ret));
  return ret;
}

gboolean
gst_mpd_client_get_next_header (GstMpdClient * client, gchar ** uri,
    guint stream_idx, gint64 * range_start, gint64 * range_end)
{
  GstActiveStream *stream;
  GstStreamPeriod *stream_period;

  stream = gst_mpdparser_get_active_stream_by_index (client, stream_idx);
  g_return_val_if_fail (stream != NULL, FALSE);
  g_return_val_if_fail (stream->cur_representation != NULL, FALSE);
  stream_period = gst_mpdparser_get_stream_period (client);
  g_return_val_if_fail (stream_period != NULL, FALSE);
  g_return_val_if_fail (stream_period->period != NULL, FALSE);

  *range_start = 0;
  *range_end = -1;

  GST_DEBUG ("Looking for current representation header");
  *uri = NULL;
  if (stream->cur_segment_base) {
    if (stream->cur_segment_base->Initialization) {
      *uri =
          g_strdup (gst_mpdparser_get_initializationURL (stream,
              stream->cur_segment_base->Initialization));
      if (stream->cur_segment_base->Initialization->range) {
        *range_start =
            stream->cur_segment_base->Initialization->range->first_byte_pos;
        *range_end =
            stream->cur_segment_base->Initialization->range->last_byte_pos;
      }
    } else if (stream->cur_segment_base->indexRange) {
      *uri =
          g_strdup (gst_mpdparser_get_initializationURL (stream,
              stream->cur_segment_base->Initialization));
      *range_start = 0;
      *range_end = stream->cur_segment_base->indexRange->first_byte_pos - 1;
    }
  } else if (stream->cur_seg_template
      && stream->cur_seg_template->initialization) {
    *uri =
        gst_mpdparser_build_URL_from_template (stream->
        cur_seg_template->initialization, stream->cur_representation->id, 0,
        stream->cur_representation->bandwidth, 0);
  }

  return *uri == NULL ? FALSE : TRUE;
}

gboolean
gst_mpd_client_get_next_header_index (GstMpdClient * client, gchar ** uri,
    guint stream_idx, gint64 * range_start, gint64 * range_end)
{
  GstActiveStream *stream;
  GstStreamPeriod *stream_period;

  stream = gst_mpdparser_get_active_stream_by_index (client, stream_idx);
  g_return_val_if_fail (stream != NULL, FALSE);
  g_return_val_if_fail (stream->cur_representation != NULL, FALSE);
  stream_period = gst_mpdparser_get_stream_period (client);
  g_return_val_if_fail (stream_period != NULL, FALSE);
  g_return_val_if_fail (stream_period->period != NULL, FALSE);

  *range_start = 0;
  *range_end = -1;

  GST_DEBUG ("Looking for current representation index");
  *uri = NULL;
  if (stream->cur_segment_base && stream->cur_segment_base->indexRange) {
    *uri =
        g_strdup (gst_mpdparser_get_initializationURL (stream,
            stream->cur_segment_base->RepresentationIndex));
    *range_start = stream->cur_segment_base->indexRange->first_byte_pos;
    *range_end = stream->cur_segment_base->indexRange->last_byte_pos;
  } else if (stream->cur_seg_template && stream->cur_seg_template->index) {
    *uri =
        gst_mpdparser_build_URL_from_template (stream->cur_seg_template->index,
        stream->cur_representation->id, 0,
        stream->cur_representation->bandwidth, 0);
  }

  return *uri == NULL ? FALSE : TRUE;
}

GstClockTime
gst_mpd_client_get_next_fragment_duration (GstMpdClient * client,
    GstActiveStream * stream)
{
  GstMediaSegment *media_segment = NULL;
  gint seg_idx;

  g_return_val_if_fail (stream != NULL, 0);

  seg_idx = stream->segment_index;

  if (stream->segments) {
    if (seg_idx < stream->segments->len && seg_idx >= 0)
      media_segment = g_ptr_array_index (stream->segments, seg_idx);

    return media_segment == NULL ? 0 : media_segment->duration;
  } else {
    GstClockTime duration =
        gst_mpd_client_get_segment_duration (client, stream, NULL);
    guint segments_count = gst_mpd_client_get_segments_counts (client, stream);

    g_return_val_if_fail (stream->cur_seg_template->MultSegBaseType->
        SegmentTimeline == NULL, 0);

    if (!GST_CLOCK_TIME_IS_VALID (duration) || (segments_count > 0
            && seg_idx >= segments_count)) {
      return 0;
    }
    return duration;
  }
}

GstClockTime
gst_mpd_client_get_media_presentation_duration (GstMpdClient * client)
{
  GstClockTime duration;

  g_return_val_if_fail (client != NULL, GST_CLOCK_TIME_NONE);

  if (client->mpd_node->mediaPresentationDuration != -1) {
    duration = client->mpd_node->mediaPresentationDuration * GST_MSECOND;
  } else {
    /* We can only get the duration for on-demand streams */
    duration = GST_CLOCK_TIME_NONE;
  }

  return duration;
}

gboolean
gst_mpd_client_set_period_id (GstMpdClient * client, const gchar * period_id)
{
  GstStreamPeriod *next_stream_period;
  gboolean ret = FALSE;
  GList *iter;
  guint period_idx;

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

  if (!gst_mpd_client_setup_media_presentation (client, GST_CLOCK_TIME_NONE, -1,
          period_id))
    return FALSE;

  for (period_idx = 0, iter = client->periods; iter;
      period_idx++, iter = g_list_next (iter)) {
    next_stream_period = iter->data;

    if (next_stream_period->period->id
        && strcmp (next_stream_period->period->id, period_id) == 0) {
      ret = TRUE;
      client->period_idx = period_idx;
      break;
    }
  }

  return ret;
}

gboolean
gst_mpd_client_set_period_index (GstMpdClient * client, guint period_idx)
{
  GstStreamPeriod *next_stream_period;
  gboolean ret = FALSE;

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

  if (!gst_mpd_client_setup_media_presentation (client, -1, period_idx, NULL))
    return FALSE;

  next_stream_period = g_list_nth_data (client->periods, period_idx);
  if (next_stream_period != NULL) {
    client->period_idx = period_idx;
    ret = TRUE;
  }

  return ret;
}

guint
gst_mpd_client_get_period_index (GstMpdClient * client)
{
  guint period_idx;

  g_return_val_if_fail (client != NULL, 0);
  period_idx = client->period_idx;

  return period_idx;
}

const gchar *
gst_mpd_client_get_period_id (GstMpdClient * client)
{
  GstStreamPeriod *period;
  gchar *period_id = NULL;

  g_return_val_if_fail (client != NULL, 0);
  period = g_list_nth_data (client->periods, client->period_idx);
  if (period && period->period)
    period_id = period->period->id;

  return period_id;
}

gboolean
gst_mpd_client_has_previous_period (GstMpdClient * client)
{
  GList *next_stream_period;
  g_return_val_if_fail (client != NULL, FALSE);
  g_return_val_if_fail (client->periods != NULL, FALSE);

  if (!gst_mpd_client_setup_media_presentation (client, GST_CLOCK_TIME_NONE,
          client->period_idx - 1, NULL))
    return FALSE;

  next_stream_period =
      g_list_nth_data (client->periods, client->period_idx - 1);

  return next_stream_period != NULL;
}

gboolean
gst_mpd_client_has_next_period (GstMpdClient * client)
{
  GList *next_stream_period;
  g_return_val_if_fail (client != NULL, FALSE);
  g_return_val_if_fail (client->periods != NULL, FALSE);

  if (!gst_mpd_client_setup_media_presentation (client, GST_CLOCK_TIME_NONE,
          client->period_idx + 1, NULL))
    return FALSE;

  next_stream_period =
      g_list_nth_data (client->periods, client->period_idx + 1);
  return next_stream_period != NULL;
}

void
gst_mpd_client_seek_to_first_segment (GstMpdClient * client)
{
  GList *list;

  g_return_if_fail (client != NULL);
  g_return_if_fail (client->active_streams != NULL);

  for (list = g_list_first (client->active_streams); list;
      list = g_list_next (list)) {
    GstActiveStream *stream = (GstActiveStream *) list->data;
    if (stream) {
      stream->segment_index = 0;
      stream->segment_repeat_index = 0;
    }
  }
}

static guint
gst_mpd_client_get_segments_counts (GstMpdClient * client,
    GstActiveStream * stream)
{
  GstStreamPeriod *stream_period;

  g_return_val_if_fail (stream != NULL, 0);

  if (stream->segments)
    return stream->segments->len;
  g_return_val_if_fail (stream->cur_seg_template->MultSegBaseType->
      SegmentTimeline == NULL, 0);

  stream_period = gst_mpdparser_get_stream_period (client);
  if (stream_period->duration != -1)
    return gst_util_uint64_scale_ceil (stream_period->duration, 1,
        gst_mpd_client_get_segment_duration (client, stream, NULL));

  return 0;
}

gboolean
gst_mpd_client_is_live (GstMpdClient * client)
{
  g_return_val_if_fail (client != NULL, FALSE);
  g_return_val_if_fail (client->mpd_node != NULL, FALSE);

  return client->mpd_node->type == GST_MPD_FILE_TYPE_DYNAMIC;
}

guint
gst_mpdparser_get_nb_active_stream (GstMpdClient * client)
{
  g_return_val_if_fail (client != NULL, 0);

  return g_list_length (client->active_streams);
}

guint
gst_mpdparser_get_nb_adaptationSet (GstMpdClient * client)
{
  GstStreamPeriod *stream_period;

  stream_period = gst_mpdparser_get_stream_period (client);
  g_return_val_if_fail (stream_period != NULL, 0);
  g_return_val_if_fail (stream_period->period != NULL, 0);

  return g_list_length (stream_period->period->AdaptationSets);
}

GstActiveStream *
gst_mpdparser_get_active_stream_by_index (GstMpdClient * client,
    guint stream_idx)
{
  g_return_val_if_fail (client != NULL, NULL);
  g_return_val_if_fail (client->active_streams != NULL, NULL);

  return g_list_nth_data (client->active_streams, stream_idx);
}

gboolean
gst_mpd_client_active_stream_contains_subtitles (GstActiveStream * stream)
{
  const gchar *mimeType;
  const gchar *adapt_set_codecs;
  const gchar *rep_codecs;

  mimeType = stream->cur_representation->RepresentationBase->mimeType;
  if (!mimeType)
    mimeType = stream->cur_adapt_set->RepresentationBase->mimeType;

  if (g_strcmp0 (mimeType, "application/ttml+xml") == 0)
    return TRUE;

  adapt_set_codecs = stream->cur_adapt_set->RepresentationBase->codecs;
  rep_codecs = stream->cur_representation->RepresentationBase->codecs;

  return (adapt_set_codecs && g_str_has_prefix (adapt_set_codecs, "stpp"))
      || (rep_codecs && g_str_has_prefix (rep_codecs, "stpp"));
}

static const gchar *
gst_mpdparser_mimetype_to_caps (const gchar * mimeType)
{
  if (mimeType == NULL)
    return NULL;
  if (strcmp (mimeType, "video/mp2t") == 0) {
    return "video/mpegts, systemstream=(bool) true";
  } else if (strcmp (mimeType, "video/mp4") == 0) {
    return "video/quicktime";
  } else if (strcmp (mimeType, "audio/mp4") == 0) {
    return "audio/x-m4a";
  } else
    return mimeType;
}

GstCaps *
gst_mpd_client_get_stream_caps (GstActiveStream * stream)
{
  const gchar *mimeType, *caps_string;
  GstCaps *ret = NULL;

  if (stream == NULL || stream->cur_adapt_set == NULL
      || stream->cur_representation == NULL)
    return NULL;

  mimeType = stream->cur_representation->RepresentationBase->mimeType;
  if (mimeType == NULL) {
    mimeType = stream->cur_adapt_set->RepresentationBase->mimeType;
  }

  caps_string = gst_mpdparser_mimetype_to_caps (mimeType);

  if ((g_strcmp0 (caps_string, "application/mp4") == 0)
      && gst_mpd_client_active_stream_contains_subtitles (stream))
    caps_string = "video/quicktime";

  if (caps_string)
    ret = gst_caps_from_string (caps_string);

  return ret;
}

gboolean
gst_mpd_client_get_bitstream_switching_flag (GstActiveStream * stream)
{
  if (stream == NULL || stream->cur_adapt_set == NULL)
    return FALSE;

  return stream->cur_adapt_set->bitstreamSwitching;
}

guint
gst_mpd_client_get_video_stream_width (GstActiveStream * stream)
{
  guint width;

  if (stream == NULL || stream->cur_adapt_set == NULL
      || stream->cur_representation == NULL)
    return 0;

  width = stream->cur_representation->RepresentationBase->width;
  if (width == 0) {
    width = stream->cur_adapt_set->RepresentationBase->width;
  }

  return width;
}

guint
gst_mpd_client_get_video_stream_height (GstActiveStream * stream)
{
  guint height;

  if (stream == NULL || stream->cur_adapt_set == NULL
      || stream->cur_representation == NULL)
    return 0;

  height = stream->cur_representation->RepresentationBase->height;
  if (height == 0) {
    height = stream->cur_adapt_set->RepresentationBase->height;
  }

  return height;
}

gboolean
gst_mpd_client_get_video_stream_framerate (GstActiveStream * stream,
    gint * fps_num, gint * fps_den)
{
  if (stream == NULL)
    return FALSE;

  if (stream->cur_adapt_set &&
      stream->cur_adapt_set->RepresentationBase->frameRate != NULL) {
    *fps_num = stream->cur_adapt_set->RepresentationBase->frameRate->num;
    *fps_den = stream->cur_adapt_set->RepresentationBase->frameRate->den;
    return TRUE;
  }

  if (stream->cur_adapt_set &&
      stream->cur_adapt_set->RepresentationBase->maxFrameRate != NULL) {
    *fps_num = stream->cur_adapt_set->RepresentationBase->maxFrameRate->num;
    *fps_den = stream->cur_adapt_set->RepresentationBase->maxFrameRate->den;
    return TRUE;
  }

  if (stream->cur_representation &&
      stream->cur_representation->RepresentationBase->frameRate != NULL) {
    *fps_num = stream->cur_representation->RepresentationBase->frameRate->num;
    *fps_den = stream->cur_representation->RepresentationBase->frameRate->den;
    return TRUE;
  }

  if (stream->cur_representation &&
      stream->cur_representation->RepresentationBase->maxFrameRate != NULL) {
    *fps_num =
        stream->cur_representation->RepresentationBase->maxFrameRate->num;
    *fps_den =
        stream->cur_representation->RepresentationBase->maxFrameRate->den;
    return TRUE;
  }

  return FALSE;
}

guint
gst_mpd_client_get_audio_stream_rate (GstActiveStream * stream)
{
  const gchar *rate;

  if (stream == NULL || stream->cur_adapt_set == NULL
      || stream->cur_representation == NULL)
    return 0;

  rate = stream->cur_representation->RepresentationBase->audioSamplingRate;
  if (rate == NULL) {
    rate = stream->cur_adapt_set->RepresentationBase->audioSamplingRate;
  }

  return rate ? atoi (rate) : 0;
}

guint
gst_mpd_client_get_audio_stream_num_channels (GstActiveStream * stream)
{
  if (stream == NULL || stream->cur_adapt_set == NULL
      || stream->cur_representation == NULL)
    return 0;
  /* TODO: here we have to parse the AudioChannelConfiguration descriptors */
  return 0;
}

guint
gst_mpdparser_get_list_and_nb_of_audio_language (GstMpdClient * client,
    GList ** lang)
{
  GstStreamPeriod *stream_period;
  GstAdaptationSetNode *adapt_set;
  GList *adaptation_sets, *list;
  const gchar *this_mimeType = "audio";
  gchar *mimeType = NULL;
  guint nb_adaptation_set = 0;

  stream_period = gst_mpdparser_get_stream_period (client);
  g_return_val_if_fail (stream_period != NULL, 0);
  g_return_val_if_fail (stream_period->period != NULL, 0);

  adaptation_sets =
      gst_mpd_client_get_adaptation_sets_for_period (client, stream_period);
  for (list = adaptation_sets; list; list = g_list_next (list)) {
    adapt_set = (GstAdaptationSetNode *) list->data;
    if (adapt_set && adapt_set->lang) {
      gchar *this_lang = adapt_set->lang;
      GstRepresentationNode *rep;
      rep =
          gst_mpdparser_get_lowest_representation (adapt_set->Representations);
      mimeType = NULL;
      if (rep->RepresentationBase)
        mimeType = rep->RepresentationBase->mimeType;
      if (!mimeType && adapt_set->RepresentationBase) {
        mimeType = adapt_set->RepresentationBase->mimeType;
      }

      if (strncmp_ext (mimeType, this_mimeType) == 0) {
        nb_adaptation_set++;
        *lang = g_list_append (*lang, this_lang);
      }
    }
  }

  return nb_adaptation_set;
}


GstDateTime *
gst_mpd_client_get_next_segment_availability_start_time (GstMpdClient * client,
    GstActiveStream * stream)
{
  GstDateTime *availability_start_time, *rv;
  gint seg_idx;
  GstStreamPeriod *stream_period;
  GstMediaSegment *segment;
  GstClockTime segmentEndTime;

  g_return_val_if_fail (client != NULL, NULL);
  g_return_val_if_fail (stream != NULL, NULL);

  stream_period = gst_mpdparser_get_stream_period (client);

  seg_idx = stream->segment_index;

  if (stream->segments) {
    segment = g_ptr_array_index (stream->segments, seg_idx);

    if (segment->repeat >= 0) {
      segmentEndTime = segment->start + (stream->segment_repeat_index + 1) *
          segment->duration;
    } else if (seg_idx < stream->segments->len - 1) {
      const GstMediaSegment *next_segment =
          g_ptr_array_index (stream->segments, seg_idx + 1);
      segmentEndTime = next_segment->start;
    } else {
      const GstStreamPeriod *stream_period;
      stream_period = gst_mpdparser_get_stream_period (client);
      segmentEndTime = stream_period->start + stream_period->duration;
    }
  } else {
    GstClockTime seg_duration;
    seg_duration = gst_mpd_client_get_segment_duration (client, stream, NULL);
    if (seg_duration == 0)
      return NULL;
    segmentEndTime = (1 + seg_idx) * seg_duration;
  }

  availability_start_time = gst_mpd_client_get_availability_start_time (client);
  if (availability_start_time == NULL) {
    GST_WARNING_OBJECT (client, "Failed to get availability_start_time");
    return NULL;
  }

  if (stream_period && stream_period->period) {
    GstDateTime *t =
        gst_mpd_client_add_time_difference (availability_start_time,
        stream_period->start / GST_USECOND);
    gst_date_time_unref (availability_start_time);
    availability_start_time = t;

    if (availability_start_time == NULL) {
      GST_WARNING_OBJECT (client, "Failed to offset availability_start_time");
      return NULL;
    }
  }

  rv = gst_mpd_client_add_time_difference (availability_start_time,
      segmentEndTime / GST_USECOND);
  gst_date_time_unref (availability_start_time);
  if (rv == NULL) {
    GST_WARNING_OBJECT (client, "Failed to offset availability_start_time");
    return NULL;
  }

  return rv;
}

gboolean
gst_mpd_client_seek_to_time (GstMpdClient * client, GDateTime * time)
{
  GDateTime *start;
  GTimeSpan ts_microseconds;
  GstClockTime ts;
  gboolean ret = TRUE;
  GList *stream;

  g_return_val_if_fail (gst_mpd_client_is_live (client), FALSE);
  g_return_val_if_fail (client->mpd_node->availabilityStartTime != NULL, FALSE);

  start =
      gst_date_time_to_g_date_time (client->mpd_node->availabilityStartTime);

  ts_microseconds = g_date_time_difference (time, start);
  g_date_time_unref (start);

  /* Clamp to availability start time, otherwise calculations wrap around */
  if (ts_microseconds < 0)
    ts_microseconds = 0;

  ts = ts_microseconds * GST_USECOND;
  for (stream = client->active_streams; stream; stream = g_list_next (stream)) {
    ret =
        ret & gst_mpd_client_stream_seek (client, stream->data, TRUE, 0, ts,
        NULL);
  }
  return ret;
}

void
gst_media_fragment_info_clear (GstMediaFragmentInfo * fragment)
{
  g_free (fragment->uri);
  g_free (fragment->index_uri);
}

gboolean
gst_mpd_client_has_isoff_ondemand_profile (GstMpdClient * client)
{
  return client->profile_isoff_ondemand;
}

/**
 * gst_mpd_client_parse_default_presentation_delay:
 * @client: #GstMpdClient that has a parsed manifest
 * @default_presentation_delay: A string that specifies a time period
 * in fragments (e.g. "5 f"), seconds ("12 s") or milliseconds
 * ("12000 ms")
 * Returns: the parsed string in milliseconds
 *
 * Since: 1.6
 */
gint64
gst_mpd_client_parse_default_presentation_delay (GstMpdClient * client,
    const gchar * default_presentation_delay)
{
  gint64 value;
  char *endptr = NULL;

  g_return_val_if_fail (client != NULL, 0);
  g_return_val_if_fail (default_presentation_delay != NULL, 0);
  value = strtol (default_presentation_delay, &endptr, 10);
  if (endptr == default_presentation_delay || value == 0) {
    return 0;
  }
  while (*endptr == ' ')
    endptr++;
  if (*endptr == 's' || *endptr == 'S') {
    value *= 1000;              /* convert to ms */
  } else if (*endptr == 'f' || *endptr == 'F') {
    gint64 segment_duration;
    g_assert (client->mpd_node != NULL);
    segment_duration = client->mpd_node->maxSegmentDuration;
    value *= segment_duration;
  } else if (*endptr != 'm' && *endptr != 'M') {
    GST_ERROR ("Unable to parse default presentation delay: %s",
        default_presentation_delay);
    value = 0;
  }
  return value;
}

GstClockTime
gst_mpd_client_get_maximum_segment_duration (GstMpdClient * client)
{
  GstClockTime ret = GST_CLOCK_TIME_NONE, dur;
  GList *stream;

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

  if (client->mpd_node->maxSegmentDuration != GST_MPD_DURATION_NONE) {
    return client->mpd_node->maxSegmentDuration * GST_MSECOND;
  }

  /* According to the DASH specification, if maxSegmentDuration is not present:
     "If not present, then the maximum Segment duration shall be the maximum
     duration of any Segment documented in this MPD"
   */
  for (stream = client->active_streams; stream; stream = g_list_next (stream)) {
    dur = gst_mpd_client_get_segment_duration (client, stream->data, NULL);
    if (dur != GST_CLOCK_TIME_NONE && (dur > ret || ret == GST_CLOCK_TIME_NONE)) {
      ret = dur;
    }
  }
  return ret;
}
