[OE-core] [pyro][PATCH] gstreamer1.0-plugins-bad: Refresh patches for live streaming and add mpdparser for Dash playready support

akuster808 akuster808 at gmail.com
Sat Apr 28 16:37:19 UTC 2018



On 04/27/2018 08:38 PM, wouterlucas wrote:
> Signed-off-by: wouterlucas <wouter at wouterlucas.com>
> ---
>  ...demux-improved-live-playback-support.patch | 358 ++++++++----------
>  ...implement-adaptivedemux-s-get_live_s.patch |  63 +--
>  ...vedemux-minimal-HTTP-context-support.patch | 142 +++++++
>  ...-PlayReady-ContentProtection-parsing.patch | 109 ++++++
>  .../gstreamer1.0-plugins-bad_1.10.4.bb        |   9 +-
>  5 files changed, 452 insertions(+), 229 deletions(-)
>  create mode 100644 meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-adaptivedemux-minimal-HTTP-context-support.patch
>  create mode 100644 meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-mpdparser-MS-PlayReady-ContentProtection-parsing.patch

This fails with:

RROR: gstreamer1.0-plugins-bad-1.10.4-r0 do_fetch: Fetcher failure:
Unable to find file
file://0002-mssdemux-Handle-the-adapter-in-the-subclass-after-bu.patch
anywhere. The paths that were searched were:
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.10.4/poky
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/poky
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/files/poky
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.10.4/qemux86
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/qemux86
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/files/qemux86
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.10.4/qemuall
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/qemuall
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/files/qemuall
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.10.4/x86
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/x86
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/files/x86
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.10.4/i586
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/i586
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/files/i586
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.10.4/
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/files/
/srv/autobuilder/autobuilder.yoctoproject.org/current_sources ERROR:
gstreamer1.0-plugins-bad-1.10.4-r0 do_fetch: Fetcher failure for URL:
'file://0002-mssdemux-Handle-the-adapter-in-the-subclass-after-bu.patch'.
Unable to fetch URL from any source. ERROR:
gstreamer1.0-plugins-bad-1.10.4-r0 do_fetch: Function failed:
base_do_fetch ERROR: Logfile of failure stored in:
/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/build/tmp/work/i586-poky-linux/gstreamer1.0-plugins-bad/1.10.4-r0/temp/log.do_fetch.1786
NOTE: recipe gstreamer1.0-plugins-bad-1.10.4-r0: task do_fetch: Failed
ERROR: Task
(/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-deb-non-deb/build/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.10.4.bb:do_fetch)


> diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-mssdemux-improved-live-playback-support.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-mssdemux-improved-live-playback-support.patch
> index 4832c18e78..041a3d6313 100644
> --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-mssdemux-improved-live-playback-support.patch
> +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-mssdemux-improved-live-playback-support.patch
> @@ -1,7 +1,7 @@
> -From 73721ad4e9e2d32e1c8b6a3b4aaa98401530e58a Mon Sep 17 00:00:00 2001
> +From 12b9645c4c5b94ff4fd5062bdb02b63db7648db9 Mon Sep 17 00:00:00 2001
>  From: Philippe Normand <philn at igalia.com>
> -Date: Tue, 29 Nov 2016 14:43:41 +0100
> -Subject: [PATCH] mssdemux: improved live playback support
> +Date: Thu, 10 Sep 2015 16:13:30 +0200
> +Subject: [PATCH 1/6] mssdemux: improved live playback support
>  
>  When a MSS server hosts a live stream the fragments listed in the
>  manifest usually don't have accurate timestamps and duration, except
> @@ -12,23 +12,20 @@ be incrementally built by parsing the first/current fragment.
>  
>  https://bugzilla.gnome.org/show_bug.cgi?id=755036
>  ---
> -Upstream-Status: Backport
> -Signed-off-by: Khem Raj <raj.khem at gmail.com>
> -
>   ext/smoothstreaming/Makefile.am               |   2 +
> - ext/smoothstreaming/gstmssdemux.c             |  60 ++++++
> - ext/smoothstreaming/gstmssfragmentparser.c    | 266 ++++++++++++++++++++++++++
> - ext/smoothstreaming/gstmssfragmentparser.h    |  84 ++++++++
> - ext/smoothstreaming/gstmssmanifest.c          | 158 ++++++++++++++-
> - ext/smoothstreaming/gstmssmanifest.h          |   7 +
> - gst-libs/gst/adaptivedemux/gstadaptivedemux.c |  27 ++-
> + ext/smoothstreaming/gstmssdemux.c             |  61 ++++++
> + ext/smoothstreaming/gstmssfragmentparser.c    | 255 ++++++++++++++++++++++++++
> + ext/smoothstreaming/gstmssfragmentparser.h    |  84 +++++++++
> + ext/smoothstreaming/gstmssmanifest.c          | 155 ++++++++++++++--
> + ext/smoothstreaming/gstmssmanifest.h          |   3 +
> + gst-libs/gst/adaptivedemux/gstadaptivedemux.c |  28 ++-
>   gst-libs/gst/adaptivedemux/gstadaptivedemux.h |  14 ++
> - 8 files changed, 606 insertions(+), 12 deletions(-)
> + 8 files changed, 586 insertions(+), 16 deletions(-)
>   create mode 100644 ext/smoothstreaming/gstmssfragmentparser.c
>   create mode 100644 ext/smoothstreaming/gstmssfragmentparser.h
>  
>  diff --git a/ext/smoothstreaming/Makefile.am b/ext/smoothstreaming/Makefile.am
> -index 4faf9df9f..a5e1ad6ae 100644
> +index 4faf9df..a5e1ad6 100644
>  --- a/ext/smoothstreaming/Makefile.am
>  +++ b/ext/smoothstreaming/Makefile.am
>  @@ -13,8 +13,10 @@ libgstsmoothstreaming_la_LIBADD = \
> @@ -43,10 +40,10 @@ index 4faf9df9f..a5e1ad6ae 100644
>  +	gstmssfragmentparser.h \
>   	gstmssmanifest.h
>  diff --git a/ext/smoothstreaming/gstmssdemux.c b/ext/smoothstreaming/gstmssdemux.c
> -index 12fb40497..120d9c22b 100644
> +index 9d0aece..70b541e 100644
>  --- a/ext/smoothstreaming/gstmssdemux.c
>  +++ b/ext/smoothstreaming/gstmssdemux.c
> -@@ -135,11 +135,18 @@ gst_mss_demux_stream_update_fragment_info (GstAdaptiveDemuxStream * stream);
> +@@ -135,9 +135,16 @@ gst_mss_demux_stream_update_fragment_info (GstAdaptiveDemuxStream * stream);
>   static gboolean gst_mss_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek);
>   static gint64
>   gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux);
> @@ -56,16 +53,14 @@ index 12fb40497..120d9c22b 100644
>   static GstFlowReturn
>   gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
>       GstBuffer * buffer);
> - static gboolean gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux,
> -     gint64 * start, gint64 * stop);
>  +static GstFlowReturn gst_mss_demux_data_received (GstAdaptiveDemux * demux,
> -+    GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
> ++    GstAdaptiveDemuxStream * stream);
>  +static gboolean
>  +gst_mss_demux_requires_periodical_playlist_update (GstAdaptiveDemux * demux);
>   
>   static void
>   gst_mss_demux_class_init (GstMssDemuxClass * klass)
> -@@ -192,10 +199,15 @@ gst_mss_demux_class_init (GstMssDemuxClass * klass)
> +@@ -190,8 +197,13 @@ gst_mss_demux_class_init (GstMssDemuxClass * klass)
>         gst_mss_demux_stream_select_bitrate;
>     gstadaptivedemux_class->stream_update_fragment_info =
>         gst_mss_demux_stream_update_fragment_info;
> @@ -73,36 +68,39 @@ index 12fb40497..120d9c22b 100644
>  +      gst_mss_demux_stream_get_fragment_waiting_time;
>     gstadaptivedemux_class->update_manifest_data =
>         gst_mss_demux_update_manifest_data;
> -   gstadaptivedemux_class->get_live_seek_range =
> -       gst_mss_demux_get_live_seek_range;
>  +  gstadaptivedemux_class->data_received = gst_mss_demux_data_received;
>  +  gstadaptivedemux_class->requires_periodical_playlist_update =
>  +      gst_mss_demux_requires_periodical_playlist_update;
>   
>     GST_DEBUG_CATEGORY_INIT (mssdemux_debug, "mssdemux", 0, "mssdemux plugin");
>   }
> -@@ -650,6 +662,13 @@ gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux)
> +@@ -648,6 +660,17 @@ gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux)
>     return interval;
>   }
>   
>  +static gint64
>  +gst_mss_demux_stream_get_fragment_waiting_time (GstAdaptiveDemuxStream * stream)
>  +{
> -+  /* Wait a second for live streams so we don't try premature fragments downloading */
> -+  return GST_SECOND;
> ++  GstMssDemuxStream *mssstream = (GstMssDemuxStream *) stream;
> ++  GstMssStreamType streamtype =
> ++      gst_mss_stream_get_type (mssstream->manifest_stream);
> ++
> ++  /* Wait a second for live audio streams so we don't try premature fragments downloading */
> ++  return streamtype == MSS_STREAM_TYPE_AUDIO ? GST_SECOND : 0;
>  +}
>  +
>   static GstFlowReturn
>   gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
>       GstBuffer * buffer)
> -@@ -670,3 +689,44 @@ gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
> - 
> -   return gst_mss_manifest_get_live_seek_range (mssdemux->manifest, start, stop);
> +@@ -659,3 +682,41 @@ gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
> +   gst_mss_manifest_reload_fragments (mssdemux->manifest, buffer);
> +   return GST_FLOW_OK;
>   }
>  +
> ++
>  +static GstFlowReturn
>  +gst_mss_demux_data_received (GstAdaptiveDemux * demux,
> -+    GstAdaptiveDemuxStream * stream, GstBuffer * buffer)
> ++    GstAdaptiveDemuxStream * stream)
>  +{
>  +  GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (demux);
>  +  GstMssDemuxStream *mssstream = (GstMssDemuxStream *) stream;
> @@ -110,27 +108,23 @@ index 12fb40497..120d9c22b 100644
>  +
>  +  if (!gst_mss_manifest_is_live (mssdemux->manifest)) {
>  +    return GST_ADAPTIVE_DEMUX_CLASS (parent_class)->data_received (demux,
> -+        stream, buffer);
> ++        stream);
>  +  }
>  +
>  +  if (gst_mss_stream_fragment_parsing_needed (mssstream->manifest_stream)) {
> -+    gst_mss_manifest_live_adapter_push (mssstream->manifest_stream, buffer);
> -+    available =
> -+        gst_mss_manifest_live_adapter_available (mssstream->manifest_stream);
> ++    available = gst_adapter_available (stream->adapter);
>  +    // FIXME: try to reduce this minimal size.
>  +    if (available < 4096) {
>  +      return GST_FLOW_OK;
>  +    } else {
> ++      GstBuffer *buffer = gst_adapter_get_buffer (stream->adapter, available);
>  +      GST_LOG_OBJECT (stream->pad, "enough data, parsing fragment.");
> -+      buffer =
> -+          gst_mss_manifest_live_adapter_take_buffer (mssstream->manifest_stream,
> -+          available);
> -+      gst_mss_stream_parse_fragment (mssstream->manifest_stream, buffer);
> ++      gst_mss_stream_fragment_parse (mssstream->manifest_stream, buffer);
> ++      gst_buffer_unref (buffer);
>  +    }
>  +  }
>  +
> -+  return GST_ADAPTIVE_DEMUX_CLASS (parent_class)->data_received (demux, stream,
> -+      buffer);
> ++  return GST_ADAPTIVE_DEMUX_CLASS (parent_class)->data_received (demux, stream);
>  +}
>  +
>  +static gboolean
> @@ -142,17 +136,17 @@ index 12fb40497..120d9c22b 100644
>  +}
>  diff --git a/ext/smoothstreaming/gstmssfragmentparser.c b/ext/smoothstreaming/gstmssfragmentparser.c
>  new file mode 100644
> -index 000000000..b554d4f31
> +index 0000000..01c3b15
>  --- /dev/null
>  +++ b/ext/smoothstreaming/gstmssfragmentparser.c
> -@@ -0,0 +1,266 @@
> +@@ -0,0 +1,255 @@
>  +/*
>  + * Microsoft Smooth-Streaming fragment parsing library
>  + *
>  + * gstmssfragmentparser.h
>  + *
> -+ * Copyright (C) 2016 Igalia S.L
> -+ * Copyright (C) 2016 Metrological
> ++ * Copyright (C) 2015 Igalia S.L
> ++ * Copyright (C) 2015 Metrological
>  + *   Author: Philippe Normand <philn at igalia.com>
>  + *
>  + * This library is free software; you can redistribute it and/or
> @@ -333,12 +327,8 @@ index 000000000..b554d4f31
>  +          size = gst_byte_reader_get_uint32_be_unchecked (&reader);
>  +          fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader);
>  +          if (fourcc == GST_MSS_FRAGMENT_FOURCC_TRUN) {
> -+            GST_TRACE ("trun box found, size: %" G_GUINT32_FORMAT, size);
> -+            if (!gst_byte_reader_skip (&reader, size - 8)) {
> -+              GST_WARNING ("Failed to skip trun box, enough data?");
> -+              error = TRUE;
> -+              goto beach;
> -+            }
> ++            gst_byte_reader_skip_unchecked (&reader, size - 8);
> ++            GST_TRACE ("trun box found, size: %u", size);
>  +          }
>  +        }
>  +      }
> @@ -354,11 +344,7 @@ index 000000000..b554d4f31
>  +    }
>  +
>  +    GST_TRACE ("box size: %" G_GUINT32_FORMAT, size);
> -+    if (!gst_byte_reader_get_uint32_le (&reader, &fourcc)) {
> -+      GST_WARNING ("Failed to get fourcc, enough data?");
> -+      error = TRUE;
> -+      break;
> -+    }
> ++    fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader);
>  +
>  +    if (fourcc == GST_MSS_FRAGMENT_FOURCC_MDAT) {
>  +      GST_LOG ("mdat box found");
> @@ -367,8 +353,7 @@ index 000000000..b554d4f31
>  +    }
>  +
>  +    if (fourcc != GST_MSS_FRAGMENT_FOURCC_UUID) {
> -+      GST_ERROR ("invalid UUID fourcc: %" GST_FOURCC_FORMAT,
> -+          GST_FOURCC_ARGS (fourcc));
> ++      GST_ERROR ("invalid UUID fourcc");
>  +      error = TRUE;
>  +      break;
>  +    }
> @@ -403,8 +388,6 @@ index 000000000..b554d4f31
>  +    }
>  +  }
>  +
> -+beach:
> -+
>  +  if (!error)
>  +    parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_FINISHED;
>  +
> @@ -414,7 +397,7 @@ index 000000000..b554d4f31
>  +}
>  diff --git a/ext/smoothstreaming/gstmssfragmentparser.h b/ext/smoothstreaming/gstmssfragmentparser.h
>  new file mode 100644
> -index 000000000..cf4711865
> +index 0000000..6626358
>  --- /dev/null
>  +++ b/ext/smoothstreaming/gstmssfragmentparser.h
>  @@ -0,0 +1,84 @@
> @@ -423,8 +406,8 @@ index 000000000..cf4711865
>  + *
>  + * gstmssfragmentparser.h
>  + *
> -+ * Copyright (C) 2016 Igalia S.L
> -+ * Copyright (C) 2016 Metrological
> ++ * Copyright (C) 2015 Igalia S.L
> ++ * Copyright (C) 2015 Metrological
>  + *   Author: Philippe Normand <philn at igalia.com>
>  + *
>  + * This library is free software; you can redistribute it and/or
> @@ -503,14 +486,14 @@ index 000000000..cf4711865
>  +
>  +#endif /* __GST_MSS_FRAGMENT_PARSER_H__ */
>  diff --git a/ext/smoothstreaming/gstmssmanifest.c b/ext/smoothstreaming/gstmssmanifest.c
> -index 144bbb42d..e1031ba55 100644
> +index 1b72e8d..d50a51a 100644
>  --- a/ext/smoothstreaming/gstmssmanifest.c
>  +++ b/ext/smoothstreaming/gstmssmanifest.c
>  @@ -1,5 +1,7 @@
>   /* GStreamer
>    * Copyright (C) 2012 Smart TV Alliance
> -+ * Copyright (C) 2016 Igalia S.L
> -+ * Copyright (C) 2016 Metrological
> ++ * Copyright (C) 2015 Igalia S.L
> ++ * Copyright (C) 2015 Metrological
>    *  Author: Thiago Sousa Santos <thiago.sousa.santos at collabora.com>, Collabora Ltd.
>    *
>    * gstmssmanifest.c:
> @@ -522,12 +505,12 @@ index 144bbb42d..e1031ba55 100644
>   
>   GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug);
>   #define GST_CAT_DEFAULT mssdemux_debug
> -@@ -74,12 +77,17 @@ struct _GstMssStream
> +@@ -73,12 +76,17 @@ struct _GstMssStream
>     gboolean active;              /* if the stream is currently being used */
>     gint selectedQualityIndex;
>   
>  +  gboolean has_live_fragments;
> -+  GstAdapter *live_adapter;
> ++  GQueue live_fragments;
>  +
>     GList *fragments;
>     GList *qualities;
> @@ -540,15 +523,15 @@ index 144bbb42d..e1031ba55 100644
>     guint fragment_repetition_index;
>     GList *current_fragment;
>     GList *current_quality;
> -@@ -96,6 +104,7 @@ struct _GstMssManifest
> +@@ -94,6 +102,7 @@ struct _GstMssManifest
> +   xmlNodePtr xmlrootnode;
>   
>     gboolean is_live;
> -   gint64 dvr_window;
>  +  guint64 look_ahead_fragment_count;
>   
>     GString *protection_system_id;
>     gchar *protection_data;
> -@@ -235,7 +244,8 @@ compare_bitrate (GstMssStreamQuality * a, GstMssStreamQuality * b)
> +@@ -233,7 +242,8 @@ compare_bitrate (GstMssStreamQuality * a, GstMssStreamQuality * b)
>   }
>   
>   static void
> @@ -558,7 +541,7 @@ index 144bbb42d..e1031ba55 100644
>   {
>     xmlNodePtr iter;
>     GstMssFragmentListBuilder builder;
> -@@ -248,9 +258,21 @@ _gst_mss_stream_init (GstMssStream * stream, xmlNodePtr node)
> +@@ -246,9 +256,18 @@ _gst_mss_stream_init (GstMssStream * stream, xmlNodePtr node)
>     stream->url = (gchar *) xmlGetProp (node, (xmlChar *) MSS_PROP_URL);
>     stream->lang = (gchar *) xmlGetProp (node, (xmlChar *) MSS_PROP_LANGUAGE);
>   
> @@ -567,9 +550,6 @@ index 144bbb42d..e1031ba55 100644
>  +   * playlist can be built incrementally from the first fragment
>  +   * of the manifest.
>  +   */
> -+
> -+  GST_DEBUG ("Live stream: %s, look-ahead fragments: %" G_GUINT64_FORMAT,
> -+      manifest->is_live ? "yes" : "no", manifest->look_ahead_fragment_count);
>  +  stream->has_live_fragments = manifest->is_live
>  +      && manifest->look_ahead_fragment_count;
>  +
> @@ -581,13 +561,15 @@ index 144bbb42d..e1031ba55 100644
>       } else if (node_has_type (iter, MSS_NODE_STREAM_QUALITY)) {
>         GstMssStreamQuality *quality = gst_mss_stream_quality_new (iter);
>         stream->qualities = g_list_prepend (stream->qualities, quality);
> -@@ -259,17 +281,24 @@ _gst_mss_stream_init (GstMssStream * stream, xmlNodePtr node)
> +@@ -257,17 +276,26 @@ _gst_mss_stream_init (GstMssStream * stream, xmlNodePtr node)
>       }
>     }
>   
>  -  stream->fragments = g_list_reverse (builder.fragments);
>  +  if (stream->has_live_fragments) {
> -+    stream->live_adapter = gst_adapter_new ();
> ++    g_queue_init (&stream->live_fragments);
> ++    g_queue_push_tail (&stream->live_fragments, builder.fragments->data);
> ++    stream->current_fragment = g_queue_peek_head_link (&stream->live_fragments);
>  +  }
>  +
>  +  if (builder.fragments) {
> @@ -609,7 +591,7 @@ index 144bbb42d..e1031ba55 100644
>   }
>   
>   
> -@@ -315,6 +344,7 @@ gst_mss_manifest_new (GstBuffer * data)
> +@@ -313,6 +341,7 @@ gst_mss_manifest_new (GstBuffer * data)
>     xmlNodePtr nodeiter;
>     gchar *live_str;
>     GstMapInfo mapinfo;
> @@ -617,33 +599,21 @@ index 144bbb42d..e1031ba55 100644
>   
>     if (!gst_buffer_map (data, &mapinfo, GST_MAP_READ)) {
>       return NULL;
> -@@ -335,6 +365,7 @@ gst_mss_manifest_new (GstBuffer * data)
> -   /* the entire file is always available for non-live streams */
> -   if (!manifest->is_live) {
> -     manifest->dvr_window = 0;
> -+    manifest->look_ahead_fragment_count = 0;
> -   } else {
> -     /* if 0, or non-existent, the length is infinite */
> -     gchar *dvr_window_str = (gchar *) xmlGetProp (root,
> -@@ -346,6 +377,17 @@ gst_mss_manifest_new (GstBuffer * data)
> -         manifest->dvr_window = 0;
> -       }
> -     }
> -+
> -+    look_ahead_fragment_count_str =
> -+        (gchar *) xmlGetProp (root, (xmlChar *) "LookAheadFragmentCount");
> -+    if (look_ahead_fragment_count_str) {
> -+      manifest->look_ahead_fragment_count =
> -+          g_ascii_strtoull (look_ahead_fragment_count_str, NULL, 10);
> -+      xmlFree (look_ahead_fragment_count_str);
> -+      if (manifest->look_ahead_fragment_count <= 0) {
> -+        manifest->look_ahead_fragment_count = 0;
> -+      }
> -+    }
> +@@ -330,13 +359,21 @@ gst_mss_manifest_new (GstBuffer * data)
> +     xmlFree (live_str);
>     }
>   
> ++  look_ahead_fragment_count_str =
> ++      (gchar *) xmlGetProp (root, (xmlChar *) "LookAheadFragmentCount");
> ++  if (look_ahead_fragment_count_str) {
> ++    manifest->look_ahead_fragment_count =
> ++        g_ascii_strtoull (look_ahead_fragment_count_str, NULL, 10);
> ++    xmlFree (look_ahead_fragment_count_str);
> ++  }
> ++
>     for (nodeiter = root->children; nodeiter; nodeiter = nodeiter->next) {
> -@@ -354,7 +396,7 @@ gst_mss_manifest_new (GstBuffer * data)
> +     if (nodeiter->type == XML_ELEMENT_NODE
> +         && (strcmp ((const char *) nodeiter->name, "StreamIndex") == 0)) {
>         GstMssStream *stream = g_new0 (GstMssStream, 1);
>   
>         manifest->streams = g_slist_append (manifest->streams, stream);
> @@ -652,39 +622,56 @@ index 144bbb42d..e1031ba55 100644
>       }
>   
>       if (nodeiter->type == XML_ELEMENT_NODE
> -@@ -371,6 +413,11 @@ gst_mss_manifest_new (GstBuffer * data)
> +@@ -353,13 +390,19 @@ gst_mss_manifest_new (GstBuffer * data)
>   static void
>   gst_mss_stream_free (GstMssStream * stream)
>   {
> -+  if (stream->live_adapter) {
> -+    gst_adapter_clear (stream->live_adapter);
> -+    g_object_unref (stream->live_adapter);
> +-  g_list_free_full (stream->fragments, g_free);
> ++  if (stream->has_live_fragments) {
> ++    g_queue_foreach (&stream->live_fragments, (GFunc) g_free, NULL);
> ++    g_queue_clear (&stream->live_fragments);
> ++  } else {
> ++    g_list_free_full (stream->fragments, g_free);
>  +  }
> -+
> -   g_list_free_full (stream->fragments, g_free);
>     g_list_free_full (stream->qualities,
>         (GDestroyNotify) gst_mss_stream_quality_free);
> -@@ -379,6 +426,7 @@ gst_mss_stream_free (GstMssStream * stream)
> +   xmlFree (stream->url);
> +   xmlFree (stream->lang);
>     g_regex_unref (stream->regex_position);
>     g_regex_unref (stream->regex_bitrate);
> -   g_free (stream);
>  +  gst_mss_fragment_parser_clear (&stream->fragment_parser);
> +   g_free (stream);
>   }
>   
> - void
> -@@ -1079,6 +1127,9 @@ GstFlowReturn
> +@@ -984,7 +1027,12 @@ gst_mss_stream_get_fragment_gst_timestamp (GstMssStream * stream)
> +   g_return_val_if_fail (stream->active, GST_CLOCK_TIME_NONE);
> + 
> +   if (!stream->current_fragment) {
> +-    GList *last = g_list_last (stream->fragments);
> ++    GList *last;
> ++
> ++    if (stream->has_live_fragments)
> ++      last = g_queue_peek_tail_link (&stream->live_fragments);
> ++    else
> ++      last = g_list_last (stream->fragments);
> +     if (last == NULL)
> +       return GST_CLOCK_TIME_NONE;
> + 
> +@@ -1037,21 +1085,54 @@ GstFlowReturn
>   gst_mss_stream_advance_fragment (GstMssStream * stream)
>   {
>     GstMssStreamFragment *fragment;
> ++  GstMssStreamFragment *prev_fragment;
>  +  const gchar *stream_type_name =
>  +      gst_mss_stream_type_name (gst_mss_stream_get_type (stream));
>  +
>     g_return_val_if_fail (stream->active, GST_FLOW_ERROR);
>   
>     if (stream->current_fragment == NULL)
> -@@ -1086,14 +1137,20 @@ gst_mss_stream_advance_fragment (GstMssStream * stream)
> +     return GST_FLOW_EOS;
>   
> -   fragment = stream->current_fragment->data;
> +-  fragment = stream->current_fragment->data;
> ++  prev_fragment = fragment = stream->current_fragment->data;
>     stream->fragment_repetition_index++;
>  -  if (stream->fragment_repetition_index < fragment->repetitions) {
>  -    return GST_FLOW_OK;
> @@ -693,10 +680,34 @@ index 144bbb42d..e1031ba55 100644
>  +    goto beach;
>   
>     stream->fragment_repetition_index = 0;
> -   stream->current_fragment = g_list_next (stream->current_fragment);
> +-  stream->current_fragment = g_list_next (stream->current_fragment);
> ++
> ++  if (stream->has_live_fragments)
> ++    stream->current_fragment = g_queue_pop_head_link (&stream->live_fragments);
> ++  else
> ++    stream->current_fragment = g_list_next (stream->current_fragment);
> ++
> ++  if (stream->current_fragment != NULL) {
> ++    fragment = stream->current_fragment->data;
> ++    if (fragment->time <= prev_fragment->time) {
> ++      while (fragment->time <= prev_fragment->time) {
> ++        if (stream->has_live_fragments)
> ++          stream->current_fragment =
> ++              g_queue_pop_head_link (&stream->live_fragments);
> ++        else
> ++          stream->current_fragment = g_list_next (stream->current_fragment);
> ++        if (stream->current_fragment == NULL)
> ++          break;
> ++        fragment = stream->current_fragment->data;
> ++      }
> ++    }
> ++  }
>  +
>  +  GST_DEBUG ("Advanced to fragment #%d on %s stream", fragment->number,
>  +      stream_type_name);
> ++  if (stream->has_live_fragments)
> ++    GST_LOG ("%u fragments left in the %s stream queue",
> ++        g_queue_get_length (&stream->live_fragments), stream_type_name);
>     if (stream->current_fragment == NULL)
>       return GST_FLOW_EOS;
>  +
> @@ -706,57 +717,22 @@ index 144bbb42d..e1031ba55 100644
>     return GST_FLOW_OK;
>   }
>   
> -@@ -1173,6 +1230,11 @@ gst_mss_stream_seek (GstMssStream * stream, gboolean forward,
> -   GST_DEBUG ("Stream %s seeking to %" G_GUINT64_FORMAT, stream->url, time);
> -   for (iter = stream->fragments; iter; iter = g_list_next (iter)) {
> -     fragment = iter->data;
> -+    if (stream->has_live_fragments) {
> -+      if (fragment->time + fragment->repetitions * fragment->duration > time)
> -+        stream->current_fragment = iter;
> -+      break;
> -+    }
> -     if (fragment->time + fragment->repetitions * fragment->duration > time) {
> -       stream->current_fragment = iter;
> -       stream->fragment_repetition_index =
> -@@ -1256,9 +1318,14 @@ static void
> - gst_mss_stream_reload_fragments (GstMssStream * stream, xmlNodePtr streamIndex)
> - {
> -   xmlNodePtr iter;
> --  guint64 current_gst_time = gst_mss_stream_get_fragment_gst_timestamp (stream);
> -+  guint64 current_gst_time;
> -   GstMssFragmentListBuilder builder;
> +@@ -1125,6 +1206,10 @@ gst_mss_stream_seek (GstMssStream * stream, gboolean forward,
> +   guint64 timescale;
> +   GstMssStreamFragment *fragment = NULL;
>   
> ++  // FIXME: Seek support for live scenario using DVR window.
>  +  if (stream->has_live_fragments)
>  +    return;
>  +
> -+  current_gst_time = gst_mss_stream_get_fragment_gst_timestamp (stream);
> -+
> -   gst_mss_fragment_list_builder_init (&builder);
> +   timescale = gst_mss_stream_get_timescale (stream);
> +   time = gst_util_uint64_scale_round (time, timescale, GST_SECOND);
>   
> -   GST_DEBUG ("Current position: %" GST_TIME_FORMAT,
> -@@ -1514,3 +1581,74 @@ gst_mss_manifest_get_live_seek_range (GstMssManifest * manifest, gint64 * start,
> - 
> -   return ret;
> +@@ -1406,3 +1491,47 @@ gst_mss_stream_get_lang (GstMssStream * stream)
> + {
> +   return stream->lang;
>   }
>  +
> -+void
> -+gst_mss_manifest_live_adapter_push (GstMssStream * stream, GstBuffer * buffer)
> -+{
> -+  gst_adapter_push (stream->live_adapter, buffer);
> -+}
> -+
> -+gsize
> -+gst_mss_manifest_live_adapter_available (GstMssStream * stream)
> -+{
> -+  return gst_adapter_available (stream->live_adapter);
> -+}
> -+
> -+GstBuffer *
> -+gst_mss_manifest_live_adapter_take_buffer (GstMssStream * stream, gsize nbytes)
> -+{
> -+  return gst_adapter_take_buffer (stream->live_adapter, nbytes);
> -+}
> -+
>  +gboolean
>  +gst_mss_stream_fragment_parsing_needed (GstMssStream * stream)
>  +{
> @@ -764,11 +740,11 @@ index 144bbb42d..e1031ba55 100644
>  +}
>  +
>  +void
> -+gst_mss_stream_parse_fragment (GstMssStream * stream, GstBuffer * buffer)
> ++gst_mss_stream_fragment_parse (GstMssStream * stream, GstBuffer * buffer)
>  +{
>  +  GstMssStreamFragment *current_fragment = NULL;
> -+  const gchar *stream_type_name;
> -+  guint8 index;
> ++  const gchar *stream_type_name =
> ++      gst_mss_stream_type_name (gst_mss_stream_get_type (stream));
>  +
>  +  if (!stream->has_live_fragments)
>  +    return;
> @@ -780,29 +756,20 @@ index 144bbb42d..e1031ba55 100644
>  +  current_fragment->time = stream->fragment_parser.tfxd.time;
>  +  current_fragment->duration = stream->fragment_parser.tfxd.duration;
>  +
> -+  stream_type_name =
> -+      gst_mss_stream_type_name (gst_mss_stream_get_type (stream));
> -+
> -+  for (index = 0; index < stream->fragment_parser.tfrf.entries_count; index++) {
> -+    GList *l = g_list_last (stream->fragments);
> -+    GstMssStreamFragment *last;
> ++  for (guint8 index = 0; index < stream->fragment_parser.tfrf.entries_count;
> ++      index++) {
> ++    GstMssStreamFragment *last = g_queue_peek_tail (&stream->live_fragments);
>  +    GstMssStreamFragment *fragment;
>  +
> -+    if (l == NULL)
> -+      break;
> -+
> -+    last = (GstMssStreamFragment *) l->data;
> -+
> -+    if (last->time == stream->fragment_parser.tfrf.entries[index].time)
> -+      continue;
> -+
> ++    if (last == NULL)
> ++        break;
>  +    fragment = g_new (GstMssStreamFragment, 1);
>  +    fragment->number = last->number + 1;
>  +    fragment->repetitions = 1;
>  +    fragment->time = stream->fragment_parser.tfrf.entries[index].time;
>  +    fragment->duration = stream->fragment_parser.tfrf.entries[index].duration;
>  +
> -+    stream->fragments = g_list_append (stream->fragments, fragment);
> ++    g_queue_push_tail (&stream->live_fragments, fragment);
>  +    GST_LOG ("Adding fragment number: %u to %s stream, time: %" G_GUINT64_FORMAT
>  +        ", duration: %" G_GUINT64_FORMAT ", repetitions: %u",
>  +        fragment->number, stream_type_name,
> @@ -810,31 +777,20 @@ index 144bbb42d..e1031ba55 100644
>  +  }
>  +}
>  diff --git a/ext/smoothstreaming/gstmssmanifest.h b/ext/smoothstreaming/gstmssmanifest.h
> -index 6b7b1f971..03b066ae5 100644
> +index af7419c..039877f 100644
>  --- a/ext/smoothstreaming/gstmssmanifest.h
>  +++ b/ext/smoothstreaming/gstmssmanifest.h
> -@@ -26,6 +26,7 @@
> - #include <glib.h>
> - #include <gio/gio.h>
> - #include <gst/gst.h>
> -+#include <gst/base/gstadapter.h>
> - 
> - G_BEGIN_DECLS
> - 
> -@@ -73,5 +74,11 @@ const gchar * gst_mss_stream_get_lang (GstMssStream * stream);
> +@@ -72,5 +72,8 @@ const gchar * gst_mss_stream_get_lang (GstMssStream * stream);
>   
>   const gchar * gst_mss_stream_type_name (GstMssStreamType streamtype);
>   
> -+void gst_mss_manifest_live_adapter_push(GstMssStream * stream, GstBuffer * buffer);
> -+gsize gst_mss_manifest_live_adapter_available(GstMssStream * stream);
> -+GstBuffer * gst_mss_manifest_live_adapter_take_buffer(GstMssStream * stream, gsize nbytes);
>  +gboolean gst_mss_stream_fragment_parsing_needed(GstMssStream * stream);
> -+void gst_mss_stream_parse_fragment(GstMssStream * stream, GstBuffer * buffer);
> ++void gst_mss_stream_fragment_parse(GstMssStream * stream, GstBuffer * buffer);
>  +
>   G_END_DECLS
>   #endif /* __GST_MSS_MANIFEST_H__ */
>  diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
> -index 634e4f388..ddca726b6 100644
> +index bf311d3..20bd839 100644
>  --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
>  +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
>  @@ -291,6 +291,9 @@ gst_adaptive_demux_wait_until (GstClock * clock, GCond * cond, GMutex * mutex,
> @@ -868,7 +824,7 @@ index 634e4f388..ddca726b6 100644
>             }
>           } else {
>             /* no streams */
> -@@ -2125,6 +2133,13 @@ gst_adaptive_demux_stream_data_received_default (GstAdaptiveDemux * demux,
> +@@ -2113,6 +2121,13 @@ gst_adaptive_demux_stream_data_received_default (GstAdaptiveDemux * demux,
>     return gst_adaptive_demux_stream_push_buffer (stream, buffer);
>   }
>   
> @@ -882,25 +838,33 @@ index 634e4f388..ddca726b6 100644
>   static GstFlowReturn
>   _src_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
>   {
> -@@ -3338,7 +3353,15 @@ gst_adaptive_demux_stream_download_loop (GstAdaptiveDemuxStream * stream)
> +@@ -2209,7 +2224,7 @@ _src_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
> +       stream->download_chunk_start_time;
> +   stream->download_total_bytes += gst_buffer_get_size (buffer);
> + 
> +-  GST_DEBUG_OBJECT (stream->pad, "Received buffer of size %" G_GSIZE_FORMAT,
> ++  GST_LOG_OBJECT (stream->pad, "Received buffer of size %" G_GSIZE_FORMAT,
> +       gst_buffer_get_size (buffer));
> + 
> +   ret = klass->data_received (demux, stream, buffer);
> +@@ -3326,7 +3341,14 @@ gst_adaptive_demux_stream_download_loop (GstAdaptiveDemuxStream * stream)
>         GST_DEBUG_OBJECT (stream->pad, "EOS, checking to stop download loop");
>         /* we push the EOS after releasing the object lock */
>         if (gst_adaptive_demux_is_live (demux)) {
>  -        if (gst_adaptive_demux_stream_wait_manifest_update (demux, stream)) {
>  +        GstAdaptiveDemuxClass *demux_class =
> -+            GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
> ++          GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
>  +
>  +        /* this might be a fragment download error, refresh the manifest, just in case */
>  +        if (!demux_class->requires_periodical_playlist_update (demux)) {
>  +          ret = gst_adaptive_demux_update_manifest (demux);
>  +          break;
> -+        } else if (gst_adaptive_demux_stream_wait_manifest_update (demux,
> -+                stream)) {
> ++        } else if (gst_adaptive_demux_stream_wait_manifest_update (demux, stream)) {
>             goto end;
>           }
>           gst_task_stop (stream->download_task);
>  diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h
> -index 780f4d93f..9a1a1b7d1 100644
> +index 780f4d9..9a1a1b7 100644
>  --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h
>  +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h
>  @@ -459,6 +459,20 @@ struct _GstAdaptiveDemuxClass
> @@ -925,5 +889,5 @@ index 780f4d93f..9a1a1b7d1 100644
>   
>   GType    gst_adaptive_demux_get_type (void);
>  -- 
> -2.11.0
> +2.7.4
>  
> diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch
> index 76d29e151b..c4639a2cda 100644
> --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch
> +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch
> @@ -1,7 +1,7 @@
> -From e9178fa082116d4bf733b184a8b6951112c17900 Mon Sep 17 00:00:00 2001
> +From e8155c77d8dcaf39ec564b85c4a56e64fce6de2b Mon Sep 17 00:00:00 2001
>  From: Matthew Waters <matthew at centricular.com>
>  Date: Thu, 10 Nov 2016 17:18:36 +1100
> -Subject: [PATCH] smoothstreaming: implement adaptivedemux's
> +Subject: [PATCH 1/2] smoothstreaming: implement adaptivedemux's
>   get_live_seek_range()
>  
>  Allows seeking through the available fragments that are still available
> @@ -10,40 +10,45 @@ manifest.
>  
>  https://bugzilla.gnome.org/show_bug.cgi?id=774178
>  ---
> -Upstream-Status: Backport
> -Signed-off-by: Khem Raj <raj.khem at gmail.com>
> -
> - ext/smoothstreaming/gstmssdemux.c    | 13 ++++++
> + ext/smoothstreaming/gstmssdemux.c    | 14 +++++-
>   ext/smoothstreaming/gstmssmanifest.c | 84 ++++++++++++++++++++++++++++++++++++
>   ext/smoothstreaming/gstmssmanifest.h |  1 +
> - 3 files changed, 98 insertions(+)
> + 3 files changed, 98 insertions(+), 1 deletion(-)
>  
>  diff --git a/ext/smoothstreaming/gstmssdemux.c b/ext/smoothstreaming/gstmssdemux.c
> -index 9d0aece2b..b66e19514 100644
> +index 1a122d4..26147fd 100644
>  --- a/ext/smoothstreaming/gstmssdemux.c
>  +++ b/ext/smoothstreaming/gstmssdemux.c
> -@@ -138,6 +138,8 @@ gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux);
> - static GstFlowReturn
> - gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
> -     GstBuffer * buffer);
> +@@ -146,6 +146,8 @@ static GstFlowReturn gst_mss_demux_data_received (GstAdaptiveDemux * demux,
> +     GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
> + static gboolean
> + gst_mss_demux_requires_periodical_playlist_update (GstAdaptiveDemux * demux);
>  +static gboolean gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux,
>  +    gint64 * start, gint64 * stop);
>   
>   static void
>   gst_mss_demux_class_init (GstMssDemuxClass * klass)
> -@@ -192,6 +194,8 @@ gst_mss_demux_class_init (GstMssDemuxClass * klass)
> -       gst_mss_demux_stream_update_fragment_info;
> -   gstadaptivedemux_class->update_manifest_data =
> -       gst_mss_demux_update_manifest_data;
> +@@ -206,6 +208,8 @@ gst_mss_demux_class_init (GstMssDemuxClass * klass)
> +   gstadaptivedemux_class->data_received = gst_mss_demux_data_received;
> +   gstadaptivedemux_class->requires_periodical_playlist_update =
> +       gst_mss_demux_requires_periodical_playlist_update;
>  +  gstadaptivedemux_class->get_live_seek_range =
>  +      gst_mss_demux_get_live_seek_range;
>   
>     GST_DEBUG_CATEGORY_INIT (mssdemux_debug, "mssdemux", 0, "mssdemux plugin");
>   }
> -@@ -659,3 +663,12 @@ gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
> -   gst_mss_manifest_reload_fragments (mssdemux->manifest, buffer);
> +@@ -694,7 +698,6 @@ gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
>     return GST_FLOW_OK;
>   }
> + 
> +-
> + static GstFlowReturn
> + gst_mss_demux_data_received (GstAdaptiveDemux * demux,
> +     GstAdaptiveDemuxStream * stream, GstBuffer *buffer)
> +@@ -739,3 +742,12 @@ gst_mss_demux_requires_periodical_playlist_update (GstAdaptiveDemux * demux)
> + 
> +   return (!gst_mss_manifest_is_live (mssdemux->manifest));
> + }
>  +
>  +static gboolean
>  +gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
> @@ -54,10 +59,10 @@ index 9d0aece2b..b66e19514 100644
>  +  return gst_mss_manifest_get_live_seek_range (mssdemux->manifest, start, stop);
>  +}
>  diff --git a/ext/smoothstreaming/gstmssmanifest.c b/ext/smoothstreaming/gstmssmanifest.c
> -index 1b72e8de1..317b3cef9 100644
> +index b9dacb3..291080a 100644
>  --- a/ext/smoothstreaming/gstmssmanifest.c
>  +++ b/ext/smoothstreaming/gstmssmanifest.c
> -@@ -42,6 +42,7 @@ GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug);
> +@@ -45,6 +45,7 @@ GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug);
>   
>   #define MSS_PROP_BITRATE              "Bitrate"
>   #define MSS_PROP_DURATION             "d"
> @@ -65,16 +70,16 @@ index 1b72e8de1..317b3cef9 100644
>   #define MSS_PROP_LANGUAGE             "Language"
>   #define MSS_PROP_NUMBER               "n"
>   #define MSS_PROP_REPETITIONS          "r"
> -@@ -94,6 +95,7 @@ struct _GstMssManifest
> -   xmlNodePtr xmlrootnode;
> +@@ -103,6 +104,7 @@ struct _GstMssManifest
>   
>     gboolean is_live;
> +   guint64 look_ahead_fragment_count;
>  +  gint64 dvr_window;
>   
>     GString *protection_system_id;
>     gchar *protection_data;
> -@@ -330,6 +332,22 @@ gst_mss_manifest_new (GstBuffer * data)
> -     xmlFree (live_str);
> +@@ -367,6 +369,22 @@ gst_mss_manifest_new (GstBuffer * data)
> +     xmlFree (look_ahead_fragment_count_str);
>     }
>   
>  +  /* the entire file is always available for non-live streams */
> @@ -96,9 +101,9 @@ index 1b72e8de1..317b3cef9 100644
>     for (nodeiter = root->children; nodeiter; nodeiter = nodeiter->next) {
>       if (nodeiter->type == XML_ELEMENT_NODE
>           && (strcmp ((const char *) nodeiter->name, "StreamIndex") == 0)) {
> -@@ -1406,3 +1424,69 @@ gst_mss_stream_get_lang (GstMssStream * stream)
> - {
> -   return stream->lang;
> +@@ -1546,3 +1564,69 @@ gst_mss_stream_fragment_parse (GstMssStream * stream, GstBuffer * buffer)
> +         fragment->time, fragment->duration, fragment->repetitions);
> +   }
>   }
>  +
>  +static GstClockTime
> @@ -167,7 +172,7 @@ index 1b72e8de1..317b3cef9 100644
>  +  return ret;
>  +}
>  diff --git a/ext/smoothstreaming/gstmssmanifest.h b/ext/smoothstreaming/gstmssmanifest.h
> -index af7419c23..6b7b1f971 100644
> +index 039877f..29545af 100644
>  --- a/ext/smoothstreaming/gstmssmanifest.h
>  +++ b/ext/smoothstreaming/gstmssmanifest.h
>  @@ -54,6 +54,7 @@ void gst_mss_manifest_reload_fragments (GstMssManifest * manifest, GstBuffer * d
> @@ -179,5 +184,5 @@ index af7419c23..6b7b1f971 100644
>   GstMssStreamType gst_mss_stream_get_type (GstMssStream *stream);
>   GstCaps * gst_mss_stream_get_caps (GstMssStream * stream);
>  -- 
> -2.11.0
> +1.8.3.2
>  
> diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-adaptivedemux-minimal-HTTP-context-support.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-adaptivedemux-minimal-HTTP-context-support.patch
> new file mode 100644
> index 0000000000..8a4ca68d83
> --- /dev/null
> +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-adaptivedemux-minimal-HTTP-context-support.patch
> @@ -0,0 +1,142 @@
> +From 992bd23193978742029966e0a2232b1bfcc06122 Mon Sep 17 00:00:00 2001
> +From: Philippe Normand <philn at igalia.com>
> +Date: Wed, 28 Oct 2015 11:52:49 +0100
> +Subject: [PATCH 3/6] adaptivedemux: minimal HTTP context support
> +
> +The uridownloader is now querying the source element for an HTTP
> +context, which stores session data (cookies only for now), and reusing
> +the data when fetching data over HTTP. Additionally the context is set
> +on adaptivedemux, which allows it to also properly use session data
> +when downloading fragments.
> +
> +https://bugzilla.gnome.org/show_bug.cgi?id=726314
> +---
> + gst-libs/gst/adaptivedemux/gstadaptivedemux.c | 16 ++++++++++++-
> + gst-libs/gst/uridownloader/gsturidownloader.c | 34 +++++++++++++++++++++++++--
> + gst-libs/gst/uridownloader/gsturidownloader.h |  2 +-
> + 3 files changed, 48 insertions(+), 4 deletions(-)
> +
> +diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
> +index 20bd839..1b5cace 100644
> +--- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
> ++++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
> +@@ -432,7 +432,7 @@ gst_adaptive_demux_init (GstAdaptiveDemux * demux,
> + 
> +   demux->priv = GST_ADAPTIVE_DEMUX_GET_PRIVATE (demux);
> +   demux->priv->input_adapter = gst_adapter_new ();
> +-  demux->downloader = gst_uri_downloader_new ();
> ++  demux->downloader = gst_uri_downloader_new (GST_ELEMENT (demux));
> +   demux->stream_struct_size = sizeof (GstAdaptiveDemuxStream);
> +   demux->priv->segment_seqnum = gst_util_seqnum_next ();
> +   demux->have_group_id = FALSE;
> +@@ -2547,6 +2547,7 @@ gst_adaptive_demux_stream_update_source (GstAdaptiveDemuxStream * stream,
> +     GstPadLinkReturn pad_link_ret;
> +     GObjectClass *gobject_class;
> +     gchar *internal_name, *bin_name;
> ++    GstContext *context = NULL;
> + 
> +     /* Our src consists of a bin containing uri_handler -> queue2 . The
> +      * purpose of the queue2 is to allow the uri_handler to download an
> +@@ -2598,6 +2599,19 @@ gst_adaptive_demux_stream_update_source (GstAdaptiveDemuxStream * stream,
> +       }
> +     }
> + 
> ++    context =
> ++        gst_element_get_context (GST_ELEMENT_CAST (demux), "http-headers");
> ++    if (context) {
> ++      const GstStructure *s = gst_context_get_structure (context);
> ++      const gchar **cookies = NULL;
> ++      gst_structure_get (s, "cookies", G_TYPE_STRV, &cookies, NULL);
> ++      if (cookies) {
> ++        GST_DEBUG_OBJECT (demux, "Passing cookies through");
> ++        g_object_set (uri_handler, "cookies", cookies, NULL);
> ++      }
> ++      gst_context_unref (context);
> ++    }
> ++
> +     /* Source bin creation */
> +     bin_name = g_strdup_printf ("srcbin-%s", GST_PAD_NAME (stream->pad));
> +     stream->src = gst_bin_new (bin_name);
> +diff --git a/gst-libs/gst/uridownloader/gsturidownloader.c b/gst-libs/gst/uridownloader/gsturidownloader.c
> +index 47b6f29..1f61250 100644
> +--- a/gst-libs/gst/uridownloader/gsturidownloader.c
> ++++ b/gst-libs/gst/uridownloader/gsturidownloader.c
> +@@ -33,6 +33,8 @@ GST_DEBUG_CATEGORY (uridownloader_debug);
> + 
> + struct _GstUriDownloaderPrivate
> + {
> ++  GstElement *parent;
> ++
> +   /* Fragments fetcher */
> +   GstElement *urisrc;
> +   GstBus *bus;
> +@@ -148,9 +150,11 @@ gst_uri_downloader_finalize (GObject * object)
> + }
> + 
> + GstUriDownloader *
> +-gst_uri_downloader_new (void)
> ++gst_uri_downloader_new (GstElement * parent)
> + {
> +-  return g_object_new (GST_TYPE_URI_DOWNLOADER, NULL);
> ++  GstUriDownloader *downloader = g_object_new (GST_TYPE_URI_DOWNLOADER, NULL);
> ++  downloader->priv->parent = parent;
> ++  return downloader;
> + }
> + 
> + static gboolean
> +@@ -413,6 +417,7 @@ gst_uri_downloader_set_uri (GstUriDownloader * downloader, const gchar * uri,
> + {
> +   GstPad *pad;
> +   GObjectClass *gobject_class;
> ++  GstContext *context = NULL;
> + 
> +   if (!gst_uri_is_valid (uri))
> +     return FALSE;
> +@@ -449,6 +454,31 @@ gst_uri_downloader_set_uri (GstUriDownloader * downloader, const gchar * uri,
> +     }
> +   }
> + 
> ++  context = gst_element_get_context (downloader->priv->parent, "http-headers");
> ++  if (!context) {
> ++    GstQuery *context_query = gst_query_new_context ("http-headers");
> ++    GstPad *parent_sink_pad =
> ++        gst_element_get_static_pad (downloader->priv->parent, "sink");
> ++    if (gst_pad_peer_query (parent_sink_pad, context_query)) {
> ++
> ++      gst_query_parse_context (context_query, &context);
> ++      gst_element_set_context (downloader->priv->parent, context);
> ++    }
> ++    gst_object_unref (parent_sink_pad);
> ++    gst_query_unref (context_query);
> ++  }
> ++
> ++  if (context) {
> ++    const GstStructure *s = gst_context_get_structure (context);
> ++    const gchar **cookies = NULL;
> ++    gst_structure_get (s, "cookies", G_TYPE_STRV, &cookies, NULL);
> ++    if (cookies) {
> ++      GST_DEBUG_OBJECT (downloader, "Passing cookies through");
> ++      g_object_set (downloader->priv->urisrc, "cookies", cookies, NULL);
> ++    }
> ++    gst_context_unref (context);
> ++  }
> ++
> +   /* add a sync handler for the bus messages to detect errors in the download */
> +   gst_element_set_bus (GST_ELEMENT (downloader->priv->urisrc),
> +       downloader->priv->bus);
> +diff --git a/gst-libs/gst/uridownloader/gsturidownloader.h b/gst-libs/gst/uridownloader/gsturidownloader.h
> +index 80b8a3e..36cbf65 100644
> +--- a/gst-libs/gst/uridownloader/gsturidownloader.h
> ++++ b/gst-libs/gst/uridownloader/gsturidownloader.h
> +@@ -60,7 +60,7 @@ struct _GstUriDownloaderClass
> + 
> + GType gst_uri_downloader_get_type (void);
> + 
> +-GstUriDownloader * gst_uri_downloader_new (void);
> ++GstUriDownloader * gst_uri_downloader_new (GstElement * parent);
> + GstFragment * gst_uri_downloader_fetch_uri (GstUriDownloader * downloader, const gchar * uri, const gchar * referer, gboolean compress, gboolean refresh, gboolean allow_cache, GError ** err);
> + GstFragment * gst_uri_downloader_fetch_uri_with_range (GstUriDownloader * downloader, const gchar * uri, const gchar * referer, gboolean compress, gboolean refresh, gboolean allow_cache, gint64 range_start, gint64 range_end, GError ** err);
> + void gst_uri_downloader_reset (GstUriDownloader *downloader);
> +-- 
> +2.7.4
> +
> diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-mpdparser-MS-PlayReady-ContentProtection-parsing.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-mpdparser-MS-PlayReady-ContentProtection-parsing.patch
> new file mode 100644
> index 0000000000..97d83aa4f7
> --- /dev/null
> +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-mpdparser-MS-PlayReady-ContentProtection-parsing.patch
> @@ -0,0 +1,109 @@
> +From cbf3d75b3d693e50722534d30a8f51995a419803 Mon Sep 17 00:00:00 2001
> +From: Philippe Normand <philn at igalia.com>
> +Date: Fri, 4 Nov 2016 09:56:33 +0100
> +Subject: [PATCH 5/6] mpdparser: MS PlayReady ContentProtection parsing
> +
> +The "pro" (PlayReady Object) element contents are now base64-decoded
> +and properly stored in Protection events.
> +
> +https://bugzilla.gnome.org/show_bug.cgi?id=773936
> +---
> + ext/dash/gstdashdemux.c |  2 +-
> + ext/dash/gstmpdparser.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> + ext/dash/gstmpdparser.h |  1 +
> + 3 files changed, 42 insertions(+), 2 deletions(-)
> +
> +diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c
> +index 271f70f..b10465e 100644
> +--- a/ext/dash/gstdashdemux.c
> ++++ b/ext/dash/gstdashdemux.c
> +@@ -745,7 +745,7 @@ gst_dash_demux_send_content_protection_event (gpointer data, gpointer userdata)
> +   /* RFC 2141 states: The leading "urn:" sequence is case-insensitive */
> +   schemeIdUri = g_ascii_strdown (cp->schemeIdUri, -1);
> +   if (g_str_has_prefix (schemeIdUri, "urn:uuid:")) {
> +-    pssi_len = strlen (cp->value);
> ++    pssi_len = cp->value_len;
> +     pssi = gst_buffer_new_wrapped (g_memdup (cp->value, pssi_len), pssi_len);
> +     GST_LOG_OBJECT (stream, "Queuing Protection event on source pad");
> +     /* RFC 4122 states that the hex part of a UUID is in lower case,
> +diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c
> +index 15d6d98..f0b3ceb 100644
> +--- a/ext/dash/gstmpdparser.c
> ++++ b/ext/dash/gstmpdparser.c
> +@@ -1313,6 +1313,7 @@ gst_mpdparser_parse_descriptor_type_node (GList ** list, xmlNode * a_node)
> +     /* if no value attribute, use XML string representation of the node */
> +     gst_mpdparser_get_xml_node_as_string (a_node, &new_descriptor->value);
> +   }
> ++  new_descriptor->value_len = strlen(new_descriptor->value);
> + }
> + 
> + static void
> +@@ -1734,6 +1735,44 @@ error:
> + }
> + 
> + 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) {
> ++            gsize decoded_len;
> ++            GstDescriptorType *new_descriptor;
> ++            new_descriptor = g_slice_new0 (GstDescriptorType);
> ++            *list = g_list_append (*list, new_descriptor);
> ++
> ++            gst_mpdparser_get_xml_prop_string (a_node, "schemeIdUri",
> ++                &new_descriptor->schemeIdUri);
> ++
> ++            gst_mpdparser_get_xml_node_content (cur_node,
> ++                &new_descriptor->value);
> ++            g_base64_decode_inplace (new_descriptor->value, &decoded_len);
> ++            *(new_descriptor->value + decoded_len) = '\0';
> ++            new_descriptor->value_len = decoded_len;
> ++            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)
> + {
> +@@ -1788,7 +1827,7 @@ gst_mpdparser_parse_representation_base_type (GstRepresentationBaseType **
> +             (&representation_base->AudioChannelConfiguration, cur_node);
> +       } else if (xmlStrcmp (cur_node->name,
> +               (xmlChar *) "ContentProtection") == 0) {
> +-        gst_mpdparser_parse_descriptor_type_node
> ++        gst_mpdparser_parse_content_protection_node
> +             (&representation_base->ContentProtection, cur_node);
> +       }
> +     }
> +diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h
> +index 85b97ea..738de68 100644
> +--- a/ext/dash/gstmpdparser.h
> ++++ b/ext/dash/gstmpdparser.h
> +@@ -277,6 +277,7 @@ struct _GstDescriptorType
> + {
> +   gchar *schemeIdUri;
> +   gchar *value;
> ++  glong value_len;
> + };
> + 
> + struct _GstContentComponentNode
> +-- 
> +2.7.4
> +
> diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.10.4.bb b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.10.4.bb
> index 0bb4053e43..c894945748 100644
> --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.10.4.bb
> +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.10.4.bb
> @@ -11,13 +11,16 @@ SRC_URI = " \
>      file://fix-maybe-uninitialized-warnings-when-compiling-with-Os.patch \
>      file://avoid-including-sys-poll.h-directly.patch \
>      file://ensure-valid-sentinels-for-gst_structure_get-etc.patch \
> +    file://0001-mssdemux-improved-live-playback-support.patch \
>      file://0001-gstreamer-gl.pc.in-don-t-append-GL_CFLAGS-to-CFLAGS.patch \
> -    file://0009-glimagesink-Downrank-to-marginal.patch \
>      file://0001-introspection.m4-prefix-pkgconfig-paths-with-PKG_CON.patch \
>      file://0001-Prepend-PKG_CONFIG_SYSROOT_DIR-to-pkg-config-output.patch \
> -    file://0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch \
>      file://0001-smoothstreaming-use-the-duration-from-the-list-of-fr.patch \
> -    file://0001-mssdemux-improved-live-playback-support.patch \
> +    file://0002-mssdemux-Handle-the-adapter-in-the-subclass-after-bu.patch \
> +    file://0003-adaptivedemux-minimal-HTTP-context-support.patch \
> +    file://0005-mpdparser-MS-PlayReady-ContentProtection-parsing.patch \
> +    file://0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch \
> +    file://0009-glimagesink-Downrank-to-marginal.patch \
>  "
>  SRC_URI[md5sum] = "2757103e57a096a1a05b3ab85b8381af"
>  SRC_URI[sha256sum] = "23ddae506b3a223b94869a0d3eea3e9a12e847f94d2d0e0b97102ce13ecd6966"

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openembedded.org/pipermail/openembedded-core/attachments/20180428/212e3f29/attachment-0002.html>


More information about the Openembedded-core mailing list