static void
widget_destroy_cb (GtkWidget * widget, GstGtkGLSink * gtk_sink)
{
- g_atomic_int_set (>k_sink->widget_destroyed, 1);
+ GST_OBJECT_LOCK (gtk_sink);
+ g_clear_object (>k_sink->widget);
+ GST_OBJECT_UNLOCK (gtk_sink);
}
static GtkGstGLWidget *
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
- gtk_gst_gl_widget_set_buffer (gtk_sink->widget, NULL);
+ GST_OBJECT_LOCK (gtk_sink);
+ if (gtk_sink->widget)
+ gtk_gst_gl_widget_set_buffer (gtk_sink->widget, NULL);
+ GST_OBJECT_UNLOCK (gtk_sink);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
if (gtk_sink->display) {
gtk_sink = GST_GTK_GL_SINK (vsink);
- gtk_gst_gl_widget_set_buffer (gtk_sink->widget, buf);
+ GST_OBJECT_LOCK (vsink);
- if (g_atomic_int_get (>k_sink->widget_destroyed)) {
+ if (gtk_sink->widget == NULL) {
+ GST_OBJECT_UNLOCK (vsink);
GST_ELEMENT_ERROR (gtk_sink, RESOURCE, NOT_FOUND,
("%s", "Output widget was destroyed"), (NULL));
return GST_FLOW_ERROR;
}
+ gtk_gst_gl_widget_set_buffer (gtk_sink->widget, buf);
+
+ GST_OBJECT_UNLOCK (vsink);
+
return GST_FLOW_OK;
}
GstVideoSink parent;
GtkGstGLWidget *widget;
- gboolean widget_destroyed;
GstVideoInfo v_info;
GstBufferPool *pool;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
- gtk_gst_widget_set_buffer (gtk_sink->widget, NULL);
+ GST_OBJECT_LOCK (gtk_sink);
+ if (gtk_sink->widget)
+ gtk_gst_widget_set_buffer (gtk_sink->widget, NULL);
+ GST_OBJECT_UNLOCK (gtk_sink);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
break;
gtk_sink = GST_GTK_SINK (vsink);
- if (gtk_sink->widget)
- gtk_gst_widget_set_buffer (gtk_sink->widget, buf);
+ GST_OBJECT_LOCK (vsink);
+
+ if (gtk_sink->widget == NULL) {
+ GST_OBJECT_UNLOCK (vsink);
+ GST_ELEMENT_ERROR (gtk_sink, RESOURCE, NOT_FOUND,
+ ("%s", "Output widget was destroyed"), (NULL));
+ return GST_FLOW_ERROR;
+ }
+
+ gtk_gst_widget_set_buffer (gtk_sink->widget, buf);
+
+ GST_OBJECT_UNLOCK (vsink);
return GST_FLOW_OK;
}
GLint attr_position;
GLint attr_texture;
GLuint current_tex;
+
+ /* Pending queued idles callback */
+ guint draw_id;
+ guint resize_id;
};
static void
_invoke_on_main ((ThreadFunc) _reset_gl, widget);
}
- if (widget->priv->context) {
+ if (widget->priv->context)
gst_object_unref (widget->priv->context);
- widget->priv->context = NULL;
- }
- if (widget->priv->display) {
+ if (widget->priv->display)
gst_object_unref (widget->priv->display);
- widget->priv->display = NULL;
- }
+
+ if (widget->priv->draw_id)
+ g_source_remove (widget->priv->draw_id);
+
+ if (widget->priv->resize_id)
+ g_source_remove (widget->priv->resize_id);
G_OBJECT_CLASS (gtk_gst_gl_widget_parent_class)->finalize (object);
}
static gboolean
_queue_draw (GtkGstGLWidget * widget)
{
+ g_mutex_lock (&widget->priv->lock);
+ widget->priv->draw_id = 0;
+ g_mutex_unlock (&widget->priv->lock);
+
gtk_widget_queue_draw (GTK_WIDGET (widget));
return G_SOURCE_REMOVE;
void
gtk_gst_gl_widget_set_buffer (GtkGstGLWidget * widget, GstBuffer * buffer)
{
- GMainContext *main_context = g_main_context_default ();
-
g_return_if_fail (GTK_IS_GST_GL_WIDGET (widget));
g_return_if_fail (buffer == NULL || widget->priv->negotiated);
gst_buffer_replace (&widget->priv->buffer, buffer);
widget->priv->new_buffer = TRUE;
- g_mutex_unlock (&widget->priv->lock);
+ if (!widget->priv->draw_id) {
+ widget->priv->draw_id = g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) _queue_draw, widget, NULL);
+ }
- g_main_context_invoke (main_context, (GSourceFunc) _queue_draw, widget);
+ g_mutex_unlock (&widget->priv->lock);
}
static void
static gboolean
_queue_resize (GtkGstGLWidget * widget)
{
+ g_mutex_lock (&widget->priv->lock);
+ widget->priv->resize_id = 0;
+ g_mutex_unlock (&widget->priv->lock);
+
gtk_widget_queue_resize (GTK_WIDGET (widget));
return G_SOURCE_REMOVE;
gboolean
gtk_gst_gl_widget_set_caps (GtkGstGLWidget * widget, GstCaps * caps)
{
- GMainContext *main_context = g_main_context_default ();
GstVideoInfo v_info;
g_return_val_if_fail (GTK_IS_GST_GL_WIDGET (widget), FALSE);
widget->priv->v_info = v_info;
widget->priv->negotiated = TRUE;
- g_mutex_unlock (&widget->priv->lock);
+ if (!widget->priv->resize_id) {
+ widget->priv->resize_id = g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) _queue_resize, widget, NULL);
+ }
- g_main_context_invoke (main_context, (GSourceFunc) _queue_resize, widget);
+ g_mutex_unlock (&widget->priv->lock);
return TRUE;
}
GstBuffer *buffer;
GstCaps *caps;
GstVideoInfo v_info;
+
+ /* Pending queued idles callback */
+ guint draw_id;
+ guint resize_id;
};
static void
gst_buffer_replace (&widget->priv->buffer, NULL);
g_mutex_clear (&widget->priv->lock);
+ if (widget->priv->draw_id)
+ g_source_remove (widget->priv->draw_id);
+
+ if (widget->priv->resize_id)
+ g_source_remove (widget->priv->resize_id);
+
G_OBJECT_CLASS (gtk_gst_widget_parent_class)->finalize (object);
}
static gboolean
_queue_draw (GtkGstWidget * widget)
{
+ g_mutex_lock (&widget->priv->lock);
+ widget->priv->draw_id = 0;
+ g_mutex_unlock (&widget->priv->lock);
+
gtk_widget_queue_draw (GTK_WIDGET (widget));
return G_SOURCE_REMOVE;
void
gtk_gst_widget_set_buffer (GtkGstWidget * widget, GstBuffer * buffer)
{
- GMainContext *main_context = g_main_context_default ();
-
g_return_if_fail (GTK_IS_GST_WIDGET (widget));
g_return_if_fail (buffer == NULL || widget->priv->negotiated);
gst_buffer_replace (&widget->priv->buffer, buffer);
- g_mutex_unlock (&widget->priv->lock);
+ if (!widget->priv->draw_id) {
+ widget->priv->draw_id = g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) _queue_draw, widget, NULL);
+ }
- g_main_context_invoke (main_context, (GSourceFunc) _queue_draw, widget);
+ g_mutex_unlock (&widget->priv->lock);
}
static gboolean
_queue_resize (GtkGstWidget * widget)
{
+ g_mutex_lock (&widget->priv->lock);
+ widget->priv->resize_id = 0;
+ g_mutex_unlock (&widget->priv->lock);
+
gtk_widget_queue_resize (GTK_WIDGET (widget));
return G_SOURCE_REMOVE;
gboolean
gtk_gst_widget_set_caps (GtkGstWidget * widget, GstCaps * caps)
{
- GMainContext *main_context = g_main_context_default ();
GstVideoInfo v_info;
g_return_val_if_fail (GTK_IS_GST_WIDGET (widget), FALSE);
return FALSE;
}
+ gst_buffer_replace (&widget->priv->buffer, NULL);
gst_caps_replace (&widget->priv->caps, caps);
widget->priv->v_info = v_info;
widget->priv->negotiated = TRUE;
- g_mutex_unlock (&widget->priv->lock);
-
- gtk_widget_queue_resize (GTK_WIDGET (widget));
+ if (!widget->priv->resize_id) {
+ widget->priv->resize_id = g_idle_add_full (G_PRIORITY_DEFAULT,
+ (GSourceFunc) _queue_resize, widget, NULL);
+ }
- g_main_context_invoke (main_context, (GSourceFunc) _queue_resize, widget);
+ g_mutex_unlock (&widget->priv->lock);
return TRUE;
}