[v2,1/2] gst: add helper for runtime check on gst plugin version

Submitted by Victor Toso on Jan. 27, 2019, 3:49 p.m.

Details

Message ID 20190127154902.21229-1-victortoso@redhat.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Spice

Not browsing as part of any series.

Commit Message

Victor Toso Jan. 27, 2019, 3:49 p.m.
From: Victor Toso <me@victortoso.com>

This patch factor out the runtime check for pulsesrc plugin version in
order to be used in the follow up patch by channel-display-gst.c

This code can be shared between spice-gstaudio.c and
channel-display-gst.c so it was moved to spice-util.c

tests/Makefile.am has been updated to avoid breaking tests/util.c that
includes the spice-util-priv.h header.

v1->v2:
 * Added an output argument for the helper function, so the caller can
   use it if he wants (Frediano)
 * Changed logic of the helper function to remove the goto (Frediano)
 * Improved documentation of the function (Frediano)
 * Moved helper function to spice-util.c (Frediano)

Signed-off-by: Victor Toso <victortoso@redhat.com>
---
 src/spice-gstaudio.c  | 49 ++++++++++-------------------------
 src/spice-util-priv.h |  5 ++++
 src/spice-util.c      | 60 +++++++++++++++++++++++++++++++++++++++++++
 tests/Makefile.am     |  8 +++++-
 4 files changed, 86 insertions(+), 36 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/spice-gstaudio.c b/src/spice-gstaudio.c
index 5f4a2fe..13f55de 100644
--- a/src/spice-gstaudio.c
+++ b/src/spice-gstaudio.c
@@ -25,7 +25,7 @@ 
 #include "spice-gstaudio.h"
 #include "spice-common.h"
 #include "spice-session.h"
-#include "spice-util.h"
+#include "spice-util-priv.h"
 
 struct stream {
     GstElement              *pipe;
@@ -553,44 +553,23 @@  SpiceGstaudio *spice_gstaudio_new(SpiceSession *session, GMainContext *context,
                                   const char *name)
 {
     GError *err = NULL;
+    GstPluginFeature *pulsesrc;
 
-    if (gst_init_check(NULL, NULL, &err)) {
-        GstPluginFeature *pulsesrc;
-
-        pulsesrc = gst_registry_lookup_feature(gst_registry_get(), "pulsesrc");
-        if (pulsesrc) {
-            unsigned major, minor, micro;
-            GstPlugin *plugin = gst_plugin_feature_get_plugin(pulsesrc);
-
-            if (sscanf(gst_plugin_get_version(plugin), "%u.%u.%u",
-                       &major, &minor, &micro) != 3) {
-                g_warn_if_reached();
-                gst_object_unref(plugin);
-                gst_object_unref(pulsesrc);
-                return NULL;
-            }
-
-            if (major < 1 ||
-                (major == 1 && minor < 14) ||
-                (major == 1 && minor == 14 && micro < 5)) {
-                g_warning("Bad pulsesrc version %s, lowering its rank",
-                          gst_plugin_get_version(plugin));
-                gst_plugin_feature_set_rank(pulsesrc, GST_RANK_NONE);
-            }
-
-            gst_object_unref(plugin);
-            gst_object_unref(pulsesrc);
+    if (!spice_check_gst_plugin_version("pulsesrc", 1, 14, 5, &pulsesrc, &err)) {
+        if (err != NULL) {
+            g_warning("Disabling GStreamer audio support: %s", err->message);
+            g_clear_error(&err);
+            return NULL;
         }
-
-        return g_object_new(SPICE_TYPE_GSTAUDIO,
-                            "session", session,
-                            "main-context", context,
-                            NULL);
+        g_warning("Bad pulsesrc version, set plugin's rank to NONE");
+        gst_plugin_feature_set_rank(pulsesrc, GST_RANK_NONE);
+        gst_object_unref(pulsesrc);
     }
 
-    g_warning("Disabling GStreamer audio support: %s", err->message);
-    g_clear_error(&err);
-    return NULL;
+    return g_object_new(SPICE_TYPE_GSTAUDIO,
+                        "session", session,
+                        "main-context", context,
+                        NULL);
 }
 
 static void spice_gstaudio_get_playback_volume_info_async(SpiceAudio *audio,
diff --git a/src/spice-util-priv.h b/src/spice-util-priv.h
index 38b0deb..c228dd6 100644
--- a/src/spice-util-priv.h
+++ b/src/spice-util-priv.h
@@ -19,6 +19,7 @@ 
 #define SPICE_UTIL_PRIV_H
 
 #include <glib.h>
+#include <gst/gst.h>
 #include "spice-util.h"
 
 G_BEGIN_DECLS
@@ -32,6 +33,10 @@  gchar* spice_unix2dos(const gchar *str, gssize len);
 gchar* spice_dos2unix(const gchar *str, gssize len);
 void spice_mono_edge_highlight(unsigned width, unsigned hight,
                                const guint8 *and, const guint8 *xor, guint8 *dest);
+gboolean spice_check_gst_plugin_version(const gchar *plugin_name,
+                                        guint major, guint minor, guint micro,
+                                        GstPluginFeature **out_plugin_feature,
+                                        GError **err);
 
 G_END_DECLS
 
diff --git a/src/spice-util.c b/src/spice-util.c
index f5a35ed..36e0276 100644
--- a/src/spice-util.c
+++ b/src/spice-util.c
@@ -20,9 +20,11 @@ 
 
 #include <stdbool.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <glib.h>
 #include <glib-object.h>
+#include <gio/gio.h>
 #include "spice-util-priv.h"
 #include "spice-util.h"
 #include "spice-util-priv.h"
@@ -54,6 +56,64 @@  static void spice_util_enable_debug_messages(void)
     }
 }
 
+/* Runtime check if a given @plugin_name is >= @major.@minor.@micro version in the system.
+ * Return TRUE or FALSE based on the check above.
+ * @err is set in case some unexecpted issue with GStreamer has happend.
+ * @out_plugin_feature is not NULL, it i'll be set in case of no unexpected errors.
+ * You should gst_object_unref() it after you use it. */
+G_GNUC_INTERNAL gboolean
+spice_check_gst_plugin_version(const gchar *plugin_name,
+                               guint major, guint minor, guint micro,
+                               GstPluginFeature **out_plugin_feature,
+                               GError **err)
+{
+    GstPluginFeature *plugin_feature;
+    GstPlugin *plugin;
+    guint nmatch, plugin_major, plugin_minor, plugin_micro;
+
+    if (out_plugin_feature) {
+        *out_plugin_feature = NULL;
+    }
+
+    if (!gst_init_check(NULL, NULL, err)) {
+        return FALSE;
+    }
+
+    plugin_feature = gst_registry_lookup_feature(gst_registry_get(), plugin_name);
+    if (!plugin_feature) {
+        return FALSE;
+    }
+
+    plugin = gst_plugin_feature_get_plugin(plugin_feature);
+    nmatch = sscanf(gst_plugin_get_version(plugin), "%u.%u.%u",
+                    &plugin_major, &plugin_minor, &plugin_micro);
+
+    SPICE_DEBUG("Requiring %s version %u.%u.%u, system has %s",
+                plugin_name, major, minor, micro, gst_plugin_get_version(plugin));
+    gst_object_unref(plugin);
+
+    if (nmatch != 3) {
+        gst_object_unref(plugin_feature);
+        *err = g_error_new(G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "bad versioning scheme for plugin %s", plugin_name);
+        return FALSE;
+    }
+
+    if (out_plugin_feature) {
+        *out_plugin_feature = plugin_feature;
+    }
+
+    if (plugin_major != major) {
+        return plugin_major > major;
+    }
+
+    if (plugin_minor != minor) {
+        return plugin_minor > minor;
+    }
+
+    return plugin_micro >= micro;
+}
+
 /**
  * spice_util_set_debug:
  * @enabled: %TRUE or %FALSE
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1bb0a25..5bbca32 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -24,13 +24,19 @@  noinst_PROGRAMS += $(TESTS)
 AM_CPPFLAGS =					\
 	$(COMMON_CFLAGS)			\
 	$(GIO_CFLAGS)				\
+	$(GSTAUDIO_CFLAGS)			\
+	$(GSTVIDEO_CFLAGS)			\
 	$(SMARTCARD_CFLAGS)			\
 	-I$(top_srcdir)/src			\
 	-I$(top_builddir)/src			\
 	-DG_LOG_DOMAIN=\"GSpice\"		\
 	$(NULL)
 
-AM_LDFLAGS = $(GIO_LIBS)
+AM_LDFLAGS =					\
+	$(GIO_LIBS)				\
+	$(GSTAUDIO_CFLAGS)			\
+	$(GSTVIDEO_CFLAGS)			\
+	$(NULL)
 
 LDADD =							\
 	$(top_builddir)/src/libspice-client-glib-impl.la\