summaryrefslogtreecommitdiff
path: root/Tools/gtk/patches
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Tools/gtk/patches
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c.tar.gz
Diffstat (limited to 'Tools/gtk/patches')
-rw-r--r--Tools/gtk/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch30
-rw-r--r--Tools/gtk/patches/fontconfig-fix-osx-cache.diff207
-rw-r--r--Tools/gtk/patches/freetype6-2.4.11-truetype-font-height-fix.patch39
-rw-r--r--Tools/gtk/patches/gdate-suppress-string-format-literal-warning.patch29
-rw-r--r--Tools/gtk/patches/glib-warning-fix.patch34
-rw-r--r--Tools/gtk/patches/gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch236
-rw-r--r--Tools/gtk/patches/gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch37
-rw-r--r--Tools/gtk/patches/gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch156
-rw-r--r--Tools/gtk/patches/gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch61
-rw-r--r--Tools/gtk/patches/gst-plugins-good-0003-rtpbin-receive-bundle-support.patch1018
-rw-r--r--Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch320
-rw-r--r--Tools/gtk/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch133
-rw-r--r--Tools/gtk/patches/gst-plugins-good-use-the-tfdt-decode-time.patch89
-rw-r--r--Tools/gtk/patches/gstreamer-0001-protection-added-function-to-filter-system-ids.patch77
-rw-r--r--Tools/gtk/patches/gtk+-configure-fix-detecting-CUPS-2.x.patch11
-rw-r--r--Tools/gtk/patches/icudata-stdlibs.patch15
-rw-r--r--Tools/gtk/patches/libnice-0001-TURN-allow-REALM-to-be-empty.patch50
-rw-r--r--Tools/gtk/patches/libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch253
-rw-r--r--Tools/gtk/patches/librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch1581
-rw-r--r--Tools/gtk/patches/libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch130
-rw-r--r--Tools/gtk/patches/libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch114
-rw-r--r--Tools/gtk/patches/mesa-gallivm-Fix-build-after-LLVM-commit-211259.patch29
-rw-r--r--Tools/gtk/patches/openh264-configure.patch12
-rw-r--r--Tools/gtk/patches/rtspsrc-timeout-on-udpsrc-is-in-nanoseconds.patch27
-rw-r--r--Tools/gtk/patches/shared-mime-info-xht-glob.patch21
-rw-r--r--Tools/gtk/patches/shared-mime-info-xhtml-magic.patch26
-rw-r--r--Tools/gtk/patches/udpsrc-improve-timeouts.patch53
-rw-r--r--Tools/gtk/patches/xserver-remove-bogus-dependencies.patch43
-rw-r--r--Tools/gtk/patches/xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch84
29 files changed, 4915 insertions, 0 deletions
diff --git a/Tools/gtk/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch b/Tools/gtk/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch
new file mode 100644
index 000000000..b4e0a541d
--- /dev/null
+++ b/Tools/gtk/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch
@@ -0,0 +1,30 @@
+From 7069d717e982adcf8e1d300cbd10eec6322a65c9 Mon Sep 17 00:00:00 2001
+From: Akira TAGOH <akira@tagoh.org>
+Date: Sun, 22 Apr 2012 21:40:44 +0900
+Subject: [PATCH] C++11 requires a space between literal and identifier
+
+Reported by Buganini
+---
+ fontconfig/fontconfig.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
+index 0e2ca50..b27ccb5 100644
+--- a/fontconfig/fontconfig.h
++++ b/fontconfig/fontconfig.h
+@@ -112,9 +112,9 @@ typedef int FcBool;
+ #define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */
+ #define FC_LCD_FILTER "lcdfilter" /* Int */
+
+-#define FC_CACHE_SUFFIX ".cache-"FC_CACHE_VERSION
+-#define FC_DIR_CACHE_FILE "fonts.cache-"FC_CACHE_VERSION
+-#define FC_USER_CACHE_FILE ".fonts.cache-"FC_CACHE_VERSION
++#define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION
++#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION
++#define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION
+
+ /* Adjust outline rasterizer */
+ #define FC_CHAR_WIDTH "charwidth" /* Int */
+--
+1.8.3.2
+
diff --git a/Tools/gtk/patches/fontconfig-fix-osx-cache.diff b/Tools/gtk/patches/fontconfig-fix-osx-cache.diff
new file mode 100644
index 000000000..2c71bc83a
--- /dev/null
+++ b/Tools/gtk/patches/fontconfig-fix-osx-cache.diff
@@ -0,0 +1,207 @@
+diff --git a/fc-cache/fc-cache.c b/fc-cache/fc-cache.c
+index 99e0e9f..bf3b6b4 100644
+--- a/fc-cache/fc-cache.c
++++ b/fc-cache/fc-cache.c
+@@ -187,13 +187,8 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force,
+
+ if (!cache)
+ {
+- if (!recursive)
+- cache = FcDirCacheRescan (dir, config);
+- else
+- {
+- (*changed)++;
+- cache = FcDirCacheRead (dir, FcTrue, config);
+- }
++ (*changed)++;
++ cache = FcDirCacheRead (dir, FcTrue, config);
+ if (!cache)
+ {
+ fprintf (stderr, "%s: error scanning\n", dir);
+@@ -391,7 +386,6 @@ main (int argc, char **argv)
+ ret += scanDirs (list, config, FcTrue, really_force, verbose, FcFalse, &changed, NULL);
+ FcStrListDone (list);
+ }
+- FcStrSetDestroy (updateDirs);
+
+ /*
+ * Try to create CACHEDIR.TAG anyway.
+diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
+index 2258251..d0b4e9e 100644
+--- a/fontconfig/fontconfig.h
++++ b/fontconfig/fontconfig.h
+@@ -541,9 +541,6 @@ FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
+
+ FcPublic FcCache *
+ FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file);
+-
+-FcPublic FcCache *
+-FcDirCacheRescan (const FcChar8 *dir, FcConfig *config);
+
+ FcPublic FcCache *
+ FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config);
+diff --git a/src/fccache.c b/src/fccache.c
+index 5173e0b..10eacff 100644
+--- a/src/fccache.c
++++ b/src/fccache.c
+@@ -828,19 +828,6 @@ bail1:
+ return NULL;
+ }
+
+-FcCache *
+-FcDirCacheRebuild (FcCache *cache, struct stat *dir_stat, FcStrSet *dirs)
+-{
+- FcCache *new;
+- FcFontSet *set = FcFontSetDeserialize (FcCacheSet (cache));
+- const FcChar8 *dir = FcCacheDir (cache);
+-
+- new = FcDirCacheBuild (set, dir, dir_stat, dirs);
+- FcFontSetDestroy (set);
+-
+- return new;
+-}
+-
+ /* write serialized state to the cache file */
+ FcBool
+ FcDirCacheWrite (FcCache *cache, FcConfig *config)
+diff --git a/src/fcdir.c b/src/fcdir.c
+index 3bcd0b8..b040a28 100644
+--- a/src/fcdir.c
++++ b/src/fcdir.c
+@@ -130,12 +130,7 @@ FcFileScanConfig (FcFontSet *set,
+ if (FcFileIsDir (file))
+ return FcStrSetAdd (dirs, file);
+ else
+- {
+- if (set)
+- return FcFileScanFontConfig (set, blanks, file, config);
+- else
+- return FcTrue;
+- }
++ return FcFileScanFontConfig (set, blanks, file, config);
+ }
+
+ FcBool
+@@ -311,45 +306,6 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
+ return cache;
+ }
+
+-FcCache *
+-FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
+-{
+- FcCache *cache = FcDirCacheLoad (dir, config, NULL);
+- FcCache *new = NULL;
+- struct stat dir_stat;
+- FcStrSet *dirs;
+-
+- if (!cache)
+- return NULL;
+- if (FcStatChecksum (dir, &dir_stat) < 0)
+- goto bail;
+- dirs = FcStrSetCreate ();
+- if (!dirs)
+- goto bail;
+-
+- /*
+- * Scan the dir
+- */
+- if (!FcDirScanConfig (NULL, dirs, NULL, dir, FcTrue, config))
+- goto bail1;
+- /*
+- * Rebuild the cache object
+- */
+- new = FcDirCacheRebuild (cache, &dir_stat, dirs);
+- if (!new)
+- goto bail1;
+- FcDirCacheUnload (cache);
+- /*
+- * Write out the cache file, ignoring any troubles
+- */
+- FcDirCacheWrite (new, config);
+-
+-bail1:
+- FcStrSetDestroy (dirs);
+-bail:
+- return new;
+-}
+-
+ /*
+ * Read (or construct) the cache for a directory
+ */
+diff --git a/src/fcfs.c b/src/fcfs.c
+index 21c6c7c..941abba 100644
+--- a/src/fcfs.c
++++ b/src/fcfs.c
+@@ -122,28 +122,6 @@ FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s)
+
+ return s_serialize;
+ }
+-
+-FcFontSet *
+-FcFontSetDeserialize (const FcFontSet *set)
+-{
+- int i;
+- FcFontSet *new = FcFontSetCreate ();
+-
+- if (!new)
+- return NULL;
+- for (i = 0; i < set->nfont; i++)
+- {
+- if (!FcFontSetAdd (new, FcPatternDuplicate (FcFontSetFont (set, i))))
+- goto bail;
+- }
+-
+- return new;
+-bail:
+- FcFontSetDestroy (new);
+-
+- return NULL;
+-}
+-
+ #define __fcfs__
+ #include "fcaliastail.h"
+ #undef __fcfs__
+diff --git a/src/fcint.h b/src/fcint.h
+index cdf2dab..362ea6f 100644
+--- a/src/fcint.h
++++ b/src/fcint.h
+@@ -567,9 +567,6 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config);
+ FcPrivate FcCache *
+ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs);
+
+-FcPrivate FcCache *
+-FcDirCacheRebuild (FcCache *cache, struct stat *dir_stat, FcStrSet *dirs);
+-
+ FcPrivate FcBool
+ FcDirCacheWrite (FcCache *cache, FcConfig *config);
+
+@@ -841,9 +838,6 @@ FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s);
+ FcPrivate FcFontSet *
+ FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s);
+
+-FcPrivate FcFontSet *
+-FcFontSetDeserialize (const FcFontSet *set);
+-
+ /* fchash.c */
+ FcPrivate FcChar8 *
+ FcHashGetSHA256Digest (const FcChar8 *input_strings,
+diff --git a/src/fcpat.c b/src/fcpat.c
+index 986cca3..0614ac2 100644
+--- a/src/fcpat.c
++++ b/src/fcpat.c
+@@ -33,7 +33,6 @@ FcPatternCreate (void)
+ p = (FcPattern *) malloc (sizeof (FcPattern));
+ if (!p)
+ return 0;
+- memset (p, 0, sizeof (FcPattern));
+ p->num = 0;
+ p->size = 0;
+ p->elts_offset = FcPtrToOffset (p, NULL);
+@@ -1311,7 +1310,6 @@ FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl)
+ }
+ return head_serialized;
+ }
+-
+ #define __fcpat__
+ #include "fcaliastail.h"
+ #include "fcftaliastail.h" \ No newline at end of file
diff --git a/Tools/gtk/patches/freetype6-2.4.11-truetype-font-height-fix.patch b/Tools/gtk/patches/freetype6-2.4.11-truetype-font-height-fix.patch
new file mode 100644
index 000000000..0ffe76b4e
--- /dev/null
+++ b/Tools/gtk/patches/freetype6-2.4.11-truetype-font-height-fix.patch
@@ -0,0 +1,39 @@
+From e0469372be3870a5ad60b2c4586e9c281357bd28 Mon Sep 17 00:00:00 2001
+From: Werner Lemberg <wl@gnu.org>
+Date: Tue, 22 Jan 2013 10:07:07 +0000
+Subject: [truetype] Fix font height.
+
+* src/truetype/ttobjs.c (tt_size_reset): The Windows rendering
+engine uses rounded values of the ascender and descender to compute
+the TrueType font height.
+---
+diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
+index c61b218..590b66c 100644
+--- a/src/truetype/ttobjs.c
++++ b/src/truetype/ttobjs.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* Objects manager (body). */
+ /* */
+-/* Copyright 1996-2012 */
++/* Copyright 1996-2013 */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -1177,11 +1177,12 @@
+ FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
+ metrics->descender =
+ FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
+- metrics->height =
+- FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
+ metrics->max_advance =
+ FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
+ metrics->x_scale ) );
++
++ /* the height is derived from rounded values */
++ metrics->height = metrics->ascender - metrics->descender;
+ }
+
+ /* compute new transformation */
+--
+cgit v0.9.0.2
diff --git a/Tools/gtk/patches/gdate-suppress-string-format-literal-warning.patch b/Tools/gtk/patches/gdate-suppress-string-format-literal-warning.patch
new file mode 100644
index 000000000..90cb951a1
--- /dev/null
+++ b/Tools/gtk/patches/gdate-suppress-string-format-literal-warning.patch
@@ -0,0 +1,29 @@
+From 3a7efd598d39366c2c9de0def2fdfb35e5e9f2a1 Mon Sep 17 00:00:00 2001
+From: coypu <coypu@sdf.org>
+Date: Mon, 8 Feb 2016 00:06:06 +0200
+Subject: [PATCH 1/1] gdate: Suppress string format literal warning
+
+Newer versions of GCC emit an error here, but we know it's safe.
+https://bugzilla.gnome.org/761550
+---
+ glib/gdate.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/glib/gdate.c b/glib/gdate.c
+index 4aece02..cdc735c 100644
+--- a/glib/gdate.c
++++ b/glib/gdate.c
+@@ -2494,7 +2494,10 @@ g_date_strftime (gchar *s,
+ * recognize whether strftime actually failed or just returned "".
+ */
+ tmpbuf[0] = '\1';
++ #pragma GCC diagnostic push
++ #pragma GCC diagnostic ignored "-Wformat-nonliteral"
+ tmplen = strftime (tmpbuf, tmpbufsize, locale_format, &tm);
++ #pragma GCC diagnostic pop
+
+ if (tmplen == 0 && tmpbuf[0] != '\0')
+ {
+--
+2.7.0
+
diff --git a/Tools/gtk/patches/glib-warning-fix.patch b/Tools/gtk/patches/glib-warning-fix.patch
new file mode 100644
index 000000000..8faf4d11f
--- /dev/null
+++ b/Tools/gtk/patches/glib-warning-fix.patch
@@ -0,0 +1,34 @@
+From 9f90ee5eeccd47f39c7a03dcd786b125a19c195d Mon Sep 17 00:00:00 2001
+From: Michael Catanzaro <mcatanzaro@gnome.org>
+Date: Sat, 13 Jun 2015 22:52:33 -0500
+Subject: [PATCH] genmarshal: silence register storage class warnings
+
+Using the register keyword triggers warnings on noteworthy compilers
+(clang), since it's deprecated in C++ and at danger of being removed
+from the language. There is no reason to use it since it isn't 1980
+anymore.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=750918
+---
+ gobject/glib-genmarshal.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gobject/glib-genmarshal.c b/gobject/glib-genmarshal.c
+index be4151a..ca78a6f 100644
+--- a/gobject/glib-genmarshal.c
++++ b/gobject/glib-genmarshal.c
+@@ -412,9 +412,9 @@ generate_marshal (const gchar *signame,
+ g_fprintf (fout, "%s%s data2);\n", indent (ind), pad ("gpointer"));
+
+ /* cfile marshal variables */
+- g_fprintf (fout, " register GMarshalFunc_%s callback;\n", signame);
+- g_fprintf (fout, " register GCClosure *cc = (GCClosure*) closure;\n");
+- g_fprintf (fout, " register gpointer data1, data2;\n");
++ g_fprintf (fout, " GMarshalFunc_%s callback;\n", signame);
++ g_fprintf (fout, " GCClosure *cc = (GCClosure*) closure;\n");
++ g_fprintf (fout, " gpointer data1, data2;\n");
+ if (sig->rarg->setter)
+ g_fprintf (fout, " %s v_return;\n", sig->rarg->ctype);
+
+--
+2.4.2 \ No newline at end of file
diff --git a/Tools/gtk/patches/gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch b/Tools/gtk/patches/gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch
new file mode 100644
index 000000000..5d1064ed5
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch
@@ -0,0 +1,236 @@
+From e938933167c494cdca443334f658b02a03c4486b Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <dueno@redhat.com>
+Date: Wed, 26 Oct 2016 14:51:01 +0200
+Subject: [PATCH] dtls: port to OpenSSL 1.1.0
+
+Changes are:
+
+- Use the wrapper functions to access opaque data types. To preserve
+ backward compatibility, define fallback definitions
+
+- Remove the use of idiom "pqueue_size(ssl->d1->sent_messages)", since
+ there is no replacement
+
+- Use RSA_generate_key_ex instead of the deprecated RSA_generate_key
+
+https://bugzilla.gnome.org/show_bug.cgi?id=773540
+---
+ ext/dtls/gstdtlscertificate.c | 15 ++++++++
+ ext/dtls/gstdtlsconnection.c | 87 ++++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 93 insertions(+), 9 deletions(-)
+
+diff --git a/ext/dtls/gstdtlscertificate.c b/ext/dtls/gstdtlscertificate.c
+index 95fbb83..c1c9602 100644
+--- a/ext/dtls/gstdtlscertificate.c
++++ b/ext/dtls/gstdtlscertificate.c
+@@ -199,7 +199,22 @@ init_generated (GstDtlsCertificate * self)
+ priv->private_key = NULL;
+ return;
+ }
++
++ /* XXX: RSA_generate_key is actually deprecated in 0.9.8 */
++#if OPENSSL_VERSION_NUMBER < 0x10100001L
+ rsa = RSA_generate_key (2048, RSA_F4, NULL, NULL);
++#else
++ rsa = RSA_new ();
++ if (rsa != NULL) {
++ BIGNUM *e = BN_new ();
++ if (e != NULL && BN_set_word (e, RSA_F4)
++ && RSA_generate_key_ex (rsa, 2048, e, NULL)) {
++ RSA_free (rsa);
++ rsa = NULL;
++ }
++ BN_free (e);
++ }
++#endif
+
+ if (!rsa) {
+ GST_WARNING_OBJECT (self, "failed to generate RSA");
+diff --git a/ext/dtls/gstdtlsconnection.c b/ext/dtls/gstdtlsconnection.c
+index 36f6d63..728f5a7 100644
+--- a/ext/dtls/gstdtlsconnection.c
++++ b/ext/dtls/gstdtlsconnection.c
+@@ -42,6 +42,8 @@
+ #include <openssl/err.h>
+ #include <openssl/ssl.h>
+
++#include <string.h>
++
+ GST_DEBUG_CATEGORY_STATIC (gst_dtls_connection_debug);
+ #define GST_CAT_DEFAULT gst_dtls_connection_debug
+ G_DEFINE_TYPE_WITH_CODE (GstDtlsConnection, gst_dtls_connection, G_TYPE_OBJECT,
+@@ -216,6 +218,38 @@ gst_dtls_connection_finalize (GObject * gobject)
+ G_OBJECT_CLASS (gst_dtls_connection_parent_class)->finalize (gobject);
+ }
+
++#if OPENSSL_VERSION_NUMBER < 0x10100001L
++static void
++BIO_set_data (BIO * bio, void *ptr)
++{
++ bio->ptr = ptr;
++}
++
++static void *
++BIO_get_data (BIO * bio)
++{
++ return bio->ptr;
++}
++
++static void
++BIO_set_shutdown (BIO * bio, int shutdown)
++{
++ bio->shutdown = shutdown;
++}
++
++static void
++BIO_set_init (BIO * bio, int init)
++{
++ bio->init = init;
++}
++
++static X509 *
++X509_STORE_CTX_get0_cert (X509_STORE_CTX * ctx)
++{
++ return ctx->cert;
++}
++#endif
++
+ static void
+ gst_dtls_connection_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+@@ -239,7 +273,7 @@ gst_dtls_connection_set_property (GObject * object, guint prop_id,
+ priv->bio = BIO_new (BIO_s_gst_dtls_connection ());
+ g_return_if_fail (priv->bio);
+
+- priv->bio->ptr = self;
++ BIO_set_data (priv->bio, self);
+ SSL_set_bio (priv->ssl, priv->bio, priv->bio);
+
+ SSL_set_verify (priv->ssl,
+@@ -573,6 +607,7 @@ log_state (GstDtlsConnection * self, const gchar * str)
+ states |= (! !SSL_want_write (priv->ssl) << 20);
+ states |= (! !SSL_want_read (priv->ssl) << 24);
+
++#if OPENSSL_VERSION_NUMBER < 0x10100001L
+ GST_LOG_OBJECT (self, "%s: role=%s buf=(%d,%p:%d/%d) %x|%x %s",
+ str,
+ priv->is_client ? "client" : "server",
+@@ -581,6 +616,15 @@ log_state (GstDtlsConnection * self, const gchar * str)
+ priv->bio_buffer_offset,
+ priv->bio_buffer_len,
+ states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
++#else
++ GST_LOG_OBJECT (self, "%s: role=%s buf=(%p:%d/%d) %x|%x %s",
++ str,
++ priv->is_client ? "client" : "server",
++ priv->bio_buffer,
++ priv->bio_buffer_offset,
++ priv->bio_buffer_len,
++ states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
++#endif
+ }
+
+ static void
+@@ -737,7 +781,7 @@ openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx)
+ self = SSL_get_ex_data (ssl, connection_ex_index);
+ g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), FALSE);
+
+- pem = _gst_dtls_x509_to_pem (x509_ctx->cert);
++ pem = _gst_dtls_x509_to_pem (X509_STORE_CTX_get0_cert (x509_ctx));
+
+ if (!pem) {
+ GST_WARNING_OBJECT (self,
+@@ -749,7 +793,8 @@ openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx)
+ gint len;
+
+ len =
+- X509_NAME_print_ex (bio, X509_get_subject_name (x509_ctx->cert), 1,
++ X509_NAME_print_ex (bio,
++ X509_get_subject_name (X509_STORE_CTX_get0_cert (x509_ctx)), 1,
+ XN_FLAG_MULTILINE);
+ BIO_read (bio, buffer, len);
+ buffer[len] = '\0';
+@@ -777,6 +822,7 @@ openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx)
+ ######## #### #######
+ */
+
++#if OPENSSL_VERSION_NUMBER < 0x10100001L
+ static BIO_METHOD custom_bio_methods = {
+ BIO_TYPE_BIO,
+ "stream",
+@@ -795,11 +841,34 @@ BIO_s_gst_dtls_connection (void)
+ {
+ return &custom_bio_methods;
+ }
++#else
++static BIO_METHOD *custom_bio_methods;
++
++static BIO_METHOD *
++BIO_s_gst_dtls_connection (void)
++{
++ if (custom_bio_methods != NULL)
++ return custom_bio_methods;
++
++ custom_bio_methods = BIO_meth_new (BIO_TYPE_BIO, "stream");
++ if (custom_bio_methods == NULL
++ || !BIO_meth_set_write (custom_bio_methods, bio_method_write)
++ || !BIO_meth_set_read (custom_bio_methods, bio_method_read)
++ || !BIO_meth_set_ctrl (custom_bio_methods, bio_method_ctrl)
++ || !BIO_meth_set_create (custom_bio_methods, bio_method_new)
++ || !BIO_meth_set_destroy (custom_bio_methods, bio_method_free)) {
++ BIO_meth_free (custom_bio_methods);
++ return NULL;
++ }
++
++ return custom_bio_methods;
++}
++#endif
+
+ static int
+ bio_method_write (BIO * bio, const char *data, int size)
+ {
+- GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);
++ GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
+
+ GST_LOG_OBJECT (self, "BIO: writing %d", size);
+
+@@ -824,7 +893,7 @@ bio_method_write (BIO * bio, const char *data, int size)
+ static int
+ bio_method_read (BIO * bio, char *out_buffer, int size)
+ {
+- GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);
++ GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
+ GstDtlsConnectionPrivate *priv = self->priv;
+ guint internal_size;
+ gint copy_size;
+@@ -868,7 +937,7 @@ bio_method_read (BIO * bio, char *out_buffer, int size)
+ static long
+ bio_method_ctrl (BIO * bio, int cmd, long arg1, void *arg2)
+ {
+- GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);
++ GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
+ GstDtlsConnectionPrivate *priv = self->priv;
+
+ switch (cmd) {
+@@ -916,8 +985,8 @@ bio_method_new (BIO * bio)
+ {
+ GST_LOG_OBJECT (NULL, "BIO: new");
+
+- bio->shutdown = 0;
+- bio->init = 1;
++ BIO_set_shutdown (bio, 0);
++ BIO_set_init (bio, 1);
+
+ return 1;
+ }
+@@ -930,6 +999,6 @@ bio_method_free (BIO * bio)
+ return 0;
+ }
+
+- GST_LOG_OBJECT (GST_DTLS_CONNECTION (bio->ptr), "BIO free");
++ GST_LOG_OBJECT (GST_DTLS_CONNECTION (BIO_get_data (bio)), "BIO free");
+ return 0;
+ }
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch b/Tools/gtk/patches/gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch
new file mode 100644
index 000000000..c66877370
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch
@@ -0,0 +1,37 @@
+From 3a069193e25364ebdacac86f4b03022c151ea29c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
+Date: Mon, 14 Nov 2016 11:32:17 +0200
+Subject: [PATCH] dtlscertificate: Fix error checking in RSA_generate_key_ex()
+ usage
+
+Was broken during the port for OpenSSL 1.1.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=774328
+---
+ ext/dtls/gstdtlscertificate.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/ext/dtls/gstdtlscertificate.c b/ext/dtls/gstdtlscertificate.c
+index c1c9602..c2d9bb2 100644
+--- a/ext/dtls/gstdtlscertificate.c
++++ b/ext/dtls/gstdtlscertificate.c
+@@ -207,12 +207,13 @@ init_generated (GstDtlsCertificate * self)
+ rsa = RSA_new ();
+ if (rsa != NULL) {
+ BIGNUM *e = BN_new ();
+- if (e != NULL && BN_set_word (e, RSA_F4)
+- && RSA_generate_key_ex (rsa, 2048, e, NULL)) {
++ if (e == NULL || !BN_set_word (e, RSA_F4)
++ || !RSA_generate_key_ex (rsa, 2048, e, NULL)) {
+ RSA_free (rsa);
+ rsa = NULL;
+ }
+- BN_free (e);
++ if (e)
++ BN_free (e);
+ }
+ #endif
+
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch b/Tools/gtk/patches/gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch
new file mode 100644
index 000000000..f0f90d104
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch
@@ -0,0 +1,156 @@
+From eeea2a7fe88a17b15318d5b6ae6e190b2f777030 Mon Sep 17 00:00:00 2001
+From: "Alejandro G. Castro" <alex@igalia.com>
+Date: Wed, 26 Oct 2016 13:21:29 +0200
+Subject: [PATCH] rtpbin: pipeline gets an EOS when any rtpsources byes
+
+Instead of sending EOS when a source byes we have to wait for
+all the sources to be gone, which means they already sent BYE and
+were removed from the session. We now handle the EOS in the rtcp
+loop checking the amount of sources in the session.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=773218
+---
+ gst/rtpmanager/gstrtpsession.c | 29 +++++++++++++++++++----------
+ gst/rtpmanager/rtpsession.c | 6 +-----
+ gst/rtpmanager/rtpsession.h | 3 +--
+ 3 files changed, 21 insertions(+), 17 deletions(-)
+
+diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c
+index 3688e85..fd1f2b1 100644
+--- a/gst/rtpmanager/gstrtpsession.c
++++ b/gst/rtpmanager/gstrtpsession.c
+@@ -293,7 +293,7 @@ static GstFlowReturn gst_rtp_session_process_rtp (RTPSession * sess,
+ static GstFlowReturn gst_rtp_session_send_rtp (RTPSession * sess,
+ RTPSource * src, gpointer data, gpointer user_data);
+ static GstFlowReturn gst_rtp_session_send_rtcp (RTPSession * sess,
+- RTPSource * src, GstBuffer * buffer, gboolean eos, gpointer user_data);
++ RTPSource * src, GstBuffer * buffer, gpointer user_data);
+ static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess,
+ GstBuffer * buffer, gpointer user_data);
+ static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
+@@ -1156,6 +1156,22 @@ rtcp_thread (GstRtpSession * rtpsession)
+ GST_RTP_SESSION_UNLOCK (rtpsession);
+ rtp_session_on_timeout (session, current_time, ntpnstime, running_time);
+ GST_RTP_SESSION_LOCK (rtpsession);
++
++ if (!rtp_session_get_num_sources (session)) {
++ /* when no sources left in the session, all of the them have went
++ * BYE at some point and removed, we can send EOS to the
++ * pipeline. */
++ GstPad *rtcp_src = rtpsession->send_rtcp_src;
++
++ if (rtcp_src) {
++ gst_object_ref (rtcp_src);
++ GST_LOG_OBJECT (rtpsession, "sending EOS");
++ GST_RTP_SESSION_UNLOCK (rtpsession);
++ gst_pad_push_event (rtpsession->send_rtcp_src, gst_event_new_eos ());
++ GST_RTP_SESSION_LOCK (rtpsession);
++ gst_object_unref (rtcp_src);
++ }
++ }
+ }
+ /* mark the thread as stopped now */
+ rtpsession->priv->thread_stopped = TRUE;
+@@ -1413,11 +1429,10 @@ do_rtcp_events (GstRtpSession * rtpsession, GstPad * srcpad)
+ }
+
+ /* called when the session manager has an RTCP packet ready for further
+- * sending. The eos flag is set when an EOS event should be sent downstream as
+- * well. */
++ * sending. */
+ static GstFlowReturn
+ gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src,
+- GstBuffer * buffer, gboolean eos, gpointer user_data)
++ GstBuffer * buffer, gpointer user_data)
+ {
+ GstFlowReturn result;
+ GstRtpSession *rtpsession;
+@@ -1440,11 +1455,6 @@ gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src,
+ GST_LOG_OBJECT (rtpsession, "sending RTCP");
+ result = gst_pad_push (rtcp_src, buffer);
+
+- /* we have to send EOS after this packet */
+- if (eos) {
+- GST_LOG_OBJECT (rtpsession, "sending EOS");
+- gst_pad_push_event (rtcp_src, gst_event_new_eos ());
+- }
+ gst_object_unref (rtcp_src);
+ } else {
+ GST_RTP_SESSION_UNLOCK (rtpsession);
+@@ -2056,7 +2066,6 @@ gst_rtp_session_event_send_rtcp_src (GstPad * pad, GstObject * parent,
+ return ret;
+ }
+
+-
+ static gboolean
+ gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstObject * parent,
+ GstEvent * event)
+diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c
+index 8b33b6b..aa8b40b 100644
+--- a/gst/rtpmanager/rtpsession.c
++++ b/gst/rtpmanager/rtpsession.c
+@@ -3263,7 +3263,6 @@ early_exit:
+ typedef struct
+ {
+ RTPSource *source;
+- gboolean is_bye;
+ GstBuffer *buffer;
+ } ReportOutput;
+
+@@ -3874,7 +3873,6 @@ static void
+ generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
+ {
+ RTPSession *sess = data->sess;
+- gboolean is_bye = FALSE;
+ ReportOutput *output;
+
+ /* only generate RTCP for active internal sources */
+@@ -3893,7 +3891,6 @@ generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
+ if (source->marked_bye) {
+ /* send BYE */
+ make_source_bye (sess, source, data);
+- is_bye = TRUE;
+ } else if (!data->is_early) {
+ /* loop over all known sources and add report blocks. If we are early, we
+ * just make a minimal RTCP packet and skip this step */
+@@ -3918,7 +3915,6 @@ generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
+
+ output = g_slice_new (ReportOutput);
+ output->source = g_object_ref (source);
+- output->is_bye = is_bye;
+ output->buffer = data->rtcp;
+ /* queue the RTCP packet to push later */
+ g_queue_push_tail (&data->output, output);
+@@ -4098,7 +4094,7 @@ done:
+ GST_DEBUG ("%p, sending RTCP packet, avg size %u, %u", &sess->stats,
+ sess->stats.avg_rtcp_packet_size, packet_size);
+ result =
+- sess->callbacks.send_rtcp (sess, source, buffer, output->is_bye,
++ sess->callbacks.send_rtcp (sess, source, buffer,
+ sess->send_rtcp_user_data);
+
+ RTP_SESSION_LOCK (sess);
+diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h
+index 9fa9327..c25981a 100644
+--- a/gst/rtpmanager/rtpsession.h
++++ b/gst/rtpmanager/rtpsession.h
+@@ -71,7 +71,6 @@ typedef GstFlowReturn (*RTPSessionSendRTP) (RTPSession *sess, RTPSource *src, gp
+ * @sess: an #RTPSession
+ * @src: the #RTPSource
+ * @buffer: the RTCP buffer ready for sending
+- * @eos: if an EOS event should be pushed
+ * @user_data: user data specified when registering
+ *
+ * This callback will be called when @sess has @buffer ready for sending to
+@@ -80,7 +79,7 @@ typedef GstFlowReturn (*RTPSessionSendRTP) (RTPSession *sess, RTPSource *src, gp
+ * Returns: a #GstFlowReturn.
+ */
+ typedef GstFlowReturn (*RTPSessionSendRTCP) (RTPSession *sess, RTPSource *src, GstBuffer *buffer,
+- gboolean eos, gpointer user_data);
++ gpointer user_data);
+
+ /**
+ * RTPSessionSyncRTCP:
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch b/Tools/gtk/patches/gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch
new file mode 100644
index 000000000..aad048300
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch
@@ -0,0 +1,61 @@
+From dab6c473c3e1b2b400ee18afc70140c2f842debf Mon Sep 17 00:00:00 2001
+From: "Alejandro G. Castro" <alex@igalia.com>
+Date: Thu, 20 Oct 2016 13:14:13 +0200
+Subject: [PATCH] rtpbin: avoid generating errors when rtcp messages are empty
+ and check the queue is not empty
+
+Add a check to verify all the output buffers were empty for the
+session in a timout and log an error.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=773269
+---
+ gst/rtpmanager/rtpsession.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c
+index 75908c0..f1d9210 100644
+--- a/gst/rtpmanager/rtpsession.c
++++ b/gst/rtpmanager/rtpsession.c
+@@ -3923,6 +3923,7 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
+ ReportData data = { GST_RTCP_BUFFER_INIT };
+ GHashTable *table_copy;
+ ReportOutput *output;
++ gboolean all_empty = FALSE;
+
+ g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR);
+
+@@ -3989,6 +3990,9 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
+ if (!is_rtcp_time (sess, current_time, &data))
+ goto done;
+
++ /* check if all the buffers are empty afer generation */
++ all_empty = TRUE;
++
+ GST_DEBUG
+ ("doing RTCP generation %u for %u sources, early %d, may suppress %d",
+ sess->generation, data.num_to_report, data.is_early, data.may_suppress);
+@@ -4036,8 +4040,8 @@ done:
+
+ empty_buffer = gst_buffer_get_size (buffer) == 0;
+
+- if (empty_buffer)
+- g_warning ("rtpsession: Trying to send an empty RTCP packet");
++ if (!empty_buffer)
++ all_empty = FALSE;
+
+ if (sess->callbacks.send_rtcp &&
+ !empty_buffer && (do_not_suppress || !data.may_suppress)) {
+@@ -4068,6 +4072,10 @@ done:
+ g_object_unref (source);
+ g_slice_free (ReportOutput, output);
+ }
++
++ if (all_empty)
++ GST_ERROR ("generated empty RTCP messages for all the sources");
++
+ return result;
+ }
+
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gst-plugins-good-0003-rtpbin-receive-bundle-support.patch b/Tools/gtk/patches/gst-plugins-good-0003-rtpbin-receive-bundle-support.patch
new file mode 100644
index 000000000..ff89c8199
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-0003-rtpbin-receive-bundle-support.patch
@@ -0,0 +1,1018 @@
+From dcd3ce9751cdef0b5ab1fa118355f92bdfe82cb3 Mon Sep 17 00:00:00 2001
+From: Philippe Normand <philn@igalia.com>
+Date: Wed, 16 Nov 2016 08:56:34 +0100
+Subject: [PATCH] rtpbin: receive bundle support
+
+A new signal named on-bundled-ssrc is provided and can be
+used by the application to redirect a stream to a different
+GstRtpSession or to keep the RTX stream grouped within the
+GstRtpSession of the same media type.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=772740
+---
+ docs/plugins/gst-plugins-good-plugins.signals | 8 +
+ gst/rtpmanager/gstrtpbin.c | 562 ++++++++++++++++++--------
+ gst/rtpmanager/gstrtpbin.h | 2 +
+ tests/check/Makefile.am | 4 +
+ tests/check/elements/.gitignore | 1 +
+ tests/check/elements/rtpbundle.c | 390 ++++++++++++++++++
+ tests/check/meson.build | 1 +
+ tests/examples/rtp/.gitignore | 2 +
+ tests/examples/rtp/Makefile.am | 10 +-
+ tests/examples/rtp/client-rtpbundle.c | 266 ++++++++++++
+ tests/examples/rtp/server-rtpbundle.c | 179 ++++++++
+ 11 files changed, 1265 insertions(+), 160 deletions(-)
+ create mode 100644 tests/check/elements/rtpbundle.c
+ create mode 100644 tests/examples/rtp/client-rtpbundle.c
+ create mode 100644 tests/examples/rtp/server-rtpbundle.c
+
+diff --git a/docs/plugins/gst-plugins-good-plugins.signals b/docs/plugins/gst-plugins-good-plugins.signals
+index 3db17e9..44bbdda 100644
+--- a/docs/plugins/gst-plugins-good-plugins.signals
++++ b/docs/plugins/gst-plugins-good-plugins.signals
+@@ -375,6 +375,14 @@ guint arg1
+ </SIGNAL>
+
+ <SIGNAL>
++<NAME>GstRtpBin::on-bundled-ssrc</NAME>
++<RETURNS>guint</RETURNS>
++<FLAGS>l</FLAGS>
++GstRtpBin *gstrtpbin
++guint arg1
++</SIGNAL>
++
++<SIGNAL>
+ <NAME>GstRtpJitterBuffer::clear-pt-map</NAME>
+ <RETURNS>void</RETURNS>
+ <FLAGS>la</FLAGS>
+diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c
+index 648adb9..f58de01 100644
+--- a/gst/rtpmanager/gstrtpbin.c
++++ b/gst/rtpmanager/gstrtpbin.c
+@@ -53,6 +53,13 @@
+ * SSRC in the RTP packets to its own SSRC and wil forward the packets on the
+ * send_rtp_src_\%u pad after updating its internal state.
+ *
++ * #GstRtpBin can also demultiplex incoming bundled streams. The first
++ * #GstRtpSession will have a #GstRtpSsrcDemux element splitting the streams
++ * based on their SSRC and potentially dispatched to a different #GstRtpSession.
++ * Because retransmission SSRCs need to be merged with the corresponding media
++ * stream the #GstRtpBin::on-bundled-ssrc signal is emitted so that the
++ * application can find out to which session the SSRC belongs.
++ *
+ * The session manager needs the clock-rate of the payload types it is handling
+ * and will signal the #GstRtpSession::request-pt-map signal when it needs such a
+ * mapping. One can clear the cached values with the #GstRtpSession::clear-pt-map
+@@ -276,6 +283,8 @@ enum
+ SIGNAL_ON_NEW_SENDER_SSRC,
+ SIGNAL_ON_SENDER_SSRC_ACTIVE,
+
++ SIGNAL_ON_BUNDLED_SSRC,
++
+ LAST_SIGNAL
+ };
+
+@@ -362,6 +371,14 @@ static void remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session);
+ static void remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session);
+ static void free_client (GstRtpBinClient * client, GstRtpBin * bin);
+ static void free_stream (GstRtpBinStream * stream, GstRtpBin * bin);
++static GstRtpBinSession *create_session (GstRtpBin * rtpbin, gint id);
++static GstPad *complete_session_sink (GstRtpBin * rtpbin,
++ GstRtpBinSession * session, gboolean bundle_demuxer_needed);
++static void
++complete_session_receiver (GstRtpBin * rtpbin, GstRtpBinSession * session,
++ guint sessid);
++static GstPad *complete_session_rtcp (GstRtpBin * rtpbin,
++ GstRtpBinSession * session, guint sessid, gboolean bundle_demuxer_needed);
+
+ /* Manages the RTP stream for one SSRC.
+ *
+@@ -428,6 +445,12 @@ struct _GstRtpBinSession
+ gulong demux_newpad_sig;
+ gulong demux_padremoved_sig;
+
++ /* Bundling support */
++ GstElement *rtp_funnel;
++ GstElement *rtcp_funnel;
++ GstElement *bundle_demux;
++ gulong bundle_demux_newpad_sig;
++
+ GMutex lock;
+
+ /* list of GstRtpBinStream */
+@@ -629,6 +652,96 @@ ssrc_demux_pad_removed (GstElement * element, guint ssrc, GstPad * pad,
+ GST_RTP_BIN_UNLOCK (rtpbin);
+ }
+
++static void
++new_bundled_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
++ GstRtpBinSession * session)
++{
++ GValue result = G_VALUE_INIT;
++ GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
++ guint session_id = 0;
++ GstRtpBinSession *target_session = NULL;
++ GstRtpBin *rtpbin = session->bin;
++ gchar *name;
++ GstPad *src_pad;
++ GstPad *recv_rtp_sink = NULL;
++ GstPad *recv_rtcp_sink = NULL;
++ GstPadLinkReturn ret;
++
++ GST_RTP_BIN_DYN_LOCK (rtpbin);
++ GST_DEBUG_OBJECT (rtpbin, "new bundled SSRC pad %08x, %s:%s", ssrc,
++ GST_DEBUG_PAD_NAME (pad));
++
++ g_value_init (&result, G_TYPE_UINT);
++ g_value_init (&params[0], GST_TYPE_ELEMENT);
++ g_value_set_object (&params[0], rtpbin);
++ g_value_init (&params[1], G_TYPE_UINT);
++ g_value_set_uint (&params[1], ssrc);
++
++ g_signal_emitv (params,
++ gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC], 0, &result);
++ g_value_unset (&params[0]);
++
++ session_id = g_value_get_uint (&result);
++ if (session_id == 0) {
++ target_session = session;
++ } else {
++ target_session = find_session_by_id (rtpbin, (gint) session_id);
++ if (!target_session) {
++ target_session = create_session (rtpbin, session_id);
++ }
++ if (!target_session->recv_rtp_sink) {
++ recv_rtp_sink = complete_session_sink (rtpbin, target_session, FALSE);
++ }
++
++ if (!target_session->recv_rtp_src)
++ complete_session_receiver (rtpbin, target_session, session_id);
++
++ if (!target_session->recv_rtcp_sink) {
++ recv_rtcp_sink =
++ complete_session_rtcp (rtpbin, target_session, session_id, FALSE);
++ }
++ }
++
++ GST_DEBUG_OBJECT (rtpbin, "Assigning bundled ssrc %u to session %u", ssrc,
++ session_id);
++
++ if (!recv_rtp_sink) {
++ recv_rtp_sink =
++ gst_element_get_request_pad (target_session->rtp_funnel, "sink_%u");
++ }
++
++ if (!recv_rtcp_sink) {
++ recv_rtcp_sink =
++ gst_element_get_request_pad (target_session->rtcp_funnel, "sink_%u");
++ }
++
++ name = g_strdup_printf ("src_%u", ssrc);
++ src_pad = gst_element_get_static_pad (element, name);
++ ret = gst_pad_link (src_pad, recv_rtp_sink);
++ g_free (name);
++ gst_object_unref (src_pad);
++ gst_object_unref (recv_rtp_sink);
++ if (ret != GST_PAD_LINK_OK) {
++ g_warning
++ ("rtpbin: failed to link bundle demuxer to receive rtp funnel for session %u",
++ session_id);
++ }
++
++ name = g_strdup_printf ("rtcp_src_%u", ssrc);
++ src_pad = gst_element_get_static_pad (element, name);
++ gst_pad_link (src_pad, recv_rtcp_sink);
++ g_free (name);
++ gst_object_unref (src_pad);
++ gst_object_unref (recv_rtcp_sink);
++ if (ret != GST_PAD_LINK_OK) {
++ g_warning
++ ("rtpbin: failed to link bundle demuxer to receive rtcp sink pad for session %u",
++ session_id);
++ }
++
++ GST_RTP_BIN_DYN_UNLOCK (rtpbin);
++}
++
+ /* create a session with the given id. Must be called with RTP_BIN_LOCK */
+ static GstRtpBinSession *
+ create_session (GstRtpBin * rtpbin, gint id)
+@@ -649,6 +762,10 @@ create_session (GstRtpBin * rtpbin, gint id)
+ sess->bin = rtpbin;
+ sess->session = session;
+ sess->demux = demux;
++
++ sess->rtp_funnel = gst_element_factory_make ("funnel", NULL);
++ sess->rtcp_funnel = gst_element_factory_make ("funnel", NULL);
++
+ sess->ptmap = g_hash_table_new_full (NULL, NULL, NULL,
+ (GDestroyNotify) gst_caps_unref);
+ rtpbin->sessions = g_slist_prepend (rtpbin->sessions, sess);
+@@ -696,6 +813,8 @@ create_session (GstRtpBin * rtpbin, gint id)
+
+ gst_bin_add (GST_BIN_CAST (rtpbin), session);
+ gst_bin_add (GST_BIN_CAST (rtpbin), demux);
++ gst_bin_add (GST_BIN_CAST (rtpbin), sess->rtp_funnel);
++ gst_bin_add (GST_BIN_CAST (rtpbin), sess->rtcp_funnel);
+
+ GST_OBJECT_LOCK (rtpbin);
+ target = GST_STATE_TARGET (rtpbin);
+@@ -704,6 +823,8 @@ create_session (GstRtpBin * rtpbin, gint id)
+ /* change state only to what's needed */
+ gst_element_set_state (demux, target);
+ gst_element_set_state (session, target);
++ gst_element_set_state (sess->rtp_funnel, target);
++ gst_element_set_state (sess->rtcp_funnel, target);
+
+ return sess;
+
+@@ -807,7 +928,7 @@ get_pt_map (GstRtpBinSession * session, guint pt)
+ GValue ret = { 0 };
+ GValue args[3] = { {0}, {0}, {0} };
+
+- GST_DEBUG ("searching pt %d in cache", pt);
++ GST_DEBUG ("searching pt %u in cache", pt);
+
+ GST_RTP_SESSION_LOCK (session);
+
+@@ -820,7 +941,7 @@ get_pt_map (GstRtpBinSession * session, guint pt)
+
+ bin = session->bin;
+
+- GST_DEBUG ("emiting signal for pt %d in session %d", pt, session->id);
++ GST_DEBUG ("emiting signal for pt %u in session %u", pt, session->id);
+
+ /* not in cache, send signal to request caps */
+ g_value_init (&args[0], GST_TYPE_ELEMENT);
+@@ -856,7 +977,7 @@ get_pt_map (GstRtpBinSession * session, guint pt)
+ if (!caps)
+ goto no_caps;
+
+- GST_DEBUG ("caching pt %d as %" GST_PTR_FORMAT, pt, caps);
++ GST_DEBUG ("caching pt %u as %" GST_PTR_FORMAT, pt, caps);
+
+ /* store in cache, take additional ref */
+ g_hash_table_insert (session->ptmap, GINT_TO_POINTER (pt),
+@@ -947,7 +1068,7 @@ gst_rtp_bin_get_session (GstRtpBin * bin, guint session_id)
+ GstElement *ret = NULL;
+
+ GST_RTP_BIN_LOCK (bin);
+- GST_DEBUG_OBJECT (bin, "retrieving GstRtpSession, index: %d", session_id);
++ GST_DEBUG_OBJECT (bin, "retrieving GstRtpSession, index: %u", session_id);
+ session = find_session_by_id (bin, (gint) session_id);
+ if (session) {
+ ret = gst_object_ref (session->session);
+@@ -964,7 +1085,7 @@ gst_rtp_bin_get_internal_session (GstRtpBin * bin, guint session_id)
+ GstRtpBinSession *session;
+
+ GST_RTP_BIN_LOCK (bin);
+- GST_DEBUG_OBJECT (bin, "retrieving internal RTPSession object, index: %d",
++ GST_DEBUG_OBJECT (bin, "retrieving internal RTPSession object, index: %u",
+ session_id);
+ session = find_session_by_id (bin, (gint) session_id);
+ if (session) {
+@@ -2194,6 +2315,29 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
+ on_sender_ssrc_active), NULL, NULL, g_cclosure_marshal_generic,
+ G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+
++
++ /**
++ * GstRtpBin::on-bundled-ssrc:
++ * @rtpbin: the object which received the signal
++ * @ssrc: the bundled SSRC
++ *
++ * Notify of a new incoming bundled SSRC. If no handler is connected to the
++ * signal then the #GstRtpSession created for the recv_rtp_sink_\%u
++ * request pad will be managing this new SSRC. However if there is a handler
++ * connected then the application can decided to dispatch this new stream to
++ * another session by providing its ID as return value of the handler. This
++ * can be particularly useful to keep retransmission SSRCs grouped with the
++ * session for which they handle retransmission.
++ *
++ * Since: 1.12
++ */
++ gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC] =
++ g_signal_new ("on-bundled-ssrc", G_TYPE_FROM_CLASS (klass),
++ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
++ on_bundled_ssrc), NULL, NULL,
++ g_cclosure_marshal_generic, G_TYPE_UINT, 1, G_TYPE_UINT);
++
++
+ g_object_class_install_property (gobject_class, PROP_SDES,
+ g_param_spec_boxed ("sdes", "SDES",
+ "The SDES items of this session",
+@@ -3021,7 +3165,7 @@ new_payload_found (GstElement * element, guint pt, GstPad * pad,
+
+ rtpbin = stream->bin;
+
+- GST_DEBUG ("new payload pad %d", pt);
++ GST_DEBUG_OBJECT (rtpbin, "new payload pad %u", pt);
+
+ GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
+
+@@ -3078,7 +3222,7 @@ pt_map_requested (GstElement * element, guint pt, GstRtpBinSession * session)
+
+ rtpbin = session->bin;
+
+- GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %d in session %d", pt,
++ GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %u in session %u", pt,
+ session->id);
+
+ caps = get_pt_map (session, pt);
+@@ -3099,7 +3243,7 @@ static void
+ payload_type_change (GstElement * element, guint pt, GstRtpBinSession * session)
+ {
+ GST_DEBUG_OBJECT (session->bin,
+- "emiting signal for pt type changed to %d in session %d", pt,
++ "emiting signal for pt type changed to %u in session %u", pt,
+ session->id);
+
+ g_signal_emit (session->bin, gst_rtp_bin_signals[SIGNAL_PAYLOAD_TYPE_CHANGE],
+@@ -3246,15 +3390,42 @@ no_stream:
+ }
+ }
+
+-static gboolean
+-complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
++static void
++session_maybe_create_bundle_demuxer (GstRtpBinSession * session)
++{
++ GstRtpBin *rtpbin;
++
++ if (session->bundle_demux)
++ return;
++
++ rtpbin = session->bin;
++ if (g_signal_has_handler_pending (rtpbin,
++ gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC], 0, TRUE)) {
++ GST_DEBUG_OBJECT (rtpbin, "Adding a bundle SSRC demuxer to session %u",
++ session->id);
++ session->bundle_demux = gst_element_factory_make ("rtpssrcdemux", NULL);
++ session->bundle_demux_newpad_sig = g_signal_connect (session->bundle_demux,
++ "new-ssrc-pad", (GCallback) new_bundled_ssrc_pad_found, session);
++
++ gst_bin_add (GST_BIN_CAST (rtpbin), session->bundle_demux);
++ gst_element_sync_state_with_parent (session->bundle_demux);
++ } else {
++ GST_DEBUG_OBJECT (rtpbin,
++ "No handler for the on-bundled-ssrc signal so no need for a bundle SSRC demuxer in session %u",
++ session->id);
++ }
++}
++
++static GstPad *
++complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session,
++ gboolean bundle_demuxer_needed)
+ {
+- gchar *gname;
+ guint sessid = session->id;
+ GstPad *recv_rtp_sink;
++ GstPad *funnel_src;
+ GstElement *decoder;
+- GstElementClass *klass;
+- GstPadTemplate *templ;
++
++ g_assert (!session->recv_rtp_sink);
+
+ /* get recv_rtp pad and store */
+ session->recv_rtp_sink =
+@@ -3265,6 +3436,9 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ g_signal_connect (session->recv_rtp_sink, "notify::caps",
+ (GCallback) caps_changed, session);
+
++ if (bundle_demuxer_needed)
++ session_maybe_create_bundle_demuxer (session);
++
+ GST_DEBUG_OBJECT (rtpbin, "requesting RTP decoder");
+ decoder = session_request_element (session, SIGNAL_REQUEST_RTP_DECODER);
+ if (decoder) {
+@@ -3282,7 +3456,14 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ if (decsrc == NULL)
+ goto dec_src_failed;
+
+- ret = gst_pad_link (decsrc, session->recv_rtp_sink);
++ if (session->bundle_demux) {
++ GstPad *demux_sink;
++ demux_sink = gst_element_get_static_pad (session->bundle_demux, "sink");
++ ret = gst_pad_link (decsrc, demux_sink);
++ gst_object_unref (demux_sink);
++ } else {
++ ret = gst_pad_link (decsrc, session->recv_rtp_sink);
++ }
+ gst_object_unref (decsrc);
+
+ if (ret != GST_PAD_LINK_OK)
+@@ -3290,81 +3471,54 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
+
+ } else {
+ GST_DEBUG_OBJECT (rtpbin, "no RTP decoder given");
+- recv_rtp_sink = gst_object_ref (session->recv_rtp_sink);
++ if (session->bundle_demux) {
++ recv_rtp_sink =
++ gst_element_get_static_pad (session->bundle_demux, "sink");
++ } else {
++ recv_rtp_sink =
++ gst_element_get_request_pad (session->rtp_funnel, "sink_%u");
++ }
+ }
+
+- GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
+- klass = GST_ELEMENT_GET_CLASS (rtpbin);
+- gname = g_strdup_printf ("recv_rtp_sink_%u", sessid);
+- templ = gst_element_class_get_pad_template (klass, "recv_rtp_sink_%u");
+- session->recv_rtp_sink_ghost =
+- gst_ghost_pad_new_from_template (gname, recv_rtp_sink, templ);
+- gst_object_unref (recv_rtp_sink);
+- gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
+- gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
+- g_free (gname);
++ funnel_src = gst_element_get_static_pad (session->rtp_funnel, "src");
++ gst_pad_link (funnel_src, session->recv_rtp_sink);
++ gst_object_unref (funnel_src);
+
+- return TRUE;
++ return recv_rtp_sink;
+
+ /* ERRORS */
+ pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session recv_rtp_sink pad");
+- return FALSE;
++ return NULL;
+ }
+ dec_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get decoder sink pad for session %d", sessid);
+- return FALSE;
++ g_warning ("rtpbin: failed to get decoder sink pad for session %u", sessid);
++ return NULL;
+ }
+ dec_src_failed:
+ {
+- g_warning ("rtpbin: failed to get decoder src pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get decoder src pad for session %u", sessid);
+ gst_object_unref (recv_rtp_sink);
+- return FALSE;
++ return NULL;
+ }
+ dec_link_failed:
+ {
+- g_warning ("rtpbin: failed to link rtp decoder for session %d", sessid);
++ g_warning ("rtpbin: failed to link rtp decoder for session %u", sessid);
+ gst_object_unref (recv_rtp_sink);
+- return FALSE;
++ return NULL;
+ }
+ }
+
+-/* Create a pad for receiving RTP for the session in @name. Must be called with
+- * RTP_BIN_LOCK.
+- */
+-static GstPad *
+-create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
++static void
++complete_session_receiver (GstRtpBin * rtpbin, GstRtpBinSession * session,
++ guint sessid)
+ {
+- guint sessid;
+ GstElement *aux;
+ GstPad *recv_rtp_src;
+- GstRtpBinSession *session;
+-
+- /* first get the session number */
+- if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
+- goto no_name;
+-
+- GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
+
+- /* get or create session */
+- session = find_session_by_id (rtpbin, sessid);
+- if (!session) {
+- GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
+- /* create session now */
+- session = create_session (rtpbin, sessid);
+- if (session == NULL)
+- goto create_error;
+- }
+-
+- /* check if pad was requested */
+- if (session->recv_rtp_sink_ghost != NULL)
+- return session->recv_rtp_sink_ghost;
+-
+- /* setup the session sink pad */
+- if (!complete_session_sink (rtpbin, session))
+- goto session_sink_failed;
++ g_assert (!session->recv_rtp_src);
+
+ session->recv_rtp_src =
+ gst_element_get_static_pad (session->session, "recv_rtp_src");
+@@ -3381,7 +3535,7 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+
+ GST_DEBUG_OBJECT (rtpbin, "linking AUX receiver");
+
+- pname = g_strdup_printf ("sink_%d", sessid);
++ pname = g_strdup_printf ("sink_%u", sessid);
+ auxsink = gst_element_get_static_pad (aux, pname);
+ g_free (pname);
+ if (auxsink == NULL)
+@@ -3394,7 +3548,7 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+
+ /* this can be NULL when this AUX element is not to be linked to
+ * an SSRC demuxer */
+- pname = g_strdup_printf ("src_%d", sessid);
++ pname = g_strdup_printf ("src_%u", sessid);
+ recv_rtp_src = gst_element_get_static_pad (aux, pname);
+ g_free (pname);
+ } else {
+@@ -3408,8 +3562,8 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+ sinkdpad = gst_element_get_static_pad (session->demux, "sink");
+ GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad");
+ gst_pad_link_full (recv_rtp_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
+- gst_object_unref (recv_rtp_src);
+ gst_object_unref (sinkdpad);
++ gst_object_unref (recv_rtp_src);
+
+ /* connect to the new-ssrc-pad signal of the SSRC demuxer */
+ session->demux_newpad_sig = g_signal_connect (session->demux,
+@@ -3417,6 +3571,71 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+ session->demux_padremoved_sig = g_signal_connect (session->demux,
+ "removed-ssrc-pad", (GCallback) ssrc_demux_pad_removed, session);
+ }
++
++ return;
++
++pad_failed:
++ {
++ g_warning ("rtpbin: failed to get session recv_rtp_src pad");
++ return;
++ }
++aux_sink_failed:
++ {
++ g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
++ return;
++ }
++aux_link_failed:
++ {
++ g_warning ("rtpbin: failed to link AUX pad to session %u", sessid);
++ return;
++ }
++}
++
++/* Create a pad for receiving RTP for the session in @name. Must be called with
++ * RTP_BIN_LOCK.
++ */
++static GstPad *
++create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
++{
++ guint sessid;
++ GstRtpBinSession *session;
++ GstPad *recv_rtp_sink;
++
++ /* first get the session number */
++ if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
++ goto no_name;
++
++ GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
++
++ /* get or create session */
++ session = find_session_by_id (rtpbin, sessid);
++ if (!session) {
++ GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
++ /* create session now */
++ session = create_session (rtpbin, sessid);
++ if (session == NULL)
++ goto create_error;
++ }
++
++ /* check if pad was requested */
++ if (session->recv_rtp_sink_ghost != NULL)
++ return session->recv_rtp_sink_ghost;
++
++ /* setup the session sink pad */
++ recv_rtp_sink = complete_session_sink (rtpbin, session, TRUE);
++ if (!recv_rtp_sink)
++ goto session_sink_failed;
++
++
++ GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
++ session->recv_rtp_sink_ghost =
++ gst_ghost_pad_new_from_template (name, recv_rtp_sink, templ);
++ gst_object_unref (recv_rtp_sink);
++ gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
++ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
++
++ complete_session_receiver (rtpbin, session, sessid);
++
+ return session->recv_rtp_sink_ghost;
+
+ /* ERRORS */
+@@ -3435,21 +3654,6 @@ session_sink_failed:
+ /* warning already done */
+ return NULL;
+ }
+-pad_failed:
+- {
+- g_warning ("rtpbin: failed to get session recv_rtp_src pad");
+- return NULL;
+- }
+-aux_sink_failed:
+- {
+- g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
+- return NULL;
+- }
+-aux_link_failed:
+- {
+- g_warning ("rtpbin: failed to link AUX pad to session %d", sessid);
+- return NULL;
+- }
+ }
+
+ static void
+@@ -3463,6 +3667,11 @@ remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ g_signal_handler_disconnect (session->demux, session->demux_padremoved_sig);
+ session->demux_padremoved_sig = 0;
+ }
++ if (session->bundle_demux_newpad_sig) {
++ g_signal_handler_disconnect (session->bundle_demux,
++ session->bundle_demux_newpad_sig);
++ session->bundle_demux_newpad_sig = 0;
++ }
+ if (session->recv_rtp_src) {
+ gst_object_unref (session->recv_rtp_src);
+ session->recv_rtp_src = NULL;
+@@ -3480,37 +3689,14 @@ remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ }
+ }
+
+-/* Create a pad for receiving RTCP for the session in @name. Must be called with
+- * RTP_BIN_LOCK.
+- */
+ static GstPad *
+-create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
+- const gchar * name)
++complete_session_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session,
++ guint sessid, gboolean bundle_demuxer_needed)
+ {
+- guint sessid;
+ GstElement *decoder;
+- GstRtpBinSession *session;
+- GstPad *sinkdpad, *decsink;
+-
+- /* first get the session number */
+- if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1)
+- goto no_name;
+-
+- GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
+-
+- /* get or create the session */
+- session = find_session_by_id (rtpbin, sessid);
+- if (!session) {
+- GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
+- /* create session now */
+- session = create_session (rtpbin, sessid);
+- if (session == NULL)
+- goto create_error;
+- }
+-
+- /* check if pad was requested */
+- if (session->recv_rtcp_sink_ghost != NULL)
+- return session->recv_rtcp_sink_ghost;
++ GstPad *sinkdpad;
++ GstPad *decsink = NULL;
++ GstPad *funnel_src;
+
+ /* get recv_rtp pad and store */
+ GST_DEBUG_OBJECT (rtpbin, "getting RTCP sink pad");
+@@ -3519,6 +3705,9 @@ create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
+ if (session->recv_rtcp_sink == NULL)
+ goto pad_failed;
+
++ if (bundle_demuxer_needed)
++ session_maybe_create_bundle_demuxer (session);
++
+ GST_DEBUG_OBJECT (rtpbin, "getting RTCP decoder");
+ decoder = session_request_element (session, SIGNAL_REQUEST_RTCP_DECODER);
+ if (decoder) {
+@@ -3535,14 +3724,26 @@ create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
+ if (decsrc == NULL)
+ goto dec_src_failed;
+
+- ret = gst_pad_link (decsrc, session->recv_rtcp_sink);
++ if (session->bundle_demux) {
++ GstPad *demux_sink;
++ demux_sink =
++ gst_element_get_static_pad (session->bundle_demux, "rtcp_sink");
++ ret = gst_pad_link (decsrc, demux_sink);
++ gst_object_unref (demux_sink);
++ } else {
++ ret = gst_pad_link (decsrc, session->recv_rtcp_sink);
++ }
+ gst_object_unref (decsrc);
+
+ if (ret != GST_PAD_LINK_OK)
+ goto dec_link_failed;
+ } else {
+ GST_DEBUG_OBJECT (rtpbin, "no RTCP decoder given");
+- decsink = gst_object_ref (session->recv_rtcp_sink);
++ if (session->bundle_demux) {
++ decsink = gst_element_get_static_pad (session->bundle_demux, "rtcp_sink");
++ } else {
++ decsink = gst_element_get_request_pad (session->rtcp_funnel, "sink_%u");
++ }
+ }
+
+ /* get srcpad, link to SSRCDemux */
+@@ -3556,26 +3757,12 @@ create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
+ gst_pad_link_full (session->sync_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
+ gst_object_unref (sinkdpad);
+
+- session->recv_rtcp_sink_ghost =
+- gst_ghost_pad_new_from_template (name, decsink, templ);
+- gst_object_unref (decsink);
+- gst_pad_set_active (session->recv_rtcp_sink_ghost, TRUE);
+- gst_element_add_pad (GST_ELEMENT_CAST (rtpbin),
+- session->recv_rtcp_sink_ghost);
++ funnel_src = gst_element_get_static_pad (session->rtcp_funnel, "src");
++ gst_pad_link (funnel_src, session->recv_rtcp_sink);
++ gst_object_unref (funnel_src);
+
+- return session->recv_rtcp_sink_ghost;
++ return decsink;
+
+- /* ERRORS */
+-no_name:
+- {
+- g_warning ("rtpbin: invalid name given");
+- return NULL;
+- }
+-create_error:
+- {
+- /* create_session already warned */
+- return NULL;
+- }
+ pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session rtcp_sink pad");
+@@ -3583,25 +3770,82 @@ pad_failed:
+ }
+ dec_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get decoder sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get decoder sink pad for session %u", sessid);
+ return NULL;
+ }
+ dec_src_failed:
+ {
+- g_warning ("rtpbin: failed to get decoder src pad for session %d", sessid);
+- gst_object_unref (decsink);
+- return NULL;
++ g_warning ("rtpbin: failed to get decoder src pad for session %u", sessid);
++ goto cleanup;
+ }
+ dec_link_failed:
+ {
+- g_warning ("rtpbin: failed to link rtcp decoder for session %d", sessid);
+- gst_object_unref (decsink);
+- return NULL;
++ g_warning ("rtpbin: failed to link rtcp decoder for session %u", sessid);
++ goto cleanup;
+ }
+ src_pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session sync_src pad");
+- gst_object_unref (decsink);
++ }
++
++cleanup:
++ gst_object_unref (decsink);
++ return NULL;
++}
++
++/* Create a pad for receiving RTCP for the session in @name. Must be called with
++ * RTP_BIN_LOCK.
++ */
++static GstPad *
++create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
++ const gchar * name)
++{
++ guint sessid;
++ GstRtpBinSession *session;
++ GstPad *decsink = NULL;
++
++ /* first get the session number */
++ if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1)
++ goto no_name;
++
++ GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
++
++ /* get or create the session */
++ session = find_session_by_id (rtpbin, sessid);
++ if (!session) {
++ GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
++ /* create session now */
++ session = create_session (rtpbin, sessid);
++ if (session == NULL)
++ goto create_error;
++ }
++
++ /* check if pad was requested */
++ if (session->recv_rtcp_sink_ghost != NULL)
++ return session->recv_rtcp_sink_ghost;
++
++ decsink = complete_session_rtcp (rtpbin, session, sessid, TRUE);
++ if (!decsink)
++ goto create_error;
++
++ session->recv_rtcp_sink_ghost =
++ gst_ghost_pad_new_from_template (name, decsink, templ);
++ gst_object_unref (decsink);
++ gst_pad_set_active (session->recv_rtcp_sink_ghost, TRUE);
++ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin),
++ session->recv_rtcp_sink_ghost);
++
++ return session->recv_rtcp_sink_ghost;
++
++ /* ERRORS */
++no_name:
++ {
++ g_warning ("rtpbin: invalid name given");
++ return NULL;
++ }
++create_error:
++ {
++ /* create_session already warned */
+ return NULL;
+ }
+ }
+@@ -3651,7 +3895,7 @@ complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ GstPadLinkReturn ret;
+
+ GST_DEBUG_OBJECT (rtpbin, "linking RTP encoder");
+- ename = g_strdup_printf ("rtp_src_%d", sessid);
++ ename = g_strdup_printf ("rtp_src_%u", sessid);
+ encsrc = gst_element_get_static_pad (encoder, ename);
+ g_free (ename);
+
+@@ -3660,7 +3904,7 @@ complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
+
+ send_rtp_src = encsrc;
+
+- ename = g_strdup_printf ("rtp_sink_%d", sessid);
++ ename = g_strdup_printf ("rtp_sink_%u", sessid);
+ encsink = gst_element_get_static_pad (encoder, ename);
+ g_free (ename);
+ if (encsink == NULL)
+@@ -3694,23 +3938,23 @@ complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ /* ERRORS */
+ no_srcpad:
+ {
+- g_warning ("rtpbin: failed to get rtp source pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get rtp source pad for session %u", sessid);
+ return FALSE;
+ }
+ enc_src_failed:
+ {
+- g_warning ("rtpbin: failed to get encoder src pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get encoder src pad for session %u", sessid);
+ return FALSE;
+ }
+ enc_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get encoder sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get encoder sink pad for session %u", sessid);
+ gst_object_unref (send_rtp_src);
+ return FALSE;
+ }
+ enc_link_failed:
+ {
+- g_warning ("rtpbin: failed to link rtp encoder for session %d", sessid);
++ g_warning ("rtpbin: failed to link rtp encoder for session %u", sessid);
+ gst_object_unref (send_rtp_src);
+ return FALSE;
+ }
+@@ -3772,22 +4016,22 @@ create_error:
+ }
+ existing_session:
+ {
+- g_warning ("rtpbin: session %d is already a sender", sessid);
++ g_warning ("rtpbin: session %u is already a sender", sessid);
+ return FALSE;
+ }
+ pad_failed:
+ {
+- g_warning ("rtpbin: failed to get session pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get session pad for session %u", sessid);
+ return FALSE;
+ }
+ aux_link_failed:
+ {
+- g_warning ("rtpbin: failed to link AUX for session %d", sessid);
++ g_warning ("rtpbin: failed to link AUX for session %u", sessid);
+ return FALSE;
+ }
+ session_src_failed:
+ {
+- g_warning ("rtpbin: failed to complete AUX for session %d", sessid);
++ g_warning ("rtpbin: failed to complete AUX for session %u", sessid);
+ return FALSE;
+ }
+ }
+@@ -3847,7 +4091,7 @@ create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+ if (!setup_aux_sender (rtpbin, session, aux))
+ goto aux_session_failed;
+
+- pname = g_strdup_printf ("sink_%d", sessid);
++ pname = g_strdup_printf ("sink_%u", sessid);
+ send_rtp_sink = gst_element_get_static_pad (aux, pname);
+ g_free (pname);
+
+@@ -3887,27 +4131,27 @@ create_error:
+ }
+ existing_session:
+ {
+- g_warning ("rtpbin: session %d is already in use", sessid);
++ g_warning ("rtpbin: session %u is already in use", sessid);
+ return NULL;
+ }
+ aux_session_failed:
+ {
+- g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
+ return NULL;
+ }
+ aux_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
+ return NULL;
+ }
+ pad_failed:
+ {
+- g_warning ("rtpbin: failed to get session pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get session pad for session %u", sessid);
+ return NULL;
+ }
+ session_src_failed:
+ {
+- g_warning ("rtpbin: failed to setup source pads for session %d", sessid);
++ g_warning ("rtpbin: failed to setup source pads for session %u", sessid);
+ return NULL;
+ }
+ }
+@@ -3978,13 +4222,13 @@ create_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+
+ GST_DEBUG_OBJECT (rtpbin, "linking RTCP encoder");
+
+- ename = g_strdup_printf ("rtcp_src_%d", sessid);
++ ename = g_strdup_printf ("rtcp_src_%u", sessid);
+ encsrc = gst_element_get_static_pad (encoder, ename);
+ g_free (ename);
+ if (encsrc == NULL)
+ goto enc_src_failed;
+
+- ename = g_strdup_printf ("rtcp_sink_%d", sessid);
++ ename = g_strdup_printf ("rtcp_sink_%u", sessid);
+ encsink = gst_element_get_static_pad (encoder, ename);
+ g_free (ename);
+ if (encsink == NULL)
+@@ -4021,23 +4265,23 @@ no_session:
+ }
+ pad_failed:
+ {
+- g_warning ("rtpbin: failed to get rtcp pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get rtcp pad for session %u", sessid);
+ return NULL;
+ }
+ enc_src_failed:
+ {
+- g_warning ("rtpbin: failed to get encoder src pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get encoder src pad for session %u", sessid);
+ return NULL;
+ }
+ enc_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get encoder sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get encoder sink pad for session %u", sessid);
+ gst_object_unref (encsrc);
+ return NULL;
+ }
+ enc_link_failed:
+ {
+- g_warning ("rtpbin: failed to link rtcp encoder for session %d", sessid);
++ g_warning ("rtpbin: failed to link rtcp encoder for session %u", sessid);
+ gst_object_unref (encsrc);
+ return NULL;
+ }
+diff --git a/gst/rtpmanager/gstrtpbin.h b/gst/rtpmanager/gstrtpbin.h
+index fb13a47..384b76d 100644
+--- a/gst/rtpmanager/gstrtpbin.h
++++ b/gst/rtpmanager/gstrtpbin.h
+@@ -127,6 +127,8 @@ struct _GstRtpBinClass {
+
+ void (*on_new_sender_ssrc) (GstRtpBin *rtpbin, guint session, guint32 ssrc);
+ void (*on_sender_ssrc_active) (GstRtpBin *rtpbin, guint session, guint32 ssrc);
++
++ guint (*on_bundled_ssrc) (GstRtpBin *rtpbin, guint ssrc);
+ };
+
+ GType gst_rtp_bin_get_type (void);
diff --git a/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch b/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch
new file mode 100644
index 000000000..fb15e018f
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch
@@ -0,0 +1,320 @@
+From ae4f7d4f09a051c2fbbd05e4df9f79fa6522104f Mon Sep 17 00:00:00 2001
+From: Xabier Rodriguez Calvar <calvaris@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, 204 insertions(+), 7 deletions(-)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 0425e66..e05e75e 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -480,6 +480,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);
+@@ -554,6 +556,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 ();
+
+@@ -612,6 +615,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 ();
+@@ -1972,6 +1976,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);
+@@ -2404,6 +2412,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 */
+@@ -3392,6 +3423,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));
+ }
+@@ -4993,6 +5026,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);
+ }
+
+@@ -6947,11 +6986,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);
+@@ -6966,17 +7142,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 53bd071..55c4f63 100644
+--- a/gst/isomp4/qtdemux.h
++++ b/gst/isomp4/qtdemux.h
+@@ -153,7 +153,7 @@ struct _GstQTDemux {
+ guint64 cenc_aux_info_offset;
+ guint8 *cenc_aux_info_sizes;
+ guint32 cenc_aux_sample_count;
+-
++ gchar *preferred_protection_system_id;
+ };
+
+ struct _GstQTDemuxClass {
+--
+2.11.0
+
diff --git a/Tools/gtk/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch b/Tools/gtk/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch
new file mode 100644
index 000000000..3a60db477
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch
@@ -0,0 +1,133 @@
+From 1a81bd90d4a3e59d6669a0bbfa456f1ed4e5db48 Mon Sep 17 00:00:00 2001
+From: Xabier Rodriguez Calvar <calvaris@igalia.com>
+Date: Thu, 7 Apr 2016 13:57:16 +0200
+Subject: [PATCH] Revert "qtdemux: expose streams with first moof for
+ fragmented format"
+
+This reverts commit d8bb6687ea251570c331038279a43d448167d6ad.
+---
+ gst/isomp4/qtdemux.c | 54 ++++++++++++++++------------------------------------
+ gst/isomp4/qtdemux.h | 1 -
+ 2 files changed, 16 insertions(+), 39 deletions(-)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 39be163..9636b4b 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -609,7 +609,6 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
+ qtdemux->state = QTDEMUX_STATE_INITIAL;
+ qtdemux->pullbased = FALSE;
+ qtdemux->posted_redirect = FALSE;
+- qtdemux->pending_configure = FALSE;
+ qtdemux->neededbytes = 16;
+ qtdemux->todrop = 0;
+ qtdemux->adapter = gst_adapter_new ();
+@@ -2049,7 +2048,6 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
+ gst_caps_replace (&qtdemux->media_caps, NULL);
+ qtdemux->timescale = 0;
+ qtdemux->got_moov = FALSE;
+- qtdemux->pending_configure = FALSE;
+ } else if (qtdemux->mss_mode) {
+ gst_flow_combiner_reset (qtdemux->flowcombiner);
+ for (n = 0; n < qtdemux->n_streams; n++)
+@@ -6104,7 +6102,6 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+ &fourcc);
+ if (fourcc == FOURCC_moov) {
+ gint n;
+- gboolean got_samples = FALSE;
+
+ /* in usual fragmented setup we could try to scan for more
+ * and end up at the the moov (after mdat) again */
+@@ -6136,27 +6133,19 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+ qtdemux_node_dump (demux, demux->moov_node);
+ qtdemux_parse_tree (demux);
+ qtdemux_prepare_streams (demux);
++ if (!demux->got_moov)
++ qtdemux_expose_streams (demux);
++ else {
+
+- for (n = 0; n < demux->n_streams; n++) {
+- QtDemuxStream *stream = demux->streams[n];
+- got_samples |= stream->stbl_index >= 0;
+- }
+- if (!demux->fragmented || got_samples) {
+- if (!demux->got_moov) {
+- qtdemux_expose_streams (demux);
+- } else {
+- for (n = 0; n < demux->n_streams; n++) {
+- QtDemuxStream *stream = demux->streams[n];
+- gst_qtdemux_configure_stream (demux, stream);
+- }
++ for (n = 0; n < demux->n_streams; n++) {
++ QtDemuxStream *stream = demux->streams[n];
++
++ gst_qtdemux_configure_stream (demux, stream);
+ }
+- gst_qtdemux_check_send_pending_segment (demux);
+- demux->pending_configure = FALSE;
+- } else {
+- demux->pending_configure = TRUE;
+ }
+
+ demux->got_moov = TRUE;
++ gst_qtdemux_check_send_pending_segment (demux);
+
+ /* fragmented streams headers shouldn't contain edts atoms */
+ if (!demux->fragmented) {
+@@ -6175,7 +6164,6 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+ guint64 dist = 0;
+ GstClockTime prev_pts;
+ guint64 prev_offset;
+- gint n;
+
+ GST_DEBUG_OBJECT (demux, "Parsing [moof]");
+
+@@ -6209,25 +6197,15 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+ ret = GST_FLOW_ERROR;
+ goto done;
+ }
+- /* in MSS we need to expose the pads after the first moof as we won't get a moov
+- * Also, fragmented format need to be exposed if a moov have no valid sample data */
+- if (demux->mss_mode || demux->pending_configure) {
+- if (!demux->exposed) {
+- if (!demux->pending_newsegment) {
+- GstSegment segment;
+- gst_segment_init (&segment, GST_FORMAT_TIME);
+- GST_DEBUG_OBJECT (demux, "new pending_newsegment");
+- demux->pending_newsegment = gst_event_new_segment (&segment);
+- }
+- qtdemux_expose_streams (demux);
+- } else {
+- for (n = 0; n < demux->n_streams; n++) {
+- QtDemuxStream *stream = demux->streams[n];
+- gst_qtdemux_configure_stream (demux, stream);
+- }
++ /* in MSS we need to expose the pads after the first moof as we won't get a moov */
++ if (demux->mss_mode && !demux->exposed) {
++ if (!demux->pending_newsegment) {
++ GstSegment segment;
++ gst_segment_init (&segment, GST_FORMAT_TIME);
++ GST_DEBUG_OBJECT (demux, "new pending_newsegment");
++ demux->pending_newsegment = gst_event_new_segment (&segment);
+ }
+- gst_qtdemux_check_send_pending_segment (demux);
+- demux->pending_configure = FALSE;
++ qtdemux_expose_streams (demux);
+ }
+ } else {
+ GST_DEBUG_OBJECT (demux, "Discarding [moof]");
+diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
+index 6061215..ecf0c63 100644
+--- a/gst/isomp4/qtdemux.h
++++ b/gst/isomp4/qtdemux.h
+@@ -89,7 +89,6 @@ struct _GstQTDemux {
+ gboolean posted_redirect;
+
+ /* push based variables */
+- gboolean pending_configure;
+ guint neededbytes;
+ guint todrop;
+ GstAdapter *adapter;
+--
+2.8.0.rc3
+
diff --git a/Tools/gtk/patches/gst-plugins-good-use-the-tfdt-decode-time.patch b/Tools/gtk/patches/gst-plugins-good-use-the-tfdt-decode-time.patch
new file mode 100644
index 000000000..c3c08dfed
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-use-the-tfdt-decode-time.patch
@@ -0,0 +1,89 @@
+From 1556043c00eb60d3871b4baa8b029175c16c7097 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Enrique=20Oca=C3=B1a=20Gonz=C3=A1lez?= <eocanha@igalia.com>
+Date: Mon, 24 Oct 2016 16:56:31 +0000
+Subject: [PATCH] Use the tfdt decode time on byte streams when it's
+ significantly different than the time in the last sample
+
+We consider there's a sifnificant difference when it's larger than on second
+or than half the duration of the last processed fragment in case the latter is
+larger.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=754230
+---
+ gst/isomp4/qtdemux.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index db2d361..5430a39 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -95,6 +95,8 @@
+
+ #define STREAM_IS_EOS(s) (s->time_position == GST_CLOCK_TIME_NONE)
+
++#define ABSDIFF(x, y) ( (x) > (y) ? ((x) - (y)) : ((y) - (x)) )
++
+ GST_DEBUG_CATEGORY (qtdemux_debug);
+
+ /*typedef struct _QtNode QtNode; */
+@@ -256,6 +258,7 @@ struct _QtDemuxStream
+ guint32 n_samples_moof; /* sample count in a moof */
+ guint64 duration_moof; /* duration in timescale of a moof, used for figure out
+ * the framerate of fragmented format stream */
++ guint64 duration_last_moof;
+ guint32 offset_in_sample;
+ guint32 max_buffer_size;
+
+@@ -1828,6 +1831,7 @@ _create_stream (void)
+ stream->protection_scheme_info = NULL;
+ stream->n_samples_moof = 0;
+ stream->duration_moof = 0;
++ stream->duration_last_moof = 0;
+ g_queue_init (&stream->protection_scheme_event_queue);
+ return stream;
+ }
+@@ -2315,6 +2319,7 @@ gst_qtdemux_stream_flush_samples_data (GstQTDemux * qtdemux,
+
+ stream->n_samples_moof = 0;
+ stream->duration_moof = 0;
++ stream->duration_last_moof = 0;
+ }
+
+ static void
+@@ -2883,6 +2888,25 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
+ stream->samples[stream->n_samples - 1].timestamp +
+ stream->samples[stream->n_samples - 1].duration;
+
++ /* If this is a GST_FORMAT_BYTES stream and there's a significant
++ * difference (1 sec.) between decode_ts and timestamp, prefer the
++ * former */
++ if (!qtdemux->upstream_format_is_time
++ && ABSDIFF (decode_ts, timestamp) >
++ MAX (stream->duration_last_moof / 2,
++ GSTTIME_TO_QTSTREAMTIME (stream, GST_SECOND))) {
++ GST_INFO_OBJECT (qtdemux,
++ "decode_ts (%" GST_TIME_FORMAT ") and timestamp (%" GST_TIME_FORMAT
++ ") are significantly different (more than %" GST_TIME_FORMAT
++ "), using decode_ts",
++ GST_TIME_ARGS (QTSTREAMTIME_TO_GSTTIME (stream, decode_ts)),
++ GST_TIME_ARGS (QTSTREAMTIME_TO_GSTTIME (stream, timestamp)),
++ GST_TIME_ARGS (QTSTREAMTIME_TO_GSTTIME (stream,
++ MAX (stream->duration_last_moof / 2,
++ GSTTIME_TO_QTSTREAMTIME (stream, GST_SECOND)))));
++ timestamp = decode_ts;
++ }
++
+ gst_ts = QTSTREAMTIME_TO_GSTTIME (stream, timestamp);
+ GST_INFO_OBJECT (qtdemux, "first sample ts %" GST_TIME_FORMAT
+ " (extends previous samples)", GST_TIME_ARGS (gst_ts));
+@@ -3544,6 +3568,7 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length,
+
+ /* initialise moof sample data */
+ stream->n_samples_moof = 0;
++ stream->duration_last_moof = stream->duration_moof;
+ stream->duration_moof = 0;
+
+ /* Track Run node */
+--
+2.1.4
+
diff --git a/Tools/gtk/patches/gstreamer-0001-protection-added-function-to-filter-system-ids.patch b/Tools/gtk/patches/gstreamer-0001-protection-added-function-to-filter-system-ids.patch
new file mode 100644
index 000000000..e72ef6c13
--- /dev/null
+++ b/Tools/gtk/patches/gstreamer-0001-protection-added-function-to-filter-system-ids.patch
@@ -0,0 +1,77 @@
+From 7772eb350591682b6a315c8a87a58131f731f1d4 Mon Sep 17 00:00:00 2001
+From: Xabier Rodriguez Calvar <calvaris@igalia.com>
+Date: Wed, 19 Oct 2016 16:44:16 +0200
+Subject: [PATCH] protection: added function to filter system ids
+
+gst_protection_filter_systems_by_available_decryptors takes an array of
+strings and returns a new array of strings filtered by the avaible
+decryptors for them so the ones you get are the ones that you should be
+able to decrypt.
+---
+ gst/gstprotection.c | 36 ++++++++++++++++++++++++++++++++++++
+ gst/gstprotection.h | 2 ++
+ 2 files changed, 38 insertions(+)
+
+diff --git a/gst/gstprotection.c b/gst/gstprotection.c
+index 8ee52ea..2d7e5e0 100644
+--- a/gst/gstprotection.c
++++ b/gst/gstprotection.c
+@@ -191,6 +191,42 @@ gst_protection_select_system (const gchar ** system_identifiers)
+ return retval;
+ }
+
++gchar **
++gst_protection_filter_systems_by_available_decryptors (const gchar **
++ system_identifiers)
++{
++ GList *decryptors, *walk;
++ gchar **retval;
++ guint i = 0, decryptors_number;
++
++ decryptors =
++ gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECRYPTOR,
++ GST_RANK_MARGINAL);
++
++ decryptors_number = g_list_length (decryptors);
++ retval = g_new (gchar *, decryptors_number + 1);
++
++ GST_TRACE ("found %u decrytors", decryptors_number);
++
++ for (walk = decryptors; walk; walk = g_list_next (walk)) {
++ GstElementFactory *fact = (GstElementFactory *) walk->data;
++
++ const char *found_sys_id =
++ gst_protection_factory_check (fact, system_identifiers);
++ GST_TRACE ("factory %s is valid for %s", GST_OBJECT_NAME (fact),
++ found_sys_id);
++
++ if (found_sys_id) {
++ retval[i++] = g_strdup (found_sys_id);
++ }
++ }
++ retval[i] = NULL;
++
++ gst_plugin_feature_list_free (decryptors);
++
++ return retval;
++}
++
+ static const gchar *
+ gst_protection_factory_check (GstElementFactory * fact,
+ const gchar ** system_identifiers)
+diff --git a/gst/gstprotection.h b/gst/gstprotection.h
+index f2f54c4..95976c5 100644
+--- a/gst/gstprotection.h
++++ b/gst/gstprotection.h
+@@ -66,6 +66,8 @@ GstProtectionMeta *gst_buffer_add_protection_meta (GstBuffer * buffer,
+ GstStructure * info);
+
+ const gchar *gst_protection_select_system (const gchar ** system_identifiers);
++gchar ** gst_protection_filter_systems_by_available_decryptors (
++ const gchar ** system_identifiers);
+
+ G_END_DECLS
+ #endif /* __GST_PROTECTION_META_H__ */
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gtk+-configure-fix-detecting-CUPS-2.x.patch b/Tools/gtk/patches/gtk+-configure-fix-detecting-CUPS-2.x.patch
new file mode 100644
index 000000000..1099f36f2
--- /dev/null
+++ b/Tools/gtk/patches/gtk+-configure-fix-detecting-CUPS-2.x.patch
@@ -0,0 +1,11 @@
+--- a/configure 2016-12-06 14:33:55.708778846 -0500
++++ b/configure 2016-12-06 14:35:09.695069930 -0500
+@@ -25092,7 +25092,7 @@
+ CUPS_API_MAJOR=`echo $ECHO_N $CUPS_API_VERSION | awk -F. '{print $1}'`
+ CUPS_API_MINOR=`echo $ECHO_N $CUPS_API_VERSION | awk -F. '{print $2}'`
+
+- if test $CUPS_API_MAJOR -gt 1 -o \
++ if test $CUPS_API_MAJOR -lt 1 -o \
+ $CUPS_API_MAJOR -eq 1 -a $CUPS_API_MINOR -lt 2; then
+ as_fn_error $? "CUPS >= 1.2 not found" "$LINENO" 5
+ fi
diff --git a/Tools/gtk/patches/icudata-stdlibs.patch b/Tools/gtk/patches/icudata-stdlibs.patch
new file mode 100644
index 000000000..5e92bdec1
--- /dev/null
+++ b/Tools/gtk/patches/icudata-stdlibs.patch
@@ -0,0 +1,15 @@
+Index: icu-52~m1/source/config/mh-linux
+===================================================================
+--- icu-52~m1.orig/source/config/mh-linux 2013-09-14 18:53:23.284040467 -0400
++++ icu-52~m1/source/config/mh-linux 2013-09-14 18:53:23.284040467 -0400
+@@ -21,7 +21,9 @@
+ LD_RPATH_PRE = -Wl,-rpath,
+
+ ## These are the library specific LDFLAGS
+-LDFLAGSICUDT=-nodefaultlibs -nostdlib
++#LDFLAGSICUDT=-nodefaultlibs -nostdlib
++# Debian change: linking icudata as data only causes too many problems.
++LDFLAGSICUDT=
+
+ ## Compiler switch to embed a library name
+ # The initial tab in the next line is to prevent icu-config from reading it.
diff --git a/Tools/gtk/patches/libnice-0001-TURN-allow-REALM-to-be-empty.patch b/Tools/gtk/patches/libnice-0001-TURN-allow-REALM-to-be-empty.patch
new file mode 100644
index 000000000..7f52e4021
--- /dev/null
+++ b/Tools/gtk/patches/libnice-0001-TURN-allow-REALM-to-be-empty.patch
@@ -0,0 +1,50 @@
+From 0c55166a817ec51096460f789234ef49237000cc Mon Sep 17 00:00:00 2001
+From: Alessandro Decina <alessandro.d@gmail.com>
+Date: Thu, 24 Mar 2016 10:48:27 +1100
+Subject: [PATCH 1/2] TURN: allow REALM to be empty
+
+---
+ agent/conncheck.c | 6 ++----
+ stun/stunhmac.c | 6 ++++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/agent/conncheck.c b/agent/conncheck.c
+index 057fc81..97bf536 100644
+--- a/agent/conncheck.c
++++ b/agent/conncheck.c
+@@ -2768,13 +2768,11 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage *
+ agent->compatibility == NICE_COMPATIBILITY_OC2007R2) &&
+ stun_message_get_class (resp) == STUN_ERROR &&
+ stun_message_find_error (resp, &code) ==
+- STUN_MESSAGE_RETURN_SUCCESS &&
+- recv_realm != NULL && recv_realm_len > 0) {
+-
++ STUN_MESSAGE_RETURN_SUCCESS) {
+ if (code == 438 ||
+ (code == 401 &&
+ !(recv_realm_len == sent_realm_len &&
+- sent_realm != NULL &&
++ recv_realm != NULL && sent_realm != NULL &&
+ memcmp (sent_realm, recv_realm, sent_realm_len) == 0))) {
+ d->stun_resp_msg = *resp;
+ memcpy (d->stun_resp_buffer, resp->buffer,
+diff --git a/stun/stunhmac.c b/stun/stunhmac.c
+index df5deb6..f73943f 100644
+--- a/stun/stunhmac.c
++++ b/stun/stunhmac.c
+@@ -90,8 +90,10 @@ static const uint8_t *priv_trim_var (const uint8_t *var, size_t *var_len)
+ ptr++;
+ (*var_len)--;
+ }
+- while(ptr[*var_len-1] == '"' ||
+- ptr[*var_len-1] == 0) {
++
++ while(*var_len > 0 &&
++ (ptr[*var_len-1] == '"' ||
++ ptr[*var_len-1] == 0)) {
+ (*var_len)--;
+ }
+
+--
+2.3.4
+
diff --git a/Tools/gtk/patches/libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch b/Tools/gtk/patches/libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch
new file mode 100644
index 000000000..6af57e8b2
--- /dev/null
+++ b/Tools/gtk/patches/libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch
@@ -0,0 +1,253 @@
+From 3196a96a408a90f707dff3f31fa3d05d64aeb68a Mon Sep 17 00:00:00 2001
+From: Alessandro Decina <alessandro.d@gmail.com>
+Date: Tue, 13 Oct 2015 12:49:19 +1100
+Subject: [PATCH] nicesrc: spin the agent mainloop in a separate thread
+
+Don't run the mainloop from the srcpad task, since that can get blocked in the
+pipeline and cause unnecessary STUN retrasmissions (at best) and completely
+block the agent (at worst).
+---
+ gst/gstnicesrc.c | 158 ++++++++++++++++++++++++++++++++-----------------------
+ gst/gstnicesrc.h | 4 +-
+ 2 files changed, 93 insertions(+), 69 deletions(-)
+
+diff --git a/gst/gstnicesrc.c b/gst/gstnicesrc.c
+index d369e09..eb59fe9 100644
+--- a/gst/gstnicesrc.c
++++ b/gst/gstnicesrc.c
+@@ -48,6 +48,14 @@ GST_DEBUG_CATEGORY_STATIC (nicesrc_debug);
+
+ #define BUFFER_SIZE (65536)
+
++static gboolean
++gst_nice_src_start (
++ GstBaseSrc *basesrc);
++
++static gboolean
++gst_nice_src_stop (
++ GstBaseSrc *basesrc);
++
+ static GstFlowReturn
+ gst_nice_src_create (
+ GstPushSrc *basesrc,
+@@ -57,10 +65,6 @@ static gboolean
+ gst_nice_src_unlock (
+ GstBaseSrc *basesrc);
+
+-static gboolean
+-gst_nice_src_unlock_stop (
+- GstBaseSrc *basesrc);
+-
+ static void
+ gst_nice_src_set_property (
+ GObject *object,
+@@ -116,8 +120,9 @@ gst_nice_src_class_init (GstNiceSrcClass *klass)
+ gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_nice_src_create);
+
+ gstbasesrc_class = (GstBaseSrcClass *) klass;
++ gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_nice_src_start);
++ gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_nice_src_stop);
+ gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_nice_src_unlock);
+- gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_nice_src_unlock_stop);
+
+ gobject_class = (GObjectClass *) klass;
+ gobject_class->set_property = gst_nice_src_set_property;
+@@ -179,9 +184,83 @@ gst_nice_src_init (GstNiceSrc *src)
+ src->component_id = 0;
+ src->mainctx = g_main_context_new ();
+ src->mainloop = g_main_loop_new (src->mainctx, FALSE);
+- src->unlocked = FALSE;
+- src->idle_source = NULL;
+ src->outbufs = g_queue_new ();
++ src->agent_io_thread = NULL;
++ g_cond_init (&src->outcond);
++}
++
++static gpointer
++gst_nice_src_agent_io_thread (gpointer data)
++{
++ GstNiceSrc *nicesrc = GST_NICE_SRC (data);
++
++ GST_INFO_OBJECT (nicesrc, "starting agent io thread");
++ g_main_loop_run (nicesrc->mainloop);
++ GST_INFO_OBJECT (nicesrc, "exiting agent io thread");
++
++ return NULL;
++}
++
++static gboolean
++main_loop_running_cb (gpointer data)
++{
++ GstNiceSrc *nicesrc = GST_NICE_SRC (data);
++
++ GST_OBJECT_LOCK (nicesrc);
++ /* _start() and _stop() could both be waiting for the mainloop to start so we
++ * need to broadcast */
++ g_cond_broadcast (&nicesrc->outcond);
++ GST_OBJECT_UNLOCK (nicesrc);
++
++ return FALSE;
++}
++
++static gboolean
++gst_nice_src_start (GstBaseSrc * basesrc)
++{
++ GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc);
++ GSource *source;
++ gchar *thread_name;
++
++ GST_OBJECT_LOCK (nicesrc);
++ source = g_idle_source_new ();
++ g_source_set_callback (source,
++ (GSourceFunc) main_loop_running_cb, nicesrc, NULL);
++ g_source_attach (source, nicesrc->mainctx);
++ g_source_unref (source);
++
++ thread_name = g_strdup_printf ("%s:agent_io", GST_OBJECT_NAME (nicesrc));
++ nicesrc->agent_io_thread = g_thread_new (thread_name, gst_nice_src_agent_io_thread, nicesrc);
++ g_free (thread_name);
++ /* wait until the agent thread starts spinning the mainloop or _stop() is
++ * called */
++ while (GST_BASE_SRC_IS_STARTING (basesrc) &&
++ !g_main_loop_is_running (nicesrc->mainloop))
++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc));
++ GST_OBJECT_UNLOCK (nicesrc);
++
++ return TRUE;
++}
++
++static gboolean
++gst_nice_src_stop (GstBaseSrc * basesrc)
++{
++ GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc);
++ GThread *agent_io_thread = NULL;
++
++ GST_OBJECT_LOCK (nicesrc);
++ /* here we wait for the agent thread created in _start() to be scheduled so
++ * that we don't risk calling _quit() first and then _run() on the mainloop */
++ while (!g_main_loop_is_running (nicesrc->mainloop))
++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc));
++ g_main_loop_quit (nicesrc->mainloop);
++ agent_io_thread = nicesrc->agent_io_thread;
++ nicesrc->agent_io_thread = NULL;
++ GST_OBJECT_UNLOCK (nicesrc);
++
++ g_thread_join (agent_io_thread);
++
++ return TRUE;
+ }
+
+ static void
+@@ -207,62 +286,17 @@ gst_nice_src_read_callback (NiceAgent *agent,
+ #endif
+ GST_OBJECT_LOCK (nicesrc);
+ g_queue_push_tail (nicesrc->outbufs, buffer);
+- g_main_loop_quit (nicesrc->mainloop);
++ g_cond_signal (&nicesrc->outcond);
+ GST_OBJECT_UNLOCK (nicesrc);
+ }
+
+ static gboolean
+-gst_nice_src_unlock_idler (gpointer data)
+-{
+- GstNiceSrc *nicesrc = GST_NICE_SRC (data);
+-
+- GST_OBJECT_LOCK (nicesrc);
+- if (nicesrc->unlocked)
+- g_main_loop_quit (nicesrc->mainloop);
+-
+- if (nicesrc->idle_source) {
+- g_source_destroy (nicesrc->idle_source);
+- g_source_unref (nicesrc->idle_source);
+- nicesrc->idle_source = NULL;
+- }
+- GST_OBJECT_UNLOCK (nicesrc);
+-
+- return FALSE;
+-}
+-
+-static gboolean
+ gst_nice_src_unlock (GstBaseSrc *src)
+ {
+ GstNiceSrc *nicesrc = GST_NICE_SRC (src);
+
+ GST_OBJECT_LOCK (src);
+- nicesrc->unlocked = TRUE;
+-
+- g_main_loop_quit (nicesrc->mainloop);
+-
+- if (!nicesrc->idle_source) {
+- nicesrc->idle_source = g_idle_source_new ();
+- g_source_set_priority (nicesrc->idle_source, G_PRIORITY_HIGH);
+- g_source_set_callback (nicesrc->idle_source, gst_nice_src_unlock_idler, src, NULL);
+- g_source_attach (nicesrc->idle_source, g_main_loop_get_context (nicesrc->mainloop));
+- }
+- GST_OBJECT_UNLOCK (src);
+-
+- return TRUE;
+-}
+-
+-static gboolean
+-gst_nice_src_unlock_stop (GstBaseSrc *src)
+-{
+- GstNiceSrc *nicesrc = GST_NICE_SRC (src);
+-
+- GST_OBJECT_LOCK (src);
+- nicesrc->unlocked = FALSE;
+- if (nicesrc->idle_source) {
+- g_source_destroy (nicesrc->idle_source);
+- g_source_unref(nicesrc->idle_source);
+- }
+- nicesrc->idle_source = NULL;
++ g_cond_signal (&nicesrc->outcond);
+ GST_OBJECT_UNLOCK (src);
+
+ return TRUE;
+@@ -278,19 +312,8 @@ gst_nice_src_create (
+ GST_LOG_OBJECT (nicesrc, "create called");
+
+ GST_OBJECT_LOCK (basesrc);
+- if (nicesrc->unlocked) {
+- GST_OBJECT_UNLOCK (basesrc);
+-#if GST_CHECK_VERSION (1,0,0)
+- return GST_FLOW_FLUSHING;
+-#else
+- return GST_FLOW_WRONG_STATE;
+-#endif
+- }
+- if (g_queue_is_empty (nicesrc->outbufs)) {
+- GST_OBJECT_UNLOCK (basesrc);
+- g_main_loop_run (nicesrc->mainloop);
+- GST_OBJECT_LOCK (basesrc);
+- }
++ if (g_queue_is_empty (nicesrc->outbufs))
++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc));
+
+ *buffer = g_queue_pop_head (nicesrc->outbufs);
+ GST_OBJECT_UNLOCK (basesrc);
+@@ -331,6 +354,7 @@ gst_nice_src_dispose (GObject *object)
+ g_queue_free (src->outbufs);
+ }
+ src->outbufs = NULL;
++ g_cond_clear (&src->outcond);
+
+ G_OBJECT_CLASS (gst_nice_src_parent_class)->dispose (object);
+ }
+diff --git a/gst/gstnicesrc.h b/gst/gstnicesrc.h
+index 5d3f554..2d9f674 100644
+--- a/gst/gstnicesrc.h
++++ b/gst/gstnicesrc.h
+@@ -68,8 +68,8 @@ struct _GstNiceSrc
+ GMainContext *mainctx;
+ GMainLoop *mainloop;
+ GQueue *outbufs;
+- gboolean unlocked;
+- GSource *idle_source;
++ GCond outcond;
++ GThread *agent_io_thread;
+ };
+
+ typedef struct _GstNiceSrcClass GstNiceSrcClass;
+--
+2.3.4
+
diff --git a/Tools/gtk/patches/librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch b/Tools/gtk/patches/librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch
new file mode 100644
index 000000000..a20af4ce1
--- /dev/null
+++ b/Tools/gtk/patches/librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch
@@ -0,0 +1,1581 @@
+diff -ur librsvg-2.36.1-orig/config.guess librsvg-2.36.1/config.guess
+--- librsvg-2.36.1-orig/config.guess 2012-02-03 13:14:58.000000000 +0100
++++ librsvg-2.36.1/config.guess 2014-09-25 18:36:54.000000000 +0200
+@@ -1,14 +1,12 @@
+ #! /bin/sh
+ # Attempt to guess a canonical system name.
+-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-# Free Software Foundation, Inc.
++# Copyright 1992-2014 Free Software Foundation, Inc.
+
+-timestamp='2009-11-20'
++timestamp='2014-03-23'
+
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful, but
+@@ -17,26 +15,22 @@
+ # General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
+-
+-
+-# Originally written by Per Bothner. Please send patches (context
+-# diff format) to <config-patches@gnu.org> and include a ChangeLog
+-# entry.
++# the same distribution terms that you use for the rest of that
++# program. This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ #
+-# This script attempts to guess a canonical system name similar to
+-# config.sub. If it succeeds, it prints the system name on stdout, and
+-# exits with 0. Otherwise, it exits with 1.
++# Originally written by Per Bothner.
+ #
+ # You can get the latest version of this script from:
+ # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
++#
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++
+
+ me=`echo "$0" | sed -e 's,.*/,,'`
+
+@@ -56,8 +50,7 @@
+ GNU config.guess ($timestamp)
+
+ Originally written by Per Bothner.
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright 1992-2014 Free Software Foundation, Inc.
+
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -139,12 +132,33 @@
+ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
++case "${UNAME_SYSTEM}" in
++Linux|GNU|GNU/*)
++ # If the system lacks a compiler, then just pick glibc.
++ # We could probably try harder.
++ LIBC=gnu
++
++ eval $set_cc_for_build
++ cat <<-EOF > $dummy.c
++ #include <features.h>
++ #if defined(__UCLIBC__)
++ LIBC=uclibc
++ #elif defined(__dietlibc__)
++ LIBC=dietlibc
++ #else
++ LIBC=gnu
++ #endif
++ EOF
++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
++ ;;
++esac
++
+ # Note: order is significant - the case branches are not exclusive.
+
+ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
++ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+@@ -180,7 +194,7 @@
+ fi
+ ;;
+ *)
+- os=netbsd
++ os=netbsd
+ ;;
+ esac
+ # The OS release
+@@ -201,6 +215,10 @@
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
++ *:Bitrig:*:*)
++ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
++ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
++ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+@@ -223,7 +241,7 @@
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
++ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+@@ -269,7 +287,10 @@
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- exit ;;
++ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
++ exitcode=$?
++ trap '' 0
++ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+@@ -295,12 +316,12 @@
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+- echo powerpc-ibm-os400
++ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+- arm:riscos:*:*|arm:RISCOS:*:*)
++ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+@@ -394,23 +415,23 @@
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+- echo m68k-atari-mint${UNAME_RELEASE}
++ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+- exit ;;
++ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+- echo m68k-atari-mint${UNAME_RELEASE}
++ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+- echo m68k-milan-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-milan-mint${UNAME_RELEASE}
++ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+- echo m68k-hades-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-hades-mint${UNAME_RELEASE}
++ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+- echo m68k-unknown-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-unknown-mint${UNAME_RELEASE}
++ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+@@ -480,8 +501,8 @@
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+- # DG/UX returns AViiON for all architectures
+- UNAME_PROCESSOR=`/usr/bin/uname -p`
++ # DG/UX returns AViiON for all architectures
++ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+@@ -494,7 +515,7 @@
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+- exit ;;
++ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+@@ -551,7 +572,7 @@
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+- *:AIX:*:[456])
++ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+@@ -594,52 +615,52 @@
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+- case "${sc_cpu_version}" in
+- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+- 532) # CPU_PA_RISC2_0
+- case "${sc_kernel_bits}" in
+- 32) HP_ARCH="hppa2.0n" ;;
+- 64) HP_ARCH="hppa2.0w" ;;
++ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
++ case "${sc_cpu_version}" in
++ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
++ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
++ 532) # CPU_PA_RISC2_0
++ case "${sc_kernel_bits}" in
++ 32) HP_ARCH="hppa2.0n" ;;
++ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+- esac ;;
+- esac
++ esac ;;
++ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+- sed 's/^ //' << EOF >$dummy.c
++ sed 's/^ //' << EOF >$dummy.c
++
++ #define _HPUX_SOURCE
++ #include <stdlib.h>
++ #include <unistd.h>
++
++ int main ()
++ {
++ #if defined(_SC_KERNEL_BITS)
++ long bits = sysconf(_SC_KERNEL_BITS);
++ #endif
++ long cpu = sysconf (_SC_CPU_VERSION);
+
+- #define _HPUX_SOURCE
+- #include <stdlib.h>
+- #include <unistd.h>
+-
+- int main ()
+- {
+- #if defined(_SC_KERNEL_BITS)
+- long bits = sysconf(_SC_KERNEL_BITS);
+- #endif
+- long cpu = sysconf (_SC_CPU_VERSION);
+-
+- switch (cpu)
+- {
+- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+- case CPU_PA_RISC2_0:
+- #if defined(_SC_KERNEL_BITS)
+- switch (bits)
+- {
+- case 64: puts ("hppa2.0w"); break;
+- case 32: puts ("hppa2.0n"); break;
+- default: puts ("hppa2.0"); break;
+- } break;
+- #else /* !defined(_SC_KERNEL_BITS) */
+- puts ("hppa2.0"); break;
+- #endif
+- default: puts ("hppa1.0"); break;
+- }
+- exit (0);
+- }
++ switch (cpu)
++ {
++ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
++ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
++ case CPU_PA_RISC2_0:
++ #if defined(_SC_KERNEL_BITS)
++ switch (bits)
++ {
++ case 64: puts ("hppa2.0w"); break;
++ case 32: puts ("hppa2.0n"); break;
++ default: puts ("hppa2.0"); break;
++ } break;
++ #else /* !defined(_SC_KERNEL_BITS) */
++ puts ("hppa2.0"); break;
++ #endif
++ default: puts ("hppa1.0"); break;
++ }
++ exit (0);
++ }
+ EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+@@ -730,22 +751,22 @@
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+- exit ;;
++ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+- exit ;;
++ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+- exit ;;
++ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+- exit ;;
++ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+- exit ;;
++ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+@@ -769,14 +790,14 @@
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+- exit ;;
++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
++ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
++ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+@@ -788,30 +809,35 @@
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+- case ${UNAME_MACHINE} in
+- pc98)
+- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++ UNAME_PROCESSOR=`/usr/bin/uname -p`
++ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
++ *:MINGW64*:*)
++ echo ${UNAME_MACHINE}-pc-mingw64
++ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
++ *:MSYS*:*)
++ echo ${UNAME_MACHINE}-pc-msys
++ exit ;;
+ i*:windows32*:*)
+- # uname -m includes "-pc" on this system.
+- echo ${UNAME_MACHINE}-mingw32
++ # uname -m includes "-pc" on this system.
++ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+- case ${UNAME_MACHINE} in
++ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+@@ -848,15 +874,22 @@
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
++ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
++ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
++ aarch64:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
++ aarch64_be:Linux:*:*)
++ UNAME_MACHINE=aarch64_be
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+@@ -866,52 +899,56 @@
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+- esac
++ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
++ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
++ arc:Linux:*:* | arceb:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
++ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
++ | grep -q __ARM_PCS_VFP
++ then
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
++ else
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
++ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+- echo cris-axis-linux-gnu
++ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+- echo crisv32-axis-linux-gnu
++ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+- echo frv-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
++ hexagon:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+- LIBC=gnu
+- eval $set_cc_for_build
+- sed 's/^ //' << EOF >$dummy.c
+- #ifdef __dietlibc__
+- LIBC=dietlibc
+- #endif
+-EOF
+- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
++ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+@@ -930,51 +967,63 @@
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
++ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+- or32:Linux:*:*)
+- echo or32-unknown-linux-gnu
++ openrisc*:Linux:*:*)
++ echo or1k-unknown-linux-${LIBC}
++ exit ;;
++ or32:Linux:*:* | or1k*:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+- echo sparc-unknown-linux-gnu
++ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+- echo hppa64-unknown-linux-gnu
++ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+- PA7*) echo hppa1.1-unknown-linux-gnu ;;
+- PA8*) echo hppa2.0-unknown-linux-gnu ;;
+- *) echo hppa-unknown-linux-gnu ;;
++ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
++ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
++ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+- echo powerpc64-unknown-linux-gnu
++ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+- echo powerpc-unknown-linux-gnu
++ echo powerpc-unknown-linux-${LIBC}
++ exit ;;
++ ppc64le:Linux:*:*)
++ echo powerpc64le-unknown-linux-${LIBC}
++ exit ;;
++ ppcle:Linux:*:*)
++ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+- echo ${UNAME_MACHINE}-ibm-linux
++ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
++ tile*:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+- echo ${UNAME_MACHINE}-dec-linux-gnu
++ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+- echo x86_64-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+@@ -983,11 +1032,11 @@
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+- # Unixware is an offshoot of SVR4, but it has its own version
+- # number series starting with 2...
+- # I am not positive that other SVR4 systems won't match this,
++ # Unixware is an offshoot of SVR4, but it has its own version
++ # number series starting with 2...
++ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+- # Use sysv4.2uw... so that sysv4* matches it.
++ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+@@ -1019,7 +1068,7 @@
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+- # UnixWare 7.x, OpenUNIX and OpenServer 6.
++ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+@@ -1047,13 +1096,13 @@
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+- # uname -m prints for DJGPP always 'pc', but it prints nothing about
+- # the processor, so we play safe by assuming i586.
++ # uname -m prints for DJGPP always 'pc', but it prints nothing about
++ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+- exit ;;
++ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+@@ -1088,8 +1137,8 @@
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+- && { echo i486-ncr-sysv4; exit; } ;;
++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
++ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+@@ -1132,10 +1181,10 @@
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+- # says <Richard.M.Bartel@ccMail.Census.GOV>
+- echo i586-unisys-sysv4
+- exit ;;
++ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
++ # says <Richard.M.Bartel@ccMail.Census.GOV>
++ echo i586-unisys-sysv4
++ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+@@ -1161,11 +1210,11 @@
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+- echo mips-nec-sysv${UNAME_RELEASE}
++ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+- echo mips-unknown-sysv${UNAME_RELEASE}
++ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+- exit ;;
++ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+@@ -1178,6 +1227,9 @@
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
++ x86_64:Haiku:*:*)
++ echo x86_64-unknown-haiku
++ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+@@ -1204,19 +1256,31 @@
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+- case $UNAME_PROCESSOR in
+- i386)
+- eval $set_cc_for_build
+- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+- grep IS_64BIT_ARCH >/dev/null
+- then
+- UNAME_PROCESSOR="x86_64"
+- fi
+- fi ;;
+- unknown) UNAME_PROCESSOR=powerpc ;;
+- esac
++ eval $set_cc_for_build
++ if test "$UNAME_PROCESSOR" = unknown ; then
++ UNAME_PROCESSOR=powerpc
++ fi
++ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
++ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
++ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
++ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
++ grep IS_64BIT_ARCH >/dev/null
++ then
++ case $UNAME_PROCESSOR in
++ i386) UNAME_PROCESSOR=x86_64 ;;
++ powerpc) UNAME_PROCESSOR=powerpc64 ;;
++ esac
++ fi
++ fi
++ elif test "$UNAME_PROCESSOR" = i386 ; then
++ # Avoid executing cc on OS X 10.9, as it ships with a stub
++ # that puts up a graphical alert prompting to install
++ # developer tools. Any system running Mac OS X 10.7 or
++ # later (Darwin 11 and later) is required to have a 64-bit
++ # processor. This is not true of the ARM version of Darwin
++ # that Apple uses in portable devices.
++ UNAME_PROCESSOR=x86_64
++ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+@@ -1230,7 +1294,10 @@
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+- NSE-?:NONSTOP_KERNEL:*:*)
++ NEO-?:NONSTOP_KERNEL:*:*)
++ echo neo-tandem-nsk${UNAME_RELEASE}
++ exit ;;
++ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+@@ -1275,13 +1342,13 @@
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+- echo mips-sei-seiux${UNAME_RELEASE}
++ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+- UNAME_MACHINE=`(uname -p) 2>/dev/null`
++ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+@@ -1299,158 +1366,10 @@
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+-esac
+-
+-#echo '(No uname command or uname output not recognized.)' 1>&2
+-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+-
+-eval $set_cc_for_build
+-cat >$dummy.c <<EOF
+-#ifdef _SEQUENT_
+-# include <sys/types.h>
+-# include <sys/utsname.h>
+-#endif
+-main ()
+-{
+-#if defined (sony)
+-#if defined (MIPSEB)
+- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+- I don't know.... */
+- printf ("mips-sony-bsd\n"); exit (0);
+-#else
+-#include <sys/param.h>
+- printf ("m68k-sony-newsos%s\n",
+-#ifdef NEWSOS4
+- "4"
+-#else
+- ""
+-#endif
+- ); exit (0);
+-#endif
+-#endif
+-
+-#if defined (__arm) && defined (__acorn) && defined (__unix)
+- printf ("arm-acorn-riscix\n"); exit (0);
+-#endif
+-
+-#if defined (hp300) && !defined (hpux)
+- printf ("m68k-hp-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (NeXT)
+-#if !defined (__ARCHITECTURE__)
+-#define __ARCHITECTURE__ "m68k"
+-#endif
+- int version;
+- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+- if (version < 4)
+- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+- else
+- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+- exit (0);
+-#endif
+-
+-#if defined (MULTIMAX) || defined (n16)
+-#if defined (UMAXV)
+- printf ("ns32k-encore-sysv\n"); exit (0);
+-#else
+-#if defined (CMU)
+- printf ("ns32k-encore-mach\n"); exit (0);
+-#else
+- printf ("ns32k-encore-bsd\n"); exit (0);
+-#endif
+-#endif
+-#endif
+-
+-#if defined (__386BSD__)
+- printf ("i386-pc-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (sequent)
+-#if defined (i386)
+- printf ("i386-sequent-dynix\n"); exit (0);
+-#endif
+-#if defined (ns32000)
+- printf ("ns32k-sequent-dynix\n"); exit (0);
+-#endif
+-#endif
+-
+-#if defined (_SEQUENT_)
+- struct utsname un;
+-
+- uname(&un);
+-
+- if (strncmp(un.version, "V2", 2) == 0) {
+- printf ("i386-sequent-ptx2\n"); exit (0);
+- }
+- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+- printf ("i386-sequent-ptx1\n"); exit (0);
+- }
+- printf ("i386-sequent-ptx\n"); exit (0);
+-
+-#endif
+-
+-#if defined (vax)
+-# if !defined (ultrix)
+-# include <sys/param.h>
+-# if defined (BSD)
+-# if BSD == 43
+- printf ("vax-dec-bsd4.3\n"); exit (0);
+-# else
+-# if BSD == 199006
+- printf ("vax-dec-bsd4.3reno\n"); exit (0);
+-# else
+- printf ("vax-dec-bsd\n"); exit (0);
+-# endif
+-# endif
+-# else
+- printf ("vax-dec-bsd\n"); exit (0);
+-# endif
+-# else
+- printf ("vax-dec-ultrix\n"); exit (0);
+-# endif
+-#endif
+-
+-#if defined (alliant) && defined (i860)
+- printf ("i860-alliant-bsd\n"); exit (0);
+-#endif
+-
+- exit (1);
+-}
+-EOF
+-
+-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+- { echo "$SYSTEM_NAME"; exit; }
+-
+-# Apollos put the system type in the environment.
+-
+-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+-
+-# Convex versions that predate uname can use getsysinfo(1)
+-
+-if [ -x /usr/convex/getsysinfo ]
+-then
+- case `getsysinfo -f cpu_type` in
+- c1*)
+- echo c1-convex-bsd
+- exit ;;
+- c2*)
+- if getsysinfo -f scalar_acc
+- then echo c32-convex-bsd
+- else echo c2-convex-bsd
+- fi
++ x86_64:VMkernel:*:*)
++ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+- c34*)
+- echo c34-convex-bsd
+- exit ;;
+- c38*)
+- echo c38-convex-bsd
+- exit ;;
+- c4*)
+- echo c4-convex-bsd
+- exit ;;
+- esac
+-fi
++esac
+
+ cat >&2 <<EOF
+ $0: unable to guess system type
+diff -ur librsvg-2.36.1-orig/config.sub librsvg-2.36.1/config.sub
+--- librsvg-2.36.1-orig/config.sub 2012-02-03 13:14:58.000000000 +0100
++++ librsvg-2.36.1/config.sub 2014-09-25 18:37:12.000000000 +0200
+@@ -1,38 +1,31 @@
+ #! /bin/sh
+ # Configuration validation subroutine script.
+-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-# Free Software Foundation, Inc.
+-
+-timestamp='2009-11-20'
+-
+-# This file is (in principle) common to ALL GNU software.
+-# The presence of a machine in this file suggests that SOME GNU software
+-# can handle that machine. It does not imply ALL GNU software can.
+-#
+-# This file is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# Copyright 1992-2014 Free Software Foundation, Inc.
++
++timestamp='2014-09-11'
++
++# This file is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
++# the same distribution terms that you use for the rest of that
++# program. This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+
+
+-# Please send patches to <config-patches@gnu.org>. Submit a context
+-# diff and a properly formatted GNU ChangeLog entry.
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+ #
+ # Configuration subroutine to validate and canonicalize a configuration type.
+ # Supply the specified configuration type as an argument.
+@@ -75,8 +68,7 @@
+ version="\
+ GNU config.sub ($timestamp)
+
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright 1992-2014 Free Software Foundation, Inc.
+
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -123,13 +115,18 @@
+ # Here we must recognize all the valid KERNEL-OS combinations.
+ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+ case $maybe_os in
+- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
++ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
++ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
++ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
++ android-linux)
++ os=-linux-android
++ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
++ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+@@ -152,12 +149,12 @@
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+- -apple | -axis | -knuth | -cray | -microblaze)
++ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+- -bluegene*)
+- os=-cnk
++ -bluegene*)
++ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+@@ -173,10 +170,10 @@
+ os=-chorusos
+ basic_machine=$1
+ ;;
+- -chorusrdb)
+- os=-chorusrdb
++ -chorusrdb)
++ os=-chorusrdb
+ basic_machine=$1
+- ;;
++ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+@@ -221,6 +218,12 @@
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
++ -lynx*178)
++ os=-lynxos178
++ ;;
++ -lynx*5)
++ os=-lynxos5
++ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+@@ -245,20 +248,28 @@
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
++ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
++ | arc | arceb \
++ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
++ | avr | avr32 \
++ | be32 | be64 \
+ | bfin \
+- | c4x | clipper \
++ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
++ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
++ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
++ | k1om \
++ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+- | maxq | mb | microblaze | mcore | mep | metag \
++ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+@@ -272,38 +283,51 @@
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
++ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
++ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
++ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+- | nios | nios2 \
++ | nds32 | nds32le | nds32be \
++ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+- | or32 \
++ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
++ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+- | rx \
++ | riscv32 | riscv64 \
++ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+- | spu | strongarm \
+- | tahoe | thumb | tic4x | tic80 | tron \
++ | spu \
++ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+- | v850 | v850e \
++ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
++ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+- m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+- # Motorola 68HC11/12.
++ c54x)
++ basic_machine=tic54x-unknown
++ ;;
++ c55x)
++ basic_machine=tic55x-unknown
++ ;;
++ c6x)
++ basic_machine=tic6x-unknown
++ ;;
++ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+@@ -313,6 +337,21 @@
+ basic_machine=mt-unknown
+ ;;
+
++ strongarm | thumb | xscale)
++ basic_machine=arm-unknown
++ ;;
++ xgate)
++ basic_machine=$basic_machine-unknown
++ os=-none
++ ;;
++ xscaleeb)
++ basic_machine=armeb-unknown
++ ;;
++
++ xscaleel)
++ basic_machine=armel-unknown
++ ;;
++
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+@@ -327,25 +366,31 @@
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
++ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
++ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
++ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+- | clipper-* | craynv-* | cydra-* \
++ | c[123]* | c30-* | [cjt]90-* | c4x-* \
++ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
++ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
++ | k1om-* \
++ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
++ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
++ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+@@ -359,33 +404,41 @@
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
++ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
++ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
++ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+- | nios-* | nios2-* \
++ | nds32-* | nds32le-* | nds32be-* \
++ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
++ | open8-* \
++ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
++ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+- | romp-* | rs6000-* | rx-* \
++ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+- | tahoe-* | thumb-* \
+- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
++ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
++ | tahoe-* \
++ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
++ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+- | v850-* | v850e-* | vax-* \
++ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
++ | vax-* \
+ | we32k-* \
+- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
++ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+@@ -410,7 +463,7 @@
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+- abacus)
++ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+@@ -480,11 +533,20 @@
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
++ c54x-*)
++ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
++ c55x-*)
++ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
++ c6x-*)
++ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+- cegcc)
++ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+@@ -516,7 +578,7 @@
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+- cr16)
++ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+@@ -674,7 +736,6 @@
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+@@ -732,11 +793,15 @@
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+- microblaze)
++ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
++ mingw64)
++ basic_machine=x86_64-pc
++ os=-mingw64
++ ;;
+ mingw32)
+- basic_machine=i386-pc
++ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+@@ -764,6 +829,10 @@
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
++ moxiebox)
++ basic_machine=moxie-unknown
++ os=-moxiebox
++ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+@@ -771,10 +840,18 @@
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
++ msys)
++ basic_machine=i686-pc
++ os=-msys
++ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
++ nacl)
++ basic_machine=le32-unknown
++ os=-nacl
++ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+@@ -839,6 +916,12 @@
+ np1)
+ basic_machine=np1-gould
+ ;;
++ neo-tandem)
++ basic_machine=neo-tandem
++ ;;
++ nse-tandem)
++ basic_machine=nse-tandem
++ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+@@ -921,9 +1004,10 @@
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+- ppc) basic_machine=powerpc-unknown
++ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ppc-* | ppcbe-*)
++ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+@@ -948,7 +1032,11 @@
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+- rdos)
++ rdos | rdos64)
++ basic_machine=x86_64-pc
++ os=-rdos
++ ;;
++ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+@@ -1017,6 +1105,9 @@
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
++ strongarm-* | thumb-*)
++ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+@@ -1073,20 +1164,8 @@
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+- tic54x | c54x*)
+- basic_machine=tic54x-unknown
+- os=-coff
+- ;;
+- tic55x | c55x*)
+- basic_machine=tic55x-unknown
+- os=-coff
+- ;;
+- tic6x | c6x*)
+- basic_machine=tic6x-unknown
+- os=-coff
+- ;;
+ tile*)
+- basic_machine=tile-unknown
++ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+@@ -1156,6 +1235,9 @@
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
++ xscale-* | xscalee[bl]-*)
++ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
++ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+@@ -1253,11 +1335,11 @@
+ if [ x"$os" != x"" ]
+ then
+ case $os in
+- # First match some system type aliases
+- # that might get confused with valid system types.
++ # First match some system type aliases
++ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+- -auroraux)
+- os=-auroraux
++ -auroraux)
++ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+@@ -1281,28 +1363,29 @@
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+- | -sym* | -kopensolaris* \
++ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+- | -openbsd* | -solidbsd* \
++ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+- | -uxpv* | -beos* | -mpeix* | -udk* \
++ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
++ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
++ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
++ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
++ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+@@ -1341,7 +1424,7 @@
+ -opened*)
+ os=-openedition
+ ;;
+- -os400*)
++ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+@@ -1390,7 +1473,7 @@
+ -sinix*)
+ os=-sysv4
+ ;;
+- -tpf*)
++ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+@@ -1426,15 +1509,14 @@
+ -aros*)
+ os=-aros
+ ;;
+- -kaos*)
+- os=-kaos
+- ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
++ -nacl*)
++ ;;
+ -none)
+ ;;
+ *)
+@@ -1457,10 +1539,10 @@
+ # system, and we'll never get to this point.
+
+ case $basic_machine in
+- score-*)
++ score-*)
+ os=-elf
+ ;;
+- spu-*)
++ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+@@ -1472,8 +1554,23 @@
+ arm*-semi)
+ os=-aout
+ ;;
+- c4x-* | tic4x-*)
+- os=-coff
++ c4x-* | tic4x-*)
++ os=-coff
++ ;;
++ c8051-*)
++ os=-elf
++ ;;
++ hexagon-*)
++ os=-elf
++ ;;
++ tic54x-*)
++ os=-coff
++ ;;
++ tic55x-*)
++ os=-coff
++ ;;
++ tic6x-*)
++ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+@@ -1493,14 +1590,11 @@
+ ;;
+ m68000-sun)
+ os=-sunos3
+- # This also exists in the configure program, but was not the
+- # default.
+- # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+- mep-*)
++ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+@@ -1527,7 +1621,7 @@
+ *-ibm)
+ os=-aix
+ ;;
+- *-knuth)
++ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
diff --git a/Tools/gtk/patches/libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch b/Tools/gtk/patches/libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch
new file mode 100644
index 000000000..67545df38
--- /dev/null
+++ b/Tools/gtk/patches/libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch
@@ -0,0 +1,130 @@
+From afee3002ff45b7a00df3d6804fa7d329b907d361 Mon Sep 17 00:00:00 2001
+From: Carlos Garcia Campos <cgarcia@igalia.com>
+Date: Mon, 30 Jan 2017 13:57:12 +0100
+Subject: [PATCH 1/2] auth: Fix async authentication when flag
+ SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is used
+
+When the flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is used, it's not possible
+to successfully authenticate, and SOUP_STATUS_UNAUTHORIZED is always
+returned even when soup_auth_autenticate was called with the right
+credentials. This happens because we set the auth on the soup message right
+after emitting the authenticate signal only if it was authenticated. If the
+signal pauses the message, the auth will no longer be associated to the message,
+and not cached either because flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is
+present. Since we always check if the auth returned by
+soup_auth_get_message is ready before trying to use it, we can simply
+always set the auth on the mssage right after emitting the authenticate
+signal even if it was not authenticated yet. If it's eventually
+authenticated then got-body callback will check it's ready to re-queue
+the message as expected.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=777936
+---
+ libsoup/soup-auth-manager.c | 4 +--
+ tests/auth-test.c | 61 +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+), 2 deletions(-)
+
+diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
+index 704661bc..9ff446cc 100644
+--- a/libsoup/soup-auth-manager.c
++++ b/libsoup/soup-auth-manager.c
+@@ -625,7 +625,7 @@ auth_got_headers (SoupMessage *msg, gpointer manager)
+ /* If we need to authenticate, try to do it. */
+ authenticate_auth (manager, auth, msg,
+ prior_auth_failed, FALSE, TRUE);
+- soup_message_set_auth (msg, soup_auth_is_ready (auth, msg) ? auth : NULL);
++ soup_message_set_auth (msg, auth);
+ g_object_unref (auth);
+ g_mutex_unlock (&priv->lock);
+ }
+@@ -689,7 +689,7 @@ proxy_auth_got_headers (SoupMessage *msg, gpointer manager)
+ /* If we need to authenticate, try to do it. */
+ authenticate_auth (manager, auth, msg,
+ prior_auth_failed, TRUE, TRUE);
+- soup_message_set_proxy_auth (msg, soup_auth_is_ready (auth, msg) ? auth : NULL);
++ soup_message_set_proxy_auth (msg, auth);
+ g_object_unref (auth);
+ g_mutex_unlock (&priv->lock);
+ }
+diff --git a/tests/auth-test.c b/tests/auth-test.c
+index b674c61c..23e22133 100644
+--- a/tests/auth-test.c
++++ b/tests/auth-test.c
+@@ -1336,6 +1336,66 @@ do_message_do_not_use_auth_cache_test (void)
+ }
+
+ static void
++async_no_auth_cache_authenticate (SoupSession *session, SoupMessage *msg,
++ SoupAuth *auth, gboolean retrying, SoupAuth **auth_out)
++{
++ debug_printf (1, " async_no_auth_cache_authenticate\n");
++
++ soup_session_pause_message (session, msg);
++ *auth_out = g_object_ref (auth);
++ g_main_loop_quit (loop);
++}
++
++static void
++async_no_auth_cache_finished (SoupSession *session, SoupMessage *msg, gpointer user_data)
++{
++ debug_printf (1, " async_no_auth_cache_finished\n");
++
++ g_main_loop_quit (loop);
++}
++
++static void
++do_async_message_do_not_use_auth_cache_test (void)
++{
++ SoupSession *session;
++ SoupMessage *msg;
++ char *uri;
++ SoupAuth *auth = NULL;
++ SoupMessageFlags flags;
++
++ SOUP_TEST_SKIP_IF_NO_APACHE;
++
++ loop = g_main_loop_new (NULL, TRUE);
++ session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
++ uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
++
++ msg = soup_message_new ("GET", uri);
++ g_free (uri);
++ g_signal_connect (session, "authenticate",
++ G_CALLBACK (async_no_auth_cache_authenticate), &auth);
++ flags = soup_message_get_flags (msg);
++ soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
++ g_object_ref (msg);
++ soup_session_queue_message (session, msg, async_no_auth_cache_finished, NULL);
++ g_main_loop_run (loop);
++
++ soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
++
++ soup_test_assert (auth, "msg didn't get authenticate signal");
++ soup_auth_authenticate (auth, "user1", "realm1");
++ g_object_unref (auth);
++
++ soup_session_unpause_message (session, msg);
++ g_main_loop_run (loop);
++
++ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
++
++ soup_test_session_abort_unref (session);
++ g_object_unref (msg);
++ g_main_loop_unref (loop);
++}
++
++static void
+ has_authorization_header_authenticate (SoupSession *session, SoupMessage *msg,
+ SoupAuth *auth, gboolean retrying, gpointer data)
+ {
+@@ -1432,6 +1492,7 @@ main (int argc, char **argv)
+ g_test_add_func ("/auth/disappearing-auth", do_disappearing_auth_test);
+ g_test_add_func ("/auth/clear-credentials", do_clear_credentials_test);
+ g_test_add_func ("/auth/message-do-not-use-auth-cache", do_message_do_not_use_auth_cache_test);
++ g_test_add_func ("/auth/async-message-do-not-use-auth-cache", do_async_message_do_not_use_auth_cache_test);
+ g_test_add_func ("/auth/authorization-header-request", do_message_has_authorization_header_test);
+
+ ret = g_test_run ();
+--
+2.11.0
+
diff --git a/Tools/gtk/patches/libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch b/Tools/gtk/patches/libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch
new file mode 100644
index 000000000..7d3ab58b2
--- /dev/null
+++ b/Tools/gtk/patches/libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch
@@ -0,0 +1,114 @@
+From c8401c372adc9a9cb11fc870c390affb10379cfa Mon Sep 17 00:00:00 2001
+From: Carlos Garcia Campos <cgarcia@igalia.com>
+Date: Sat, 11 Feb 2017 17:44:46 +0100
+Subject: [PATCH 2/2] auth: do not use cached credentials in lookup method when
+ flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is present
+
+This is causing that a request with flag
+SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE success if a previous request without
+the flag stored the credentials. This patch also fixes another issues
+with the test /auth/message-do-not-use-auth-cache, the case of providing
+the credentials in the url was working because do_digest_nonce_test()
+didn't disconnect the authenticate signal that was actually used. This
+is because soup_uri_to_string removes the password from the uri. The
+test needs to use a custom message created with
+soup_message_new_from_uri() instead of using do_digest_nonce_test().
+
+https://bugzilla.gnome.org/show_bug.cgi?id=778497
+---
+ libsoup/soup-auth-manager.c | 6 ++++++
+ tests/auth-test.c | 29 +++++++++++++++++++++++++----
+ 2 files changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
+index 9ff446cc..b32ba900 100644
+--- a/libsoup/soup-auth-manager.c
++++ b/libsoup/soup-auth-manager.c
+@@ -472,6 +472,9 @@ lookup_auth (SoupAuthManagerPrivate *priv, SoupMessage *msg)
+ if (auth && soup_auth_is_ready (auth, msg))
+ return auth;
+
++ if (soup_message_get_flags (msg) & SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE)
++ return NULL;
++
+ host = get_auth_host_for_uri (priv, soup_message_get_uri (msg));
+ if (!host->auth_realms && !make_auto_ntlm_auth (priv, host))
+ return NULL;
+@@ -496,6 +499,9 @@ lookup_proxy_auth (SoupAuthManagerPrivate *priv, SoupMessage *msg)
+ if (auth && soup_auth_is_ready (auth, msg))
+ return auth;
+
++ if (soup_message_get_flags (msg) & SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE)
++ return NULL;
++
+ return priv->proxy_auth;
+ }
+
+diff --git a/tests/auth-test.c b/tests/auth-test.c
+index 23e22133..2d66da9e 100644
+--- a/tests/auth-test.c
++++ b/tests/auth-test.c
+@@ -442,6 +442,12 @@ do_digest_nonce_test (SoupSession *session,
+ got_401 ? "got" : "did not get");
+ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
+
++ if (expect_signal) {
++ g_signal_handlers_disconnect_by_func (session,
++ G_CALLBACK (digest_nonce_authenticate),
++ NULL);
++ }
++
+ g_object_unref (msg);
+ }
+
+@@ -1297,9 +1303,10 @@ do_message_do_not_use_auth_cache_test (void)
+ {
+ SoupSession *session;
+ SoupAuthManager *manager;
++ SoupMessage *msg;
++ SoupMessageFlags flags;
+ SoupURI *soup_uri;
+ char *uri;
+- char *uri_with_credentials;
+
+ SOUP_TEST_SKIP_IF_NO_APACHE;
+
+@@ -1318,18 +1325,32 @@ do_message_do_not_use_auth_cache_test (void)
+ soup_uri = soup_uri_new (uri);
+ soup_uri_set_user (soup_uri, "user1");
+ soup_uri_set_password (soup_uri, "realm1");
+- uri_with_credentials = soup_uri_to_string (soup_uri, FALSE);
++ msg = soup_message_new_from_uri (SOUP_METHOD_GET, soup_uri);
++ flags = soup_message_get_flags (msg);
++ soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
++ soup_session_send_message (session, msg);
++ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
++ g_object_unref (msg);
+ soup_uri_free (soup_uri);
+- do_digest_nonce_test (session, "Fourth", uri_with_credentials, FALSE, TRUE, FALSE);
+- g_free (uri_with_credentials);
+
+ manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
++
+ soup_auth_manager_clear_cached_credentials (manager);
+
+ /* Now check that credentials are not stored */
+ do_digest_nonce_test (session, "First", uri, FALSE, TRUE, TRUE);
+ do_digest_nonce_test (session, "Second", uri, TRUE, TRUE, TRUE);
+ do_digest_nonce_test (session, "Third", uri, TRUE, FALSE, FALSE);
++
++ /* Credentials were stored for uri, but if we set SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE flag,
++ * and we don't have the authenticate signal, it should respond with 401
++ */
++ msg = soup_message_new (SOUP_METHOD_GET, uri);
++ flags = soup_message_get_flags (msg);
++ soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
++ soup_session_send_message (session, msg);
++ soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
++ g_object_unref (msg);
+ g_free (uri);
+
+ soup_test_session_abort_unref (session);
+--
+2.11.0
+
diff --git a/Tools/gtk/patches/mesa-gallivm-Fix-build-after-LLVM-commit-211259.patch b/Tools/gtk/patches/mesa-gallivm-Fix-build-after-LLVM-commit-211259.patch
new file mode 100644
index 000000000..75f38e552
--- /dev/null
+++ b/Tools/gtk/patches/mesa-gallivm-Fix-build-after-LLVM-commit-211259.patch
@@ -0,0 +1,29 @@
+From 564821c917f4a9d5a0de2ee77b90b0cd85e3d3a6 Mon Sep 17 00:00:00 2001
+From: Aaron Watry <awatry@gmail.com>
+Date: Fri, 20 Jun 2014 19:13:30 -0500
+Subject: [PATCH] gallivm: Fix build after LLVM commit 211259
+
+Signed-off-by: Aaron Watry <awatry@gmail.com>
+Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
+---
+ src/gallium/auxiliary/gallivm/lp_bld_debug.cpp | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
+index df26883..413a0c2 100644
+--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
++++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
+@@ -51,7 +51,9 @@
+ #include <llvm/MC/MCInstPrinter.h>
+ #include <llvm/MC/MCRegisterInfo.h>
+
+-#if HAVE_LLVM >= 0x0303
++#if HAVE_LLVM >= 0x0305
++#define OwningPtr std::unique_ptr
++#elif HAVE_LLVM >= 0x0303
+ #include <llvm/ADT/OwningPtr.h>
+ #endif
+
+--
+2.1.0
+
diff --git a/Tools/gtk/patches/openh264-configure.patch b/Tools/gtk/patches/openh264-configure.patch
new file mode 100644
index 000000000..7bf1bd5a1
--- /dev/null
+++ b/Tools/gtk/patches/openh264-configure.patch
@@ -0,0 +1,12 @@
+--- /dev/null 2015-06-05 15:20:34.000000000 +1000
++++ pseudo-configure 2015-06-05 15:20:37.000000000 +1000
+@@ -0,0 +1,8 @@
++#!/bin/sh
++
++X=Makefile
++sed -e "s:^PREFIX=.*:PREFIX=$JHBUILD_PREFIX:" ${X} > ${X}.tmp && mv ${X}.tmp ${X}
++sed -e "s:^SHAREDLIB_DIR=.*:SHAREDLIB_DIR=$CMAKE_LIBRARY_PATH:" ${X} > ${X}.tmp && mv ${X}.tmp ${X}
++
++X=build/x86-common.mk
++sed -e "s:^ASM =.*:ASM = yasm:" $X > ${X}.tmp && mv ${X}.tmp $X
+
diff --git a/Tools/gtk/patches/rtspsrc-timeout-on-udpsrc-is-in-nanoseconds.patch b/Tools/gtk/patches/rtspsrc-timeout-on-udpsrc-is-in-nanoseconds.patch
new file mode 100644
index 000000000..87ed49087
--- /dev/null
+++ b/Tools/gtk/patches/rtspsrc-timeout-on-udpsrc-is-in-nanoseconds.patch
@@ -0,0 +1,27 @@
+From e0bb1fe30985aa0784825388500cc4fa92c1ff9c Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wim.taymans@collabora.co.uk>
+Date: Wed, 12 Dec 2012 11:09:42 +0100
+Subject: [PATCH 2/2] rtspsrc: timeout on udpsrc is in nanoseconds
+
+---
+ gst/rtsp/gstrtspsrc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
+index 98577b8..902d8ff 100644
+--- a/gst/rtsp/gstrtspsrc.c
++++ b/gst/rtsp/gstrtspsrc.c
+@@ -2812,8 +2812,8 @@ gst_rtspsrc_stream_configure_udp (GstRTSPSrc * src, GstRTSPStream * stream,
+ /* configure a timeout on the UDP port. When the timeout message is
+ * posted, we assume UDP transport is not possible. We reconnect using TCP
+ * if we can. */
+- g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout", src->udp_timeout,
+- NULL);
++ g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout",
++ src->udp_timeout * 1000, NULL);
+
+ /* get output pad of the UDP source. */
+ *outpad = gst_element_get_static_pad (stream->udpsrc[0], "src");
+--
+1.8.1.2
+
diff --git a/Tools/gtk/patches/shared-mime-info-xht-glob.patch b/Tools/gtk/patches/shared-mime-info-xht-glob.patch
new file mode 100644
index 000000000..667ae4991
--- /dev/null
+++ b/Tools/gtk/patches/shared-mime-info-xht-glob.patch
@@ -0,0 +1,21 @@
+From 6e5818deb54fdfa70f5798fc1df1d5c3eaba42df Mon Sep 17 00:00:00 2001
+From: Bastien Nocera <hadess@hadess.net>
+Date: Thu, 7 Jan 2016 15:48:47 +0100
+Subject: Add *.xht as a glob for XHTML files
+
+
+diff --git a/freedesktop.org.xml.in b/freedesktop.org.xml.in
+index dc12655..48696d9 100644
+--- a/freedesktop.org.xml.in
++++ b/freedesktop.org.xml.in
+@@ -3669,6 +3669,7 @@ command to generate the output files.
+ <sub-class-of type="application/xml"/>
+ <generic-icon name="text-html"/>
+ <glob pattern="*.xhtml"/>
++ <glob pattern="*.xht"/>
+ <root-XML namespaceURI='http://www.w3.org/1999/xhtml' localName='html'/>
+ </mime-type>
+ <mime-type type="application/zip">
+--
+cgit v0.10.2
+
diff --git a/Tools/gtk/patches/shared-mime-info-xhtml-magic.patch b/Tools/gtk/patches/shared-mime-info-xhtml-magic.patch
new file mode 100644
index 000000000..4d0e81615
--- /dev/null
+++ b/Tools/gtk/patches/shared-mime-info-xhtml-magic.patch
@@ -0,0 +1,26 @@
+From 4961dc3e48d13c0c675ad7c135419b864813ca55 Mon Sep 17 00:00:00 2001
+From: Bastien Nocera <hadess@hadess.net>
+Date: Thu, 7 Jan 2016 15:49:16 +0100
+Subject: Add magic for XHTML files
+
+
+diff --git a/freedesktop.org.xml.in b/freedesktop.org.xml.in
+index 48696d9..9ea2f95 100644
+--- a/freedesktop.org.xml.in
++++ b/freedesktop.org.xml.in
+@@ -3670,6 +3670,12 @@ command to generate the output files.
+ <generic-icon name="text-html"/>
+ <glob pattern="*.xhtml"/>
+ <glob pattern="*.xht"/>
++ <magic priority="60">
++ <match type="string" value="//W3C//DTD XHTML " offset="0:256"/>
++ <match type="string" value="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" offset="0:256"/>
++ <match type="string" value="&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml" offset="0:256"/>
++ <match type="string" value="&lt;HTML xmlns=&quot;http://www.w3.org/1999/xhtml" offset="0:256"/>
++ </magic>
+ <root-XML namespaceURI='http://www.w3.org/1999/xhtml' localName='html'/>
+ </mime-type>
+ <mime-type type="application/zip">
+--
+cgit v0.10.2
+
diff --git a/Tools/gtk/patches/udpsrc-improve-timeouts.patch b/Tools/gtk/patches/udpsrc-improve-timeouts.patch
new file mode 100644
index 000000000..d26e346a8
--- /dev/null
+++ b/Tools/gtk/patches/udpsrc-improve-timeouts.patch
@@ -0,0 +1,53 @@
+From dbbdf54778771535dfea5ddbdeeaba89d9bc7be6 Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wim.taymans@collabora.co.uk>
+Date: Wed, 12 Dec 2012 11:08:13 +0100
+Subject: [PATCH 1/2] udpsrc: improve timeouts
+
+Make it possible to set the timeout after we went to the READY state by using
+the timeout when checking the condition. This also makes it possible to set the
+timeout with a higher granularity than seconds.
+---
+ gst/udp/gstudpsrc.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c
+index bdad5b3..5b54021 100644
+--- a/gst/udp/gstudpsrc.c
++++ b/gst/udp/gstudpsrc.c
+@@ -397,13 +397,20 @@ retry:
+ goto no_select;
+
+ do {
++ gint64 timeout;
++
+ try_again = FALSE;
+
++ if (udpsrc->timeout)
++ timeout = udpsrc->timeout / 1000;
++ else
++ timeout = -1;
++
+ GST_LOG_OBJECT (udpsrc, "doing select, timeout %" G_GUINT64_FORMAT,
+- udpsrc->timeout);
++ timeout);
+
+- if (!g_socket_condition_wait (udpsrc->used_socket, G_IO_IN | G_IO_PRI,
+- udpsrc->cancellable, &err)) {
++ if (!g_socket_condition_timed_wait (udpsrc->used_socket, G_IO_IN | G_IO_PRI,
++ timeout, udpsrc->cancellable, &err)) {
+ if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_BUSY)
+ || g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ goto stopped;
+@@ -823,9 +830,6 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
+ goto getsockname_error;
+ }
+
+- if (src->timeout)
+- g_socket_set_timeout (src->used_socket, src->timeout / GST_SECOND);
+-
+ #if GLIB_CHECK_VERSION (2, 35, 7)
+ {
+ gint val = 0;
+--
+1.8.1.2
+
diff --git a/Tools/gtk/patches/xserver-remove-bogus-dependencies.patch b/Tools/gtk/patches/xserver-remove-bogus-dependencies.patch
new file mode 100644
index 000000000..e17753e37
--- /dev/null
+++ b/Tools/gtk/patches/xserver-remove-bogus-dependencies.patch
@@ -0,0 +1,43 @@
+From 879f42531ff04be578c39f9d44548aeb3ded67fd Mon Sep 17 00:00:00 2001
+From: Gustavo Noronha Silva <gustavo.noronha@collabora.com>
+Date: Wed, 8 May 2013 19:44:15 -0300
+Subject: [PATCH 2/2] Filter out -l parameters when setting dependencies
+
+Newer make (Fedora 19) gets confused when it finds a -l parameter in a
+dependency, and tries to make it as a target, causing the build to fail.
+
+Signed-off-by: Gustavo Noronha Silva <gustavo.noronha@collabora.com>
+---
+ hw/vfb/Makefile.am | 2 +-
+ test/Makefile.am | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/vfb/Makefile.am b/hw/vfb/Makefile.am
+index 9f4992c..06830ae 100644
+--- a/hw/vfb/Makefile.am
++++ b/hw/vfb/Makefile.am
+@@ -20,7 +20,7 @@ XVFB_LIBS = \
+ $(top_builddir)/Xi/libXistubs.la
+
+ Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS)
+-Xvfb_DEPENDENCIES = $(XVFB_LIBS)
++Xvfb_DEPENDENCIES = $(filter-out -l%,$(XVFB_LIBS))
+ Xvfb_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
+
+ relink:
+diff --git a/test/Makefile.am b/test/Makefile.am
+index 34f53fc..3509306 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -131,7 +131,7 @@ libxservertest_la_LIBADD += \
+ endif
+ endif
+
+-libxservertest_la_DEPENDENCIES = $(libxservertest_la_LIBADD)
++libxservertest_la_DEPENDENCIES = $(filter-out -l%,$(libxservertest_la_LIBADD))
+ endif
+
+ EXTRA_DIST = ddxstubs.c
+--
+1.8.2.1
+
diff --git a/Tools/gtk/patches/xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch b/Tools/gtk/patches/xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch
new file mode 100644
index 000000000..ad380c851
--- /dev/null
+++ b/Tools/gtk/patches/xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch
@@ -0,0 +1,84 @@
+From fcbd29debee422bcb147057a089fd1da5e699656 Mon Sep 17 00:00:00 2001
+From: Carlos Alberto Lopez Perez <clopez@igalia.com>
+Date: Wed, 23 Mar 2016 03:47:58 +0100
+Subject: [PATCH xserver] Search for DRI drivers at LIBGL_DRIVERS_PATH
+ environment variable.
+
+ * The Mesa driver uses this environment variable to override the
+ default compiled search path for DRI drivers.
+
+ * This is useful for testing purposes when the user needs to
+ override the system default one at runtime.
+---
+ glx/glxdricommon.c | 40 ++++++++++++++++++++++++++++++----------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c
+index 62cce13..543f631 100644
+--- a/glx/glxdricommon.c
++++ b/glx/glxdricommon.c
+@@ -246,8 +246,6 @@ glxConvertConfigs(const __DRIcoreExtension * core,
+ return head.next;
+ }
+
+-static const char dri_driver_path[] = DRI_DRIVER_PATH;
+-
+ /* Temporary define to allow building without a dri_interface.h from
+ * updated Mesa. Some day when we don't care about Mesa that old any
+ * more this can be removed.
+@@ -261,22 +259,44 @@ glxProbeDriver(const char *driverName,
+ void **coreExt, const char *coreName, int coreVersion,
+ void **renderExt, const char *renderName, int renderVersion)
+ {
+- int i;
++ int i, len;
+ void *driver;
+ char filename[PATH_MAX];
+ char *get_extensions_name;
+ const __DRIextension **extensions = NULL;
++ const char *dri_driver_path, *p, *next;
+
+- snprintf(filename, sizeof filename, "%s/%s_dri.so",
+- dri_driver_path, driverName);
++ dri_driver_path = getenv("LIBGL_DRIVERS_PATH");
++
++ if (dri_driver_path == NULL)
++ dri_driver_path = DRI_DRIVER_PATH;
++
++ for (p = dri_driver_path; *p; p = next) {
++ next = strchr(p, ':');
++ if (next == NULL) {
++ len = strlen(p);
++ next = p + len;
++ }
++ else {
++ len = next - p;
++ next++;
++ }
++
++ snprintf(filename, sizeof filename, "%.*s/%s_dri.so",
++ len, p, driverName);
++
++ driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
++ if (driver == NULL)
++ LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
++ filename, dlerror());
++ else
++ break;
+
+- driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+- if (driver == NULL) {
+- LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
+- filename, dlerror());
+- goto cleanup_failure;
+ }
+
++ if (driver == NULL)
++ goto cleanup_failure;
++
+ if (asprintf(&get_extensions_name, "%s_%s",
+ __DRI_DRIVER_GET_EXTENSIONS, driverName) != -1) {
+ const __DRIextension **(*get_extensions)(void);
+--
+2.1.4
+