[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