diff pidgin/gtkmedia.c @ 26135:c334a9e17426

Wait to create the sinks until the frames are ready. This should hopefully be the end of the BadWindow errors.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Mon, 19 Jan 2009 10:44:07 +0000
parents 6eeb500ce9a2
children f6a98b2b8d92
line wrap: on
line diff
--- a/pidgin/gtkmedia.c	Sat Jan 17 04:36:40 2009 +0000
+++ b/pidgin/gtkmedia.c	Mon Jan 19 10:44:07 2009 +0000
@@ -318,42 +318,37 @@
 	g_signal_emit(gtkmedia, pidgin_media_signals[MESSAGE], 0, msg);
 }
 
-static gboolean
-create_window (GstBus *bus, GstMessage *message, PidginMedia *gtkmedia)
+typedef struct
 {
-	char *name;
-
-	if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ELEMENT)
-		return TRUE;
-
-	if (!gst_structure_has_name(message->structure, "prepare-xwindow-id"))
-		return TRUE;
-
-	name = gst_object_get_name(GST_MESSAGE_SRC (message));
-
-	/* The XOverlay's name is the sink's name with a suffix */
-	if (!strncmp(name, "purplevideosink", strlen("purplevideosink")))
-		gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)),
-					     GDK_WINDOW_XWINDOW(gtkmedia->priv->remote_video->window));
-	else if (!strncmp(name, "purplelocalvideosink", strlen("purplelocalvideosink")))
-		gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)),
-					     GDK_WINDOW_XWINDOW(gtkmedia->priv->local_video->window));
-	g_free(name);
-	return TRUE;
-}
+	PidginMedia *gtkmedia;
+	gchar *session_id;
+	gchar *participant;
+} PidginMediaRealizeData;
 
 static gboolean
-realize_cb_cb(GstElement *element)
+realize_cb_cb(PidginMediaRealizeData *data)
 {
-	gst_element_set_locked_state(element, FALSE);
-	gst_element_set_state(element, GST_STATE_PLAYING);
+	PidginMediaPrivate *priv = data->gtkmedia->priv;
+	gulong window_id;
+
+	if (data->participant == NULL)
+		window_id = GDK_WINDOW_XWINDOW(priv->local_video->window);
+	else
+		window_id = GDK_WINDOW_XWINDOW(priv->remote_video->window);
+
+	purple_media_set_output_window(priv->media, data->session_id,
+			data->participant, window_id);
+
+	g_free(data->session_id);
+	g_free(data->participant);
+	g_free(data);
 	return FALSE;
 }
 
 static void
-realize_cb(GtkWidget *widget, GstElement *element)
+realize_cb(GtkWidget *widget, PidginMediaRealizeData *data)
 {
-	g_timeout_add(0, (GSourceFunc)realize_cb_cb, element);
+	g_timeout_add(0, (GSourceFunc)realize_cb_cb, data);
 }
 
 static void
@@ -390,7 +385,6 @@
 	GstElement *videosendbin = NULL;
 	gboolean audiorecvbool = FALSE;
 	gboolean videorecvbool = FALSE;
-	GstBus *bus;
 	gboolean is_initiator;
 
 	PurpleMediaSessionType type = purple_media_get_session_type(media, sid);
@@ -406,8 +400,8 @@
 	} else if (type & PURPLE_MEDIA_VIDEO) {
 		if (!videosendbin && (type & PURPLE_MEDIA_SEND_VIDEO)) {
 			purple_media_video_init_src(&videosendbin);
-			gst_element_set_locked_state(videosendbin, TRUE);
 			purple_media_set_src(media, sid, videosendbin);
+			gst_element_set_state(videosendbin, GST_STATE_PLAYING);
 		}
 		if (!videorecvbool && (type & PURPLE_MEDIA_RECV_VIDEO)) {
 			videorecvbool = TRUE;
@@ -432,6 +426,7 @@
 		send_widget = gtkmedia->priv->send_widget;
 
 	if (videorecvbool) {
+		PidginMediaRealizeData *data;
 		GtkWidget *aspect;
 		GtkWidget *remote_video;
 		GtkWidget *plug;
@@ -454,7 +449,14 @@
 		gtk_container_add(GTK_CONTAINER(aspect), socket);
 		gtk_widget_show(socket);
 
+		data = g_new0(PidginMediaRealizeData, 1);
+		data->gtkmedia = gtkmedia;
+		data->session_id = g_strdup(sid);
+		data->participant = g_strdup(gtkmedia->priv->screenname);
+
 		remote_video = gtk_drawing_area_new();
+		g_signal_connect(G_OBJECT(remote_video), "realize",
+				G_CALLBACK(realize_cb), data);
 		gtk_container_add(GTK_CONTAINER(plug), remote_video);
 		gtk_widget_set_size_request (GTK_WIDGET(remote_video), 100, -1);
 		gtk_widget_show(remote_video);
@@ -463,6 +465,7 @@
 		gtkmedia->priv->remote_video = remote_video;
 	}
 	if (videosendbin) {
+		PidginMediaRealizeData *data;
 		GtkWidget *aspect;
 		GtkWidget *local_video;
 		GtkWidget *plug;
@@ -485,9 +488,14 @@
 		gtk_container_add(GTK_CONTAINER(aspect), socket);
 		gtk_widget_show(socket);
 
+		data = g_new0(PidginMediaRealizeData, 1);
+		data->gtkmedia = gtkmedia;
+		data->session_id = g_strdup(sid);
+		data->participant = NULL;
+
 		local_video = gtk_drawing_area_new();
 		g_signal_connect(G_OBJECT(local_video), "realize",
-				G_CALLBACK(realize_cb), videosendbin);
+				G_CALLBACK(realize_cb), data);
 		gtk_container_add(GTK_CONTAINER(plug), local_video);
 		gtk_widget_set_size_request (GTK_WIDGET(local_video), 100, -1);
 
@@ -518,17 +526,13 @@
 		gtk_widget_show(gtkmedia->priv->mute);
 	}
 
-	bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
 
-	if (videorecvbool || videosendbin)
-		g_signal_connect(bus, "sync-message::element",
-				G_CALLBACK(create_window), gtkmedia);
-
-	if (audiorecvbool || audiosendbin)
+	if (audiorecvbool || audiosendbin) {
+		GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
 		g_signal_connect(G_OBJECT(bus), "message::element",
 				G_CALLBACK(level_message_cb), gtkmedia);
-
-	gst_object_unref(bus);
+		gst_object_unref(bus);
+	}
 
 	if (send_widget != NULL)
 		gtkmedia->priv->send_widget = send_widget;