aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch')
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch183
1 files changed, 183 insertions, 0 deletions
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
new file mode 100644
index 0000000000..76d29e151b
--- /dev/null
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch
@@ -0,0 +1,183 @@
+From e9178fa082116d4bf733b184a8b6951112c17900 Mon Sep 17 00:00:00 2001
+From: Matthew Waters <matthew@centricular.com>
+Date: Thu, 10 Nov 2016 17:18:36 +1100
+Subject: [PATCH] smoothstreaming: implement adaptivedemux's
+ get_live_seek_range()
+
+Allows seeking through the available fragments that are still available
+on the server as specified by the DVRWindowLength attribute in the
+manifest.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=774178
+---
+Upstream-Status: Backport
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+ ext/smoothstreaming/gstmssdemux.c | 13 ++++++
+ ext/smoothstreaming/gstmssmanifest.c | 84 ++++++++++++++++++++++++++++++++++++
+ ext/smoothstreaming/gstmssmanifest.h | 1 +
+ 3 files changed, 98 insertions(+)
+
+diff --git a/ext/smoothstreaming/gstmssdemux.c b/ext/smoothstreaming/gstmssdemux.c
+index 9d0aece2b..b66e19514 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);
++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;
++ 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);
+ return GST_FLOW_OK;
+ }
++
++static gboolean
++gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
++ gint64 * stop)
++{
++ GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (demux);
++
++ 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
+--- a/ext/smoothstreaming/gstmssmanifest.c
++++ b/ext/smoothstreaming/gstmssmanifest.c
+@@ -42,6 +42,7 @@ GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug);
+
+ #define MSS_PROP_BITRATE "Bitrate"
+ #define MSS_PROP_DURATION "d"
++#define MSS_PROP_DVR_WINDOW_LENGTH "DVRWindowLength"
+ #define MSS_PROP_LANGUAGE "Language"
+ #define MSS_PROP_NUMBER "n"
+ #define MSS_PROP_REPETITIONS "r"
+@@ -94,6 +95,7 @@ struct _GstMssManifest
+ xmlNodePtr xmlrootnode;
+
+ gboolean is_live;
++ gint64 dvr_window;
+
+ GString *protection_system_id;
+ gchar *protection_data;
+@@ -330,6 +332,22 @@ gst_mss_manifest_new (GstBuffer * data)
+ xmlFree (live_str);
+ }
+
++ /* the entire file is always available for non-live streams */
++ if (!manifest->is_live) {
++ manifest->dvr_window = 0;
++ } else {
++ /* if 0, or non-existent, the length is infinite */
++ gchar *dvr_window_str = (gchar *) xmlGetProp (root,
++ (xmlChar *) MSS_PROP_DVR_WINDOW_LENGTH);
++ if (dvr_window_str) {
++ manifest->dvr_window = g_ascii_strtoull (dvr_window_str, NULL, 10);
++ xmlFree (dvr_window_str);
++ if (manifest->dvr_window <= 0) {
++ manifest->dvr_window = 0;
++ }
++ }
++ }
++
+ 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;
+ }
++
++static GstClockTime
++gst_mss_manifest_get_dvr_window_length_clock_time (GstMssManifest * manifest)
++{
++ gint64 timescale;
++
++ /* the entire file is always available for non-live streams */
++ if (manifest->dvr_window == 0)
++ return GST_CLOCK_TIME_NONE;
++
++ timescale = gst_mss_manifest_get_timescale (manifest);
++ return (GstClockTime) gst_util_uint64_scale_round (manifest->dvr_window,
++ GST_SECOND, timescale);
++}
++
++static gboolean
++gst_mss_stream_get_live_seek_range (GstMssStream * stream, gint64 * start,
++ gint64 * stop)
++{
++ GList *l;
++ GstMssStreamFragment *fragment;
++ guint64 timescale = gst_mss_stream_get_timescale (stream);
++
++ g_return_val_if_fail (stream->active, FALSE);
++
++ /* XXX: assumes all the data in the stream is still available */
++ l = g_list_first (stream->fragments);
++ fragment = (GstMssStreamFragment *) l->data;
++ *start = gst_util_uint64_scale_round (fragment->time, GST_SECOND, timescale);
++
++ l = g_list_last (stream->fragments);
++ fragment = (GstMssStreamFragment *) l->data;
++ *stop = gst_util_uint64_scale_round (fragment->time + fragment->duration *
++ fragment->repetitions, GST_SECOND, timescale);
++
++ return TRUE;
++}
++
++gboolean
++gst_mss_manifest_get_live_seek_range (GstMssManifest * manifest, gint64 * start,
++ gint64 * stop)
++{
++ GSList *iter;
++ gboolean ret = FALSE;
++
++ for (iter = manifest->streams; iter; iter = g_slist_next (iter)) {
++ GstMssStream *stream = iter->data;
++
++ if (stream->active) {
++ /* FIXME: bound this correctly for multiple streams */
++ if (!(ret = gst_mss_stream_get_live_seek_range (stream, start, stop)))
++ break;
++ }
++ }
++
++ if (ret && gst_mss_manifest_is_live (manifest)) {
++ GstClockTime dvr_window =
++ gst_mss_manifest_get_dvr_window_length_clock_time (manifest);
++
++ if (GST_CLOCK_TIME_IS_VALID (dvr_window) && *stop - *start > dvr_window) {
++ *start = *stop - dvr_window;
++ }
++ }
++
++ return ret;
++}
+diff --git a/ext/smoothstreaming/gstmssmanifest.h b/ext/smoothstreaming/gstmssmanifest.h
+index af7419c23..6b7b1f971 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
+ GstClockTime gst_mss_manifest_get_min_fragment_duration (GstMssManifest * manifest);
+ const gchar * gst_mss_manifest_get_protection_system_id (GstMssManifest * manifest);
+ const gchar * gst_mss_manifest_get_protection_data (GstMssManifest * manifest);
++gboolean gst_mss_manifest_get_live_seek_range (GstMssManifest * manifest, gint64 * start, gint64 * stop);
+
+ GstMssStreamType gst_mss_stream_get_type (GstMssStream *stream);
+ GstCaps * gst_mss_stream_get_caps (GstMssStream * stream);
+--
+2.11.0
+