From: Nicolas Dufresne Date: Thu, 11 Jun 2015 16:10:23 +0000 (-0400) Subject: gstgtk: Allow doing gst-inspect-1.0 on these elements X-Git-Tag: 1.19.3~509^2~1701^2~92 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5c6050f8495204eee48b8a6b7e5bee3b9e420ab6;p=platform%2Fupstream%2Fgstreamer.git gstgtk: Allow doing gst-inspect-1.0 on these elements This patch allow going gst-inspect-1.0 on these elements removing ugly crash that was previously occurring. The method consist of making the widget creation as lazy as possible. This way we don't endup doing gtk_init() before the application. We also ref_sink() the widget, so we don't crash if the parent widget is discarded, and cleanly error out with GL if the widget has no parent window, because calling gtk_widget_realized() can only be done if the widget has been parented to a window). --- diff --git a/ext/gtk/gstgtkglsink.c b/ext/gtk/gstgtkglsink.c index 1572f97..9ad1950 100644 --- a/ext/gtk/gstgtkglsink.c +++ b/ext/gtk/gstgtkglsink.c @@ -120,7 +120,6 @@ gst_gtk_gl_sink_class_init (GstGtkGLSinkClass * klass) static void gst_gtk_gl_sink_init (GstGtkGLSink * gtk_sink) { - gtk_sink->widget = (GtkGstGLWidget *) gtk_gst_gl_widget_new (); } static void @@ -165,6 +164,28 @@ gst_gtk_gl_sink_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static GtkGstGLWidget * +gst_gtk_gl_sink_get_widget (GstGtkGLSink * gtk_sink) +{ + if (gtk_sink->widget != NULL) + return gtk_sink->widget; + + /* Ensure GTK is initialized, this has no side effect if it was already + * initialized. Also, we do that lazylli, so the application can be first */ + if (!gtk_init_check (NULL, NULL)) { + GST_ERROR_OBJECT (gtk_sink, "Could not ensure GTK initialization."); + return NULL; + } + + gtk_sink->widget = (GtkGstGLWidget *) gtk_gst_gl_widget_new (); + + /* Take the floating ref, otherwise the destruction of the container will + * make this widget disapear possibly before we are done. */ + gst_object_ref_sink (gtk_sink->widget); + + return gtk_sink->widget; +} + static void gst_gtk_gl_sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) @@ -175,7 +196,7 @@ gst_gtk_gl_sink_get_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_WIDGET: - g_value_set_object (value, gtk_sink->widget); + g_value_set_object (value, gst_gtk_gl_sink_get_widget (gtk_sink)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -254,6 +275,17 @@ gst_gtk_gl_sink_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: + if (gst_gtk_gl_sink_get_widget (gtk_sink) == NULL) + return GST_STATE_CHANGE_FAILURE; + + /* After this point, gtk_sink->widget will always be set */ + + if (!gtk_widget_get_parent (GTK_WIDGET (gtk_sink->widget))) { + GST_ERROR_OBJECT (gtk_sink, + "gtkglsink widget need to be parented to work."); + return GST_STATE_CHANGE_FAILURE; + } + if (!gtk_gst_gl_widget_init_winsys (gtk_sink->widget)) return GST_STATE_CHANGE_FAILURE; diff --git a/ext/gtk/gstgtksink.c b/ext/gtk/gstgtksink.c index e60d1bb..b921ff0 100644 --- a/ext/gtk/gstgtksink.c +++ b/ext/gtk/gstgtksink.c @@ -117,7 +117,6 @@ gst_gtk_sink_class_init (GstGtkSinkClass * klass) static void gst_gtk_sink_init (GstGtkSink * gtk_sink) { - gtk_sink->widget = (GtkGstWidget *) gtk_gst_widget_new (); } static void @@ -141,6 +140,28 @@ gst_gtk_sink_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static GtkGstWidget * +gst_gtk_sink_get_widget (GstGtkSink * gtk_sink) +{ + if (gtk_sink->widget != NULL) + return gtk_sink->widget; + + /* Ensure GTK is initialized, this has no side effect if it was already + * initialized. Also, we do that lazylli, so the application can be first */ + if (!gtk_init_check (NULL, NULL)) { + GST_ERROR_OBJECT (gtk_sink, "Could not ensure GTK initialization."); + return NULL; + } + + gtk_sink->widget = (GtkGstWidget *) gtk_gst_widget_new (); + + /* Take the floating ref, other wise the destruction of the container will + * make this widget disapear possibly before we are done. */ + gst_object_ref_sink (gtk_sink->widget); + + return gtk_sink->widget; +} + static void gst_gtk_sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) @@ -151,7 +172,7 @@ gst_gtk_sink_get_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_WIDGET: - g_value_set_object (value, gtk_sink->widget); + g_value_set_object (value, gst_gtk_sink_get_widget (gtk_sink)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -191,6 +212,8 @@ gst_gtk_sink_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: + if (gst_gtk_sink_get_widget (gtk_sink) == NULL) + return GST_STATE_CHANGE_FAILURE; break; case GST_STATE_CHANGE_READY_TO_PAUSED: break;