Diff
Modified: trunk/Tools/ChangeLog (219389 => 219390)
--- trunk/Tools/ChangeLog 2017-07-12 10:58:31 UTC (rev 219389)
+++ trunk/Tools/ChangeLog 2017-07-12 11:26:11 UTC (rev 219390)
@@ -1,3 +1,24 @@
+2017-07-12 Zan Dobersek <zdober...@igalia.com>
+
+ [GTK][WPE] Align Jhbuild patches for GStreamer packages
+ https://bugs.webkit.org/show_bug.cgi?id=174363
+
+ Reviewed by Michael Catanzaro.
+
+ Align the patches we apply over Jhbuild-managed GStreamer dependency packages
+ between the GTK+ and WPE port. There's no reason for the two ports to apply
+ different patches over same versions of GStreamer releases.
+
+ This aligns the two ports on this specific issue. Next we'll look into
+ creating a single GStreamer-specific Jhbuild moduleset that will allow us
+ to keep these patches in a single place, avoiding duplicate files.
+
+ * gtk/jhbuild.modules:
+ * gtk/patches/gst-plugins-good-0005-souphttpsrc-cookie-jar-and-context-query-support.patch: Added.
+ * gtk/patches/gst-plugins-good-0006-qtdemux-add-context-for-a-preferred-protection.patch: Renamed from Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch.
+ * gtk/patches/gst-plugins-good-0008-qtdemux-also-push-buffers-without-encryption-info-in.patch: Added.
+ * wpe/patches/gstreamer-typefind-Only-push-a-CAPS-event-downstream-if-the-.patch: Removed.
+
2017-07-11 Dean Jackson <d...@apple.com>
Remove NAVIGATOR_HWCONCURRENCY
Modified: trunk/Tools/gtk/jhbuild.modules (219389 => 219390)
--- trunk/Tools/gtk/jhbuild.modules 2017-07-12 10:58:31 UTC (rev 219389)
+++ trunk/Tools/gtk/jhbuild.modules 2017-07-12 11:26:11 UTC (rev 219390)
@@ -351,7 +351,9 @@
repo="gstreamer"
hash="sha256:be053f6ed716eeb517cec148cec637cdce571c6e04d5c21409e2876fb76c7639">
<patch file="gst-plugins-good-0003-rtpbin-receive-bundle-support.patch" strip="1"/>
- <patch file="gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch" strip="1"/>
+ <patch file="gst-plugins-good-0005-souphttpsrc-cookie-jar-and-context-query-support.patch" strip="1"/>
+ <patch file="gst-plugins-good-0006-qtdemux-add-context-for-a-preferred-protection.patch" strip="1"/>
+ <patch file="gst-plugins-good-0008-qtdemux-also-push-buffers-without-encryption-info-in.patch" strip="1"/>
</branch>
</autotools>
Deleted: trunk/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch (219389 => 219390)
--- trunk/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch 2017-07-12 10:58:31 UTC (rev 219389)
+++ trunk/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch 2017-07-12 11:26:11 UTC (rev 219390)
@@ -1,320 +0,0 @@
-From 248573a84e8f715e5abdc0a2a5ce2faf3e7852fd Mon Sep 17 00:00:00 2001
-From: Xabier Rodriguez Calvar <calva...@igalia.com>
-Date: Fri, 16 Sep 2016 16:08:18 +0200
-Subject: [PATCH] qtdemux: add context for a preferred protection
-
-qtdemux selected the first system corresponding to a working GStreamer
-decryptor. With this change, before selecting that decryptor, qtdemux
-will check if it has context (a preferred decryptor id) and if not, it
-will request it.
-
-The request includes track-id, available key system ids for the
-available decryptors and event the events so that the init data is
-accessible.
----
- gst/isomp4/qtdemux.c | 209 +++++++++++++++++++++++++++++++++++++++++++++++++--
- gst/isomp4/qtdemux.h | 2 +
- 2 files changed, 205 insertions(+), 6 deletions(-)
-
-diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
-index 4cbcaedb2..2d4279646 100644
---- a/gst/isomp4/qtdemux.c
-+++ b/gst/isomp4/qtdemux.c
-@@ -490,6 +490,8 @@ static GstIndex *gst_qtdemux_get_index (GstElement * element);
- #endif
- static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element,
- GstStateChange transition);
-+static void gst_qtdemux_set_context (GstElement * element,
-+ GstContext * context);
- static gboolean qtdemux_sink_activate (GstPad * sinkpad, GstObject * parent);
- static gboolean qtdemux_sink_activate_mode (GstPad * sinkpad,
- GstObject * parent, GstPadMode mode, gboolean active);
-@@ -576,6 +578,7 @@ gst_qtdemux_class_init (GstQTDemuxClass * klass)
- gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_qtdemux_set_index);
- gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_qtdemux_get_index);
- #endif
-+ gstelement_class->set_context = GST_DEBUG_FUNCPTR (gst_qtdemux_set_context);
-
- gst_tag_register_musicbrainz_tags ();
-
-@@ -634,6 +637,7 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
- qtdemux->cenc_aux_info_sizes = NULL;
- qtdemux->cenc_aux_sample_count = 0;
- qtdemux->protection_system_ids = NULL;
-+ qtdemux->preferred_protection_system_id = NULL;
- g_queue_init (&qtdemux->protection_event_queue);
- gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
- qtdemux->flowcombiner = gst_flow_combiner_new ();
-@@ -1997,6 +2001,10 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
- g_queue_foreach (&qtdemux->protection_event_queue, (GFunc) gst_event_unref,
- NULL);
- g_queue_clear (&qtdemux->protection_event_queue);
-+ if (qtdemux->preferred_protection_system_id) {
-+ g_free (qtdemux->preferred_protection_system_id);
-+ qtdemux->preferred_protection_system_id = NULL;
-+ }
- }
- qtdemux->offset = 0;
- gst_adapter_clear (qtdemux->adapter);
-@@ -2485,6 +2493,29 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
- }
-
- static void
-+gst_qtdemux_set_context (GstElement * element, GstContext * context)
-+{
-+ GstQTDemux *qtdemux = GST_QTDEMUX (element);
-+
-+ g_return_if_fail (GST_IS_CONTEXT (context));
-+
-+ if (g_strcmp0 (gst_context_get_context_type (context),
-+ "drm-preferred-decryption-system-id") == 0) {
-+ const GstStructure *s;
-+
-+ s = gst_context_get_structure (context);
-+ qtdemux->preferred_protection_system_id =
-+ g_strdup (gst_structure_get_string (s, "decryption-system-id"));
-+ GST_DEBUG_OBJECT (element, "set preferred decryption system to %s",
-+ qtdemux->preferred_protection_system_id);
-+ }
-+
-+ GST_TRACE_OBJECT (element, "chaining set_context to superclass %p or %p",
-+ GST_ELEMENT_GET_CLASS (element), parent_class);
-+ GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
-+}
-+
-+static void
- qtdemux_parse_ftyp (GstQTDemux * qtdemux, const guint8 * buffer, gint length)
- {
- /* counts as header data */
-@@ -3673,6 +3704,8 @@ qtdemux_parse_pssh (GstQTDemux * qtdemux, GNode * node)
- event = gst_event_new_protection (sysid_string, pssh,
- (parent_box_type == FOURCC_moov) ? "isobmff/moov" : "isobmff/moof");
- for (i = 0; i < qtdemux->n_streams; ++i) {
-+ GST_TRACE_OBJECT (qtdemux,
-+ "adding protection event for stream %d and system %s", i, sysid_string);
- g_queue_push_tail (&qtdemux->streams[i]->protection_scheme_event_queue,
- gst_event_ref (event));
- }
-@@ -5380,6 +5413,12 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
- GstEvent *event;
-
- while ((event = g_queue_pop_head (&stream->protection_scheme_event_queue))) {
-+#if (!GST_DISABLE_GST_DEBUG)
-+ const gchar *system_id = NULL;
-+ gst_event_parse_protection (event, &system_id, NULL, NULL);
-+ GST_TRACE_OBJECT (qtdemux, "pushing again protection event for system %s",
-+ system_id);
-+#endif
- gst_pad_push_event (stream->pad, event);
- }
-
-@@ -7475,11 +7514,148 @@ qtdemux_do_allocation (GstQTDemux * qtdemux, QtDemuxStream * stream)
- }
-
- static gboolean
-+pad_query (const GValue * item, GValue * value, gpointer user_data)
-+{
-+ GstPad *pad = g_value_get_object (item);
-+ GstQuery *query = user_data;
-+ gboolean res;
-+
-+ res = gst_pad_peer_query (pad, query);
-+
-+ if (res) {
-+ g_value_set_boolean (value, TRUE);
-+ return FALSE;
-+ }
-+
-+ GST_INFO_OBJECT (pad, "pad peer query failed");
-+ return TRUE;
-+}
-+
-+static gboolean
-+gst_qtdemux_run_query (GstElement * element, GstQuery * query,
-+ GstPadDirection direction)
-+{
-+ GstIterator *it;
-+ GstIteratorFoldFunction func = pad_query;
-+ GValue res = { 0, };
-+
-+ g_value_init (&res, G_TYPE_BOOLEAN);
-+ g_value_set_boolean (&res, FALSE);
-+
-+ /* Ask neighbor */
-+ if (direction == GST_PAD_SRC)
-+ it = gst_element_iterate_src_pads (element);
-+ else
-+ it = gst_element_iterate_sink_pads (element);
-+
-+ while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC)
-+ gst_iterator_resync (it);
-+
-+ gst_iterator_free (it);
-+
-+ return g_value_get_boolean (&res);
-+}
-+
-+static void
-+gst_qtdemux_request_protection_context_if_needed (GstQTDemux * qtdemux,
-+ QtDemuxStream * stream)
-+{
-+ GstQuery *query;
-+ GstContext *ctxt;
-+ GstElement *element = GST_ELEMENT (qtdemux);
-+ GstStructure *st;
-+ gchar **filtered_sys_ids;
-+ GValue event_list = G_VALUE_INIT;
-+ GList *walk;
-+
-+ /* 1. Check if we already have the context. */
-+ if (qtdemux->preferred_protection_system_id != NULL) {
-+ GST_LOG_OBJECT (element,
-+ "already have the protection context, no need to request it again");
-+ return;
-+ }
-+
-+ GST_TRACE_OBJECT (qtdemux, "currently we have detected %u protection systems",
-+ qtdemux->protection_system_ids->len);
-+ g_ptr_array_add (qtdemux->protection_system_ids, NULL);
-+ filtered_sys_ids = gst_protection_filter_systems_by_available_decryptors (
-+ (const gchar **) qtdemux->protection_system_ids->pdata);
-+ g_ptr_array_remove_index (qtdemux->protection_system_ids,
-+ qtdemux->protection_system_ids->len - 1);
-+ if (filtered_sys_ids == NULL || filtered_sys_ids[0] == NULL) {
-+ GST_LOG_OBJECT (qtdemux, "no suitable decryptors found, not issuing the "
-+ "context request");
-+ g_strfreev (filtered_sys_ids);
-+ return;
-+ }
-+ GST_TRACE_OBJECT (qtdemux, "found suitable decryptors, running the context "
-+ "request");
-+
-+ if (stream->protection_scheme_event_queue.length) {
-+ GST_TRACE_OBJECT (qtdemux, "using stream event queue, length %u",
-+ stream->protection_scheme_event_queue.length);
-+ walk = stream->protection_scheme_event_queue.tail;
-+ } else {
-+ GST_TRACE_OBJECT (qtdemux, "using demuxer event queue, length %u",
-+ qtdemux->protection_event_queue.length);
-+ walk = qtdemux->protection_event_queue.tail;
-+ }
-+
-+ g_value_init (&event_list, GST_TYPE_LIST);
-+ for (; walk; walk = g_list_previous (walk)) {
-+ GValue *event_value = g_new0 (GValue, 1);
-+ g_value_init (event_value, GST_TYPE_EVENT);
-+ g_value_set_boxed (event_value, walk->data);
-+ gst_value_list_append_and_take_value (&event_list, event_value);
-+ }
-+
-+ /* 2a) Query downstream with GST_QUERY_CONTEXT for the context and
-+ * check if downstream already has a context of the specific type
-+ * 2b) Query upstream as above.
-+ */
-+ query = gst_query_new_context ("drm-preferred-decryption-system-id");
-+ st = (GstStructure *) gst_query_get_structure (query);
-+ gst_structure_set (st, "track-id", G_TYPE_UINT, stream->track_id,
-+ "stream-encryption-systems", G_TYPE_STRV, filtered_sys_ids, NULL);
-+ gst_structure_set_value (st, "stream-encryption-events", &event_list);
-+ if (gst_qtdemux_run_query (element, query, GST_PAD_SRC)) {
-+ gst_query_parse_context (query, &ctxt);
-+ GST_INFO_OBJECT (element, "found context (%p) in downstream query", ctxt);
-+ gst_element_set_context (element, ctxt);
-+ } else if (gst_qtdemux_run_query (element, query, GST_PAD_SINK)) {
-+ gst_query_parse_context (query, &ctxt);
-+ GST_INFO_OBJECT (element, "found context (%p) in upstream query", ctxt);
-+ gst_element_set_context (element, ctxt);
-+ } else {
-+ /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
-+ * the required context type and afterwards check if a
-+ * usable context was set now as in 1). The message could
-+ * be handled by the parent bins of the element and the
-+ * application.
-+ */
-+ GstMessage *msg;
-+
-+ GST_INFO_OBJECT (element, "posting need context message");
-+ msg = gst_message_new_need_context (GST_OBJECT_CAST (element),
-+ "drm-preferred-decryption-system-id");
-+ st = (GstStructure *) gst_message_get_structure (msg);
-+ gst_structure_set (st, "track-id", G_TYPE_UINT, stream->track_id,
-+ "stream-encryption-systems", G_TYPE_STRV, filtered_sys_ids, NULL);
-+ gst_structure_set_value (st, "stream-encryption-events", &event_list);
-+ gst_element_post_message (element, msg);
-+ }
-+
-+ g_strfreev (filtered_sys_ids);
-+ g_value_unset (&event_list);
-+ gst_query_unref (query);
-+}
-+
-+static gboolean
- gst_qtdemux_configure_protected_caps (GstQTDemux * qtdemux,
- QtDemuxStream * stream)
- {
- GstStructure *s;
-- const gchar *selected_system;
-+ const gchar *selected_system = NULL;
-
- g_return_val_if_fail (qtdemux != NULL, FALSE);
- g_return_val_if_fail (stream != NULL, FALSE);
-@@ -7494,17 +7670,38 @@ gst_qtdemux_configure_protected_caps (GstQTDemux * qtdemux,
- "cenc protection system information has been found");
- return FALSE;
- }
-- g_ptr_array_add (qtdemux->protection_system_ids, NULL);
-- selected_system = gst_protection_select_system ((const gchar **)
-- qtdemux->protection_system_ids->pdata);
-- g_ptr_array_remove_index (qtdemux->protection_system_ids,
-- qtdemux->protection_system_ids->len - 1);
-+
-+ gst_qtdemux_request_protection_context_if_needed (qtdemux, stream);
-+ if (qtdemux->preferred_protection_system_id != NULL) {
-+ guint i;
-+ for (i = 0; i < qtdemux->protection_system_ids->len; i++) {
-+ if (g_strcmp0 (g_ptr_array_index (qtdemux->protection_system_ids, i),
-+ qtdemux->preferred_protection_system_id) == 0) {
-+ const gchar *preferred_system_array[] =
-+ { qtdemux->preferred_protection_system_id, NULL };
-+ selected_system = gst_protection_select_system (preferred_system_array);
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (!selected_system) {
-+ g_ptr_array_add (qtdemux->protection_system_ids, NULL);
-+ selected_system = gst_protection_select_system ((const gchar **)
-+ qtdemux->protection_system_ids->pdata);
-+ g_ptr_array_remove_index (qtdemux->protection_system_ids,
-+ qtdemux->protection_system_ids->len - 1);
-+ }
-+
- if (!selected_system) {
- GST_ERROR_OBJECT (qtdemux, "stream is protected, but no "
- "suitable decryptor element has been found");
- return FALSE;
- }
-
-+ GST_DEBUG_OBJECT (qtdemux, "selected protection system is %s",
-+ selected_system);
-+
- s = gst_caps_get_structure (stream->caps, 0);
- if (!gst_structure_has_name (s, "application/x-cenc")) {
- gst_structure_set (s,
-diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
-index 771ddcc5b..2c37c2c3e 100644
---- a/gst/isomp4/qtdemux.h
-+++ b/gst/isomp4/qtdemux.h
-@@ -155,6 +155,8 @@ struct _GstQTDemux {
- guint8 *cenc_aux_info_sizes;
- guint32 cenc_aux_sample_count;
-
-+ gchar *preferred_protection_system_id;
-+
-
- /*
- * ALL VARIABLES BELOW ARE ONLY USED IN PUSH-BASED MODE
---
-2.11.0
-
Added: trunk/Tools/gtk/patches/gst-plugins-good-0005-souphttpsrc-cookie-jar-and-context-query-support.patch (0 => 219390)
--- trunk/Tools/gtk/patches/gst-plugins-good-0005-souphttpsrc-cookie-jar-and-context-query-support.patch (rev 0)
+++ trunk/Tools/gtk/patches/gst-plugins-good-0005-souphttpsrc-cookie-jar-and-context-query-support.patch 2017-07-12 11:26:11 UTC (rev 219390)
@@ -0,0 +1,120 @@
+From 8e03a63fd55f5ae447994579890e8630b27f4a1b Mon Sep 17 00:00:00 2001
+From: Philippe Normand <ph...@igalia.com>
+Date: Wed, 28 Oct 2015 12:00:09 +0100
+Subject: [PATCH 2/3] souphttpsrc: cookie jar and context query support
+
+Use a volatile Cookie jar to store cookies and handle the context
+query so that session data can be shared with other elements (like
+adaptivedemux).
+
+https://bugzilla.gnome.org/show_bug.cgi?id=726314
+---
+ ext/soup/gstsouphttpsrc.c | 41 +++++++++++++++++++++++++++++++++++++++--
+ ext/soup/gstsouphttpsrc.h | 1 +
+ 2 files changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/ext/soup/gstsouphttpsrc.c b/ext/soup/gstsouphttpsrc.c
+index fc7cba7..0d3e886 100644
+--- a/ext/soup/gstsouphttpsrc.c
++++ b/ext/soup/gstsouphttpsrc.c
+@@ -482,6 +482,7 @@ gst_soup_http_src_init (GstSoupHTTPSrc * src)
+ src->cookies = NULL;
+ src->iradio_mode = DEFAULT_IRADIO_MODE;
+ src->session = NULL;
++ src->cookie_jar = NULL;
+ src->msg = NULL;
+ src->timeout = DEFAULT_TIMEOUT;
+ src->log_level = DEFAULT_SOUP_LOG_LEVEL;
+@@ -943,6 +944,9 @@ gst_soup_http_src_session_open (GstSoupHTTPSrc * src)
+ soup_session_remove_feature_by_type (src->session,
+ SOUP_TYPE_CONTENT_DECODER);
+
++ src->cookie_jar = soup_cookie_jar_new ();
++ soup_session_add_feature (src->session,
++ SOUP_SESSION_FEATURE (src->cookie_jar));
+ return TRUE;
+ }
+
+@@ -958,6 +962,11 @@ gst_soup_http_src_session_close (GstSoupHTTPSrc * src)
+ src->msg = NULL;
+ }
+
++ if (src->cookie_jar) {
++ g_object_unref (src->cookie_jar);
++ src->cookie_jar = NULL;
++ }
++
+ if (src->session) {
+ soup_session_abort (src->session);
+ g_object_unref (src->session);
+@@ -1426,11 +1435,12 @@ gst_soup_http_src_build_message (GstSoupHTTPSrc * src, const gchar * method)
+ }
+ if (src->cookies) {
+ gchar **cookie;
++ SoupURI *uri = soup_uri_new (src->location);
+
+ for (cookie = src->cookies; *cookie != NULL; cookie++) {
+- soup_message_headers_append (src->msg->request_headers, "Cookie",
+- *cookie);
++ soup_cookie_jar_set_cookie (src->cookie_jar, uri, *cookie);
+ }
++ soup_uri_free (uri);
+ }
+
+ soup_message_set_flags (src->msg, SOUP_MESSAGE_OVERWRITE_CHUNKS |
+@@ -1910,6 +1920,12 @@ gst_soup_http_src_query (GstBaseSrc * bsrc, GstQuery * query)
+ gboolean ret;
+ GstSchedulingFlags flags;
+ gint minsize, maxsize, align;
++ GstContext *context;
++ GstStructure *context_structure;
++ char *cookie;
++ const gchar *cookies[2];
++ const gchar *context_type;
++ SoupURI *uri;
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_URI:
+@@ -1921,6 +1937,27 @@ gst_soup_http_src_query (GstBaseSrc * bsrc, GstQuery * query)
+ }
+ ret = TRUE;
+ break;
++ case GST_QUERY_CONTEXT:
++ if (gst_query_parse_context_type (query, &context_type)
++ && !g_strcmp0 (context_type, "http-headers")) {
++ uri = soup_uri_new (src->location);
++ cookie = soup_cookie_jar_get_cookies (src->cookie_jar, uri, TRUE);
++ context = gst_context_new ("http-headers", FALSE);
++ gst_context_make_writable (context);
++ context_structure = gst_context_writable_structure (context);
++ if (cookie != NULL) {
++ cookies[0] = cookie;
++ cookies[1] = NULL;
++ gst_structure_set (context_structure, "cookies", G_TYPE_STRV, cookies,
++ NULL);
++ g_free (cookie);
++ }
++ gst_query_set_context (query, context);
++ soup_uri_free (uri);
++ ret = TRUE;
++ break;
++ }
++
+ default:
+ ret = FALSE;
+ break;
+diff --git a/ext/soup/gstsouphttpsrc.h b/ext/soup/gstsouphttpsrc.h
+index dd01656..9c6bb5c 100644
+--- a/ext/soup/gstsouphttpsrc.h
++++ b/ext/soup/gstsouphttpsrc.h
+@@ -60,6 +60,7 @@ struct _GstSoupHTTPSrc {
+ gchar *proxy_pw; /* Authentication user password for proxy URI. */
+ gchar **cookies; /* HTTP request cookies. */
+ SoupSession *session; /* Async context. */
++ SoupCookieJar *cookie_jar; /* Volatile HTTP cookie storage */
+ SoupMessage *msg; /* Request message. */
+ GstFlowReturn ret; /* Return code from callback. */
+ gint retry_count; /* Number of retries since we received data */
+--
+1.8.3.2
+
Added: trunk/Tools/gtk/patches/gst-plugins-good-0006-qtdemux-add-context-for-a-preferred-protection.patch (0 => 219390)
--- trunk/Tools/gtk/patches/gst-plugins-good-0006-qtdemux-add-context-for-a-preferred-protection.patch (rev 0)
+++ trunk/Tools/gtk/patches/gst-plugins-good-0006-qtdemux-add-context-for-a-preferred-protection.patch 2017-07-12 11:26:11 UTC (rev 219390)
@@ -0,0 +1,329 @@
+From 9d7201ca76e7875cddd106df06b4d7637c025465 Mon Sep 17 00:00:00 2001
+From: Xabier Rodriguez Calvar <calva...@igalia.com>
+Date: Wed, 21 Jun 2017 17:59:21 +0200
+Subject: [PATCH 2/3] qtdemux: add context for a preferred protection
+
+qtdemux selected the first system corresponding to a working GStreamer
+decryptor. With this change, before selecting that decryptor, qtdemux
+will check if it has context (a preferred decryptor id) and if not, it
+will request it.
+
+The request includes track-id, available key system ids for the
+available decryptors and even the events so that the init data is
+accessible.
+
+[eoca...@igalia.com: select the preferred protection system even if not available]
+
+Test "4. ClearKeyVideo" in YouTube leanback EME conformance tests 2016 for
+H.264[1] uses a media file[2] with cenc encryption which embeds 'pssh' boxes
+with the init data for the Playready and Widevine encryption systems, but not
+for the ClearKey encryption system (as defined by the EMEv0.1b spec[3] and with
+the encryption system id defined in [4]).
+
+Instead, the ClearKey encryption system is manually selected by the web page
+code (even if not originally detected by qtdemux) and the proper decryption key
+is dispatched to the decryptor, which can then decrypt the video successfully.
+
+[1] http://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/2016.html?test_type=encryptedmedia-test&webm=false
+[2] http://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/media/car_cenc-20120827-86.mp4
+[3] https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#simple-decryption-clear-key
+[4] https://www.w3.org/Bugs/Public/show_bug.cgi?id=24027#c2
+
+https://bugzilla.gnome.org/show_bug.cgi?id=770107
+---
+ gst/isomp4/qtdemux.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++++--
+ gst/isomp4/qtdemux.h | 1 +
+ 2 files changed, 195 insertions(+), 6 deletions(-)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 0a41b26f2..ae57bdf9b 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -513,6 +513,8 @@ static GstIndex *gst_qtdemux_get_index (GstElement * element);
+ #endif
+ static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element,
+ GstStateChange transition);
++static void gst_qtdemux_set_context (GstElement * element,
++ GstContext * context);
+ static gboolean qtdemux_sink_activate (GstPad * sinkpad, GstObject * parent);
+ static gboolean qtdemux_sink_activate_mode (GstPad * sinkpad,
+ GstObject * parent, GstPadMode mode, gboolean active);
+@@ -602,6 +604,7 @@ gst_qtdemux_class_init (GstQTDemuxClass * klass)
+ gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_qtdemux_set_index);
+ gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_qtdemux_get_index);
+ #endif
++ gstelement_class->set_context = GST_DEBUG_FUNCPTR (gst_qtdemux_set_context);
+
+ gst_tag_register_musicbrainz_tags ();
+
+@@ -660,6 +663,7 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
+ qtdemux->cenc_aux_info_sizes = NULL;
+ qtdemux->cenc_aux_sample_count = 0;
+ qtdemux->protection_system_ids = NULL;
++ qtdemux->preferred_protection_system_id = NULL;
+ g_queue_init (&qtdemux->protection_event_queue);
+ gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
+ qtdemux->tag_list = gst_tag_list_new_empty ();
+@@ -2113,6 +2117,10 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
+ g_ptr_array_free (qtdemux->protection_system_ids, TRUE);
+ qtdemux->protection_system_ids = NULL;
+ }
++ if (qtdemux->preferred_protection_system_id) {
++ g_free (qtdemux->preferred_protection_system_id);
++ qtdemux->preferred_protection_system_id = NULL;
++ }
+ } else if (qtdemux->mss_mode) {
+ gst_flow_combiner_reset (qtdemux->flowcombiner);
+ for (n = 0; n < qtdemux->n_streams; n++)
+@@ -2590,6 +2598,28 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
+ }
+
+ static void
++gst_qtdemux_set_context (GstElement * element, GstContext * context)
++{
++ GstQTDemux *qtdemux = GST_QTDEMUX (element);
++
++ g_return_if_fail (GST_IS_CONTEXT (context));
++
++ if (gst_context_has_context_type (context,
++ "drm-preferred-decryption-system-id")) {
++ const GstStructure *s;
++
++ s = gst_context_get_structure (context);
++ g_free (qtdemux->preferred_protection_system_id);
++ qtdemux->preferred_protection_system_id =
++ g_strdup (gst_structure_get_string (s, "decryption-system-id"));
++ GST_DEBUG_OBJECT (element, "set preferred decryption system to %s",
++ qtdemux->preferred_protection_system_id);
++ }
++
++ GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
++}
++
++static void
+ qtdemux_parse_ftyp (GstQTDemux * qtdemux, const guint8 * buffer, gint length)
+ {
+ /* counts as header data */
+@@ -3819,6 +3849,8 @@ qtdemux_parse_pssh (GstQTDemux * qtdemux, GNode * node)
+ event = gst_event_new_protection (sysid_string, pssh,
+ (parent_box_type == FOURCC_moov) ? "isobmff/moov" : "isobmff/moof");
+ for (i = 0; i < qtdemux->n_streams; ++i) {
++ GST_TRACE_OBJECT (qtdemux,
++ "adding protection event for stream %d and system %s", i, sysid_string);
+ g_queue_push_tail (&qtdemux->streams[i]->protection_scheme_event_queue,
+ gst_event_ref (event));
+ }
+@@ -5529,6 +5561,8 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
+ GstEvent *event;
+
+ while ((event = g_queue_pop_head (&stream->protection_scheme_event_queue))) {
++ GST_TRACE_OBJECT (stream->pad, "pushing protection event: %"
++ GST_PTR_FORMAT, event);
+ gst_pad_push_event (stream->pad, event);
+ }
+
+@@ -7688,11 +7722,141 @@ qtdemux_do_allocation (GstQTDemux * qtdemux, QtDemuxStream * stream)
+ }
+
+ static gboolean
++pad_query (const GValue * item, GValue * value, gpointer user_data)
++{
++ GstPad *pad = g_value_get_object (item);
++ GstQuery *query = user_data;
++ gboolean res;
++
++ res = gst_pad_peer_query (pad, query);
++
++ if (res) {
++ g_value_set_boolean (value, TRUE);
++ return FALSE;
++ }
++
++ GST_INFO_OBJECT (pad, "pad peer query failed");
++ return TRUE;
++}
++
++static gboolean
++gst_qtdemux_run_query (GstElement * element, GstQuery * query,
++ GstPadDirection direction)
++{
++ GstIterator *it;
++ GstIteratorFoldFunction func = pad_query;
++ GValue res = { 0, };
++
++ g_value_init (&res, G_TYPE_BOOLEAN);
++ g_value_set_boolean (&res, FALSE);
++
++ /* Ask neighbor */
++ if (direction == GST_PAD_SRC)
++ it = gst_element_iterate_src_pads (element);
++ else
++ it = gst_element_iterate_sink_pads (element);
++
++ while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC)
++ gst_iterator_resync (it);
++
++ gst_iterator_free (it);
++
++ return g_value_get_boolean (&res);
++}
++
++static void
++gst_qtdemux_request_protection_context (GstQTDemux * qtdemux,
++ QtDemuxStream * stream)
++{
++ GstQuery *query;
++ GstContext *ctxt;
++ GstElement *element = GST_ELEMENT (qtdemux);
++ GstStructure *st;
++ gchar **filtered_sys_ids;
++ GValue event_list = G_VALUE_INIT;
++ GList *walk;
++
++ /* 1. Check if we already have the context. */
++ if (qtdemux->preferred_protection_system_id != NULL) {
++ GST_LOG_OBJECT (element,
++ "already have the protection context, no need to request it again");
++ return;
++ }
++
++ g_ptr_array_add (qtdemux->protection_system_ids, NULL);
++ filtered_sys_ids = gst_protection_filter_systems_by_available_decryptors (
++ (const gchar **) qtdemux->protection_system_ids->pdata);
++ g_ptr_array_remove_index (qtdemux->protection_system_ids,
++ qtdemux->protection_system_ids->len - 1);
++ GST_TRACE_OBJECT (qtdemux, "detected %u protection systems, we have "
++ "decryptors for %u of them, running context request",
++ qtdemux->protection_system_ids->len, g_strv_length (filtered_sys_ids));
++
++ if (stream->protection_scheme_event_queue.length) {
++ GST_TRACE_OBJECT (qtdemux, "using stream event queue, length %u",
++ stream->protection_scheme_event_queue.length);
++ walk = stream->protection_scheme_event_queue.tail;
++ } else {
++ GST_TRACE_OBJECT (qtdemux, "using demuxer event queue, length %u",
++ qtdemux->protection_event_queue.length);
++ walk = qtdemux->protection_event_queue.tail;
++ }
++
++ g_value_init (&event_list, GST_TYPE_LIST);
++ for (; walk; walk = g_list_previous (walk)) {
++ GValue *event_value = g_new0 (GValue, 1);
++ g_value_init (event_value, GST_TYPE_EVENT);
++ g_value_set_boxed (event_value, walk->data);
++ gst_value_list_append_and_take_value (&event_list, event_value);
++ }
++
++ /* 2a) Query downstream with GST_QUERY_CONTEXT for the context and
++ * check if downstream already has a context of the specific type
++ * 2b) Query upstream as above.
++ */
++ query = gst_query_new_context ("drm-preferred-decryption-system-id");
++ st = gst_query_writable_structure (query);
++ gst_structure_set (st, "track-id", G_TYPE_UINT, stream->track_id,
++ "stream-encryption-systems", G_TYPE_STRV, filtered_sys_ids, NULL);
++ gst_structure_set_value (st, "stream-encryption-events", &event_list);
++ if (gst_qtdemux_run_query (element, query, GST_PAD_SRC)) {
++ gst_query_parse_context (query, &ctxt);
++ GST_INFO_OBJECT (element, "found context (%p) in downstream query", ctxt);
++ gst_element_set_context (element, ctxt);
++ } else if (gst_qtdemux_run_query (element, query, GST_PAD_SINK)) {
++ gst_query_parse_context (query, &ctxt);
++ GST_INFO_OBJECT (element, "found context (%p) in upstream query", ctxt);
++ gst_element_set_context (element, ctxt);
++ } else {
++ /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
++ * the required context type and afterwards check if a
++ * usable context was set now as in 1). The message could
++ * be handled by the parent bins of the element and the
++ * application.
++ */
++ GstMessage *msg;
++
++ GST_INFO_OBJECT (element, "posting need context message");
++ msg = gst_message_new_need_context (GST_OBJECT_CAST (element),
++ "drm-preferred-decryption-system-id");
++ st = (GstStructure *) gst_message_get_structure (msg);
++ gst_structure_set (st, "track-id", G_TYPE_UINT, stream->track_id,
++ "stream-encryption-systems", G_TYPE_STRV, filtered_sys_ids, NULL);
++ gst_structure_set_value (st, "stream-encryption-events", &event_list);
++ gst_element_post_message (element, msg);
++ }
++
++ g_strfreev (filtered_sys_ids);
++ g_value_unset (&event_list);
++ gst_query_unref (query);
++}
++
++static gboolean
+ gst_qtdemux_configure_protected_caps (GstQTDemux * qtdemux,
+ QtDemuxStream * stream)
+ {
+ GstStructure *s;
+- const gchar *selected_system;
++ const gchar *selected_system = NULL;
+
+ g_return_val_if_fail (qtdemux != NULL, FALSE);
+ g_return_val_if_fail (stream != NULL, FALSE);
+@@ -7708,17 +7872,41 @@ gst_qtdemux_configure_protected_caps (GstQTDemux * qtdemux,
+ "cenc protection system information has been found");
+ return FALSE;
+ }
+- g_ptr_array_add (qtdemux->protection_system_ids, NULL);
+- selected_system = gst_protection_select_system ((const gchar **)
+- qtdemux->protection_system_ids->pdata);
+- g_ptr_array_remove_index (qtdemux->protection_system_ids,
+- qtdemux->protection_system_ids->len - 1);
++
++ gst_qtdemux_request_protection_context (qtdemux, stream);
++ if (qtdemux->preferred_protection_system_id != NULL) {
++ const gchar *preferred_system_array[] =
++ { qtdemux->preferred_protection_system_id, NULL };
++
++ selected_system = gst_protection_select_system (preferred_system_array);
++
++ if (selected_system) {
++ GST_TRACE_OBJECT (qtdemux, "selected preferred system %s",
++ qtdemux->preferred_protection_system_id);
++ } else {
++ GST_WARNING_OBJECT (qtdemux, "could not select preferred system %s "
++ "because there is no available decryptor",
++ qtdemux->preferred_protection_system_id);
++ }
++ }
++
++ if (!selected_system) {
++ g_ptr_array_add (qtdemux->protection_system_ids, NULL);
++ selected_system = gst_protection_select_system ((const gchar **)
++ qtdemux->protection_system_ids->pdata);
++ g_ptr_array_remove_index (qtdemux->protection_system_ids,
++ qtdemux->protection_system_ids->len - 1);
++ }
++
+ if (!selected_system) {
+ GST_ERROR_OBJECT (qtdemux, "stream is protected, but no "
+ "suitable decryptor element has been found");
+ return FALSE;
+ }
+
++ GST_DEBUG_OBJECT (qtdemux, "selected protection system is %s",
++ selected_system);
++
+ s = gst_caps_get_structure (stream->caps, 0);
+ if (!gst_structure_has_name (s, "application/x-cenc")) {
+ gst_structure_set (s,
+diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
+index ebd725871..b3d64a4e8 100644
+--- a/gst/isomp4/qtdemux.h
++++ b/gst/isomp4/qtdemux.h
+@@ -154,6 +154,7 @@ struct _GstQTDemux {
+ guint64 cenc_aux_info_offset;
+ guint8 *cenc_aux_info_sizes;
+ guint32 cenc_aux_sample_count;
++ gchar *preferred_protection_system_id;
+
+
+ /*
+--
+2.11.0
+
Added: trunk/Tools/gtk/patches/gst-plugins-good-0008-qtdemux-also-push-buffers-without-encryption-info-in.patch (0 => 219390)
--- trunk/Tools/gtk/patches/gst-plugins-good-0008-qtdemux-also-push-buffers-without-encryption-info-in.patch (rev 0)
+++ trunk/Tools/gtk/patches/gst-plugins-good-0008-qtdemux-also-push-buffers-without-encryption-info-in.patch 2017-07-12 11:26:11 UTC (rev 219390)
@@ -0,0 +1,50 @@
+From 78559bc5db3495f12b0284e4be5fc8bfcd7041e2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Enrique=20Oca=C3=B1a=20Gonz=C3=A1lez?= <eoca...@igalia.com>
+Date: Mon, 24 Apr 2017 17:22:02 +0000
+Subject: [PATCH] qtdemux: also push buffers without encryption info instead of
+ dropping them
+
+---
+ gst/isomp4/qtdemux.c | 26 ++++++++++++--------------
+ 1 file changed, 12 insertions(+), 14 deletions(-)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 6b0c820..7b71237 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -5421,20 +5421,18 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
+ gst_pad_push_event (stream->pad, event);
+ }
+
+- if (info->crypto_info == NULL) {
+- GST_DEBUG_OBJECT (qtdemux, "cenc metadata hasn't been parsed yet");
+- gst_buffer_unref (buf);
+- goto exit;
+- }
+-
+- index = stream->sample_index - (stream->n_samples - info->crypto_info->len);
+- if (G_LIKELY (index >= 0 && index < info->crypto_info->len)) {
+- /* steal structure from array */
+- crypto_info = g_ptr_array_index (info->crypto_info, index);
+- g_ptr_array_index (info->crypto_info, index) = NULL;
+- GST_LOG_OBJECT (qtdemux, "attaching cenc metadata [%u]", index);
+- if (!crypto_info || !gst_buffer_add_protection_meta (buf, crypto_info))
+- GST_ERROR_OBJECT (qtdemux, "failed to attach cenc metadata to buffer");
++ if (info->crypto_info == NULL)
++ GST_DEBUG_OBJECT (qtdemux, "cenc metadata hasn't been parsed yet, pushing buffer as if it wasn't encrypted");
++ else {
++ index = stream->sample_index - (stream->n_samples - info->crypto_info->len);
++ if (G_LIKELY (index >= 0 && index < info->crypto_info->len)) {
++ /* steal structure from array */
++ crypto_info = g_ptr_array_index (info->crypto_info, index);
++ g_ptr_array_index (info->crypto_info, index) = NULL;
++ GST_LOG_OBJECT (qtdemux, "attaching cenc metadata [%u]", index);
++ if (!crypto_info || !gst_buffer_add_protection_meta (buf, crypto_info))
++ GST_ERROR_OBJECT (qtdemux, "failed to attach cenc metadata to buffer");
++ }
+ }
+ }
+
+--
+1.8.3.2
+
Deleted: trunk/Tools/wpe/patches/gstreamer-typefind-Only-push-a-CAPS-event-downstream-if-the-.patch (219389 => 219390)
--- trunk/Tools/wpe/patches/gstreamer-typefind-Only-push-a-CAPS-event-downstream-if-the-.patch 2017-07-12 10:58:31 UTC (rev 219389)
+++ trunk/Tools/wpe/patches/gstreamer-typefind-Only-push-a-CAPS-event-downstream-if-the-.patch 2017-07-12 11:26:11 UTC (rev 219390)
@@ -1,32 +0,0 @@
-From 5e43ee5989d7b51dcb3145bd997525247a3d62dc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebast...@centricular.com>
-Date: Wed, 11 May 2016 15:06:39 +0300
-Subject: [PATCH] typefind: Only push a CAPS event downstream if the sinkpad is
- not in PULL mode
-
-The other signal handlers of the type-found signal might have reactivated
-typefind in PULL mode already, pushing a CAPS event at that point would cause
-deadlocks and is in general unexpected by elements that are in PULL mode.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=765906
----
- plugins/elements/gsttypefindelement.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c
-index c686412..453ff75 100644
---- a/plugins/elements/gsttypefindelement.c
-+++ b/plugins/elements/gsttypefindelement.c
-@@ -179,6 +179,10 @@ gst_type_find_element_have_type (GstTypeFindElement * typefind,
- GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT ", probability=%u",
- caps, probability);
-
-+ /* Do nothing if downstream is pulling from us */
-+ if (GST_PAD_MODE (typefind->src) == GST_PAD_MODE_PULL)
-+ return;
-+
- GST_OBJECT_LOCK (typefind);
-
- /* Now actually send the CAPS event downstream.
---
-2.8.1