From bf5741f424e5d478e6941be5c59d571020e54cf0 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Fri, 23 Apr 2021 16:08:48 +0900 Subject: [PATCH] smart-mixer: Add support for d3d11compositor and glvideomixer Some hardware compositor elements (d3d11compositor and glvideomixer) consist of wrapper bin with internal mixer element. So, we need special handling for such elements. Part-of: --- ges/ges-smart-video-mixer.c | 15 +++++++++--- ges/ges-utils.c | 46 ++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/ges/ges-smart-video-mixer.c b/ges/ges-smart-video-mixer.c index 877e4e540f..636f1699b9 100644 --- a/ges/ges-smart-video-mixer.c +++ b/ges/ges-smart-video-mixer.c @@ -402,16 +402,25 @@ ges_smart_mixer_constructed (GObject * obj) { GstPad *pad; GstElement *identity, *videoconvert; - GESSmartMixer *self = GES_SMART_MIXER (obj); gchar *cname = g_strdup_printf ("%s-compositor", GST_OBJECT_NAME (self)); + GstElement *mixer; self->mixer = gst_element_factory_create (ges_get_compositor_factory (), cname); g_free (cname); - g_object_set (self->mixer, "background", 1, "emit-signals", TRUE, NULL); - g_signal_connect (self->mixer, "samples-selected", + + if (GST_IS_BIN (self->mixer)) { + g_object_get (self->mixer, "mixer", &mixer, NULL); + g_assert (mixer); + } else { + mixer = gst_object_ref (self->mixer); + } + + g_object_set (mixer, "background", 1, "emit-signals", TRUE, NULL); + g_signal_connect (mixer, "samples-selected", G_CALLBACK (ges_smart_mixer_samples_selected_cb), self); + gst_object_unref (mixer); /* See https://gitlab.freedesktop.org/gstreamer/gstreamer/issues/310 */ GST_FIXME ("Stop dropping allocation query when it is not required anymore."); diff --git a/ges/ges-utils.c b/ges/ges-utils.c index 6ca105f2cb..36940680a4 100644 --- a/ges/ges-utils.c +++ b/ges/ges-utils.c @@ -137,6 +137,7 @@ find_compositor (GstPluginFeature * feature, gpointer udata) gboolean res = FALSE; const gchar *klass; GstPluginFeature *loaded_feature = NULL; + GstElement *elem = NULL; if (G_UNLIKELY (!GST_IS_ELEMENT_FACTORY (feature))) return FALSE; @@ -153,9 +154,48 @@ find_compositor (GstPluginFeature * feature, gpointer udata) return FALSE; } - res = - g_type_is_a (gst_element_factory_get_element_type (GST_ELEMENT_FACTORY - (loaded_feature)), GST_TYPE_AGGREGATOR); + /* Some hardware compositor elements (d3d11compositor for example) consist of + * bin with internal mixer elements */ + if (g_type_is_a (gst_element_factory_get_element_type (GST_ELEMENT_FACTORY + (loaded_feature)), GST_TYPE_BIN)) { + GParamSpec *pspec; + GstElement *mixer = NULL; + + elem = + gst_element_factory_create (GST_ELEMENT_FACTORY_CAST (loaded_feature), + NULL); + + /* Checks whether this element has mixer property and the internal element + * is aggregator subclass */ + if (!elem) { + GST_ERROR ("Could not create element from factory %" GST_PTR_FORMAT, + feature); + goto done; + } + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (elem), "mixer"); + if (!pspec) + goto done; + + if (!g_type_is_a (pspec->value_type, GST_TYPE_ELEMENT)) + goto done; + + g_object_get (elem, "mixer", &mixer, NULL); + if (!mixer) + goto done; + + if (GST_IS_AGGREGATOR (mixer)) + res = TRUE; + + gst_object_unref (mixer); + } else { + res = + g_type_is_a (gst_element_factory_get_element_type (GST_ELEMENT_FACTORY + (loaded_feature)), GST_TYPE_AGGREGATOR); + } + +done: + gst_clear_object (&elem); gst_object_unref (loaded_feature); return res; }