comparison 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
comparison
equal deleted inserted replaced
26134:997bbae7b80f 26135:c334a9e17426
316 pidgin_media_emit_message(PidginMedia *gtkmedia, const char *msg) 316 pidgin_media_emit_message(PidginMedia *gtkmedia, const char *msg)
317 { 317 {
318 g_signal_emit(gtkmedia, pidgin_media_signals[MESSAGE], 0, msg); 318 g_signal_emit(gtkmedia, pidgin_media_signals[MESSAGE], 0, msg);
319 } 319 }
320 320
321 typedef struct
322 {
323 PidginMedia *gtkmedia;
324 gchar *session_id;
325 gchar *participant;
326 } PidginMediaRealizeData;
327
321 static gboolean 328 static gboolean
322 create_window (GstBus *bus, GstMessage *message, PidginMedia *gtkmedia) 329 realize_cb_cb(PidginMediaRealizeData *data)
323 { 330 {
324 char *name; 331 PidginMediaPrivate *priv = data->gtkmedia->priv;
325 332 gulong window_id;
326 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ELEMENT) 333
327 return TRUE; 334 if (data->participant == NULL)
328 335 window_id = GDK_WINDOW_XWINDOW(priv->local_video->window);
329 if (!gst_structure_has_name(message->structure, "prepare-xwindow-id")) 336 else
330 return TRUE; 337 window_id = GDK_WINDOW_XWINDOW(priv->remote_video->window);
331 338
332 name = gst_object_get_name(GST_MESSAGE_SRC (message)); 339 purple_media_set_output_window(priv->media, data->session_id,
333 340 data->participant, window_id);
334 /* The XOverlay's name is the sink's name with a suffix */ 341
335 if (!strncmp(name, "purplevideosink", strlen("purplevideosink"))) 342 g_free(data->session_id);
336 gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)), 343 g_free(data->participant);
337 GDK_WINDOW_XWINDOW(gtkmedia->priv->remote_video->window)); 344 g_free(data);
338 else if (!strncmp(name, "purplelocalvideosink", strlen("purplelocalvideosink")))
339 gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)),
340 GDK_WINDOW_XWINDOW(gtkmedia->priv->local_video->window));
341 g_free(name);
342 return TRUE;
343 }
344
345 static gboolean
346 realize_cb_cb(GstElement *element)
347 {
348 gst_element_set_locked_state(element, FALSE);
349 gst_element_set_state(element, GST_STATE_PLAYING);
350 return FALSE; 345 return FALSE;
351 } 346 }
352 347
353 static void 348 static void
354 realize_cb(GtkWidget *widget, GstElement *element) 349 realize_cb(GtkWidget *widget, PidginMediaRealizeData *data)
355 { 350 {
356 g_timeout_add(0, (GSourceFunc)realize_cb_cb, element); 351 g_timeout_add(0, (GSourceFunc)realize_cb_cb, data);
357 } 352 }
358 353
359 static void 354 static void
360 pidgin_media_error_cb(PidginMedia *media, const char *error, PidginMedia *gtkmedia) 355 pidgin_media_error_cb(PidginMedia *media, const char *error, PidginMedia *gtkmedia)
361 { 356 {
388 GtkWidget *send_widget = NULL, *recv_widget = NULL; 383 GtkWidget *send_widget = NULL, *recv_widget = NULL;
389 GstElement *audiosendbin = NULL, *audiosendlevel = NULL; 384 GstElement *audiosendbin = NULL, *audiosendlevel = NULL;
390 GstElement *videosendbin = NULL; 385 GstElement *videosendbin = NULL;
391 gboolean audiorecvbool = FALSE; 386 gboolean audiorecvbool = FALSE;
392 gboolean videorecvbool = FALSE; 387 gboolean videorecvbool = FALSE;
393 GstBus *bus;
394 gboolean is_initiator; 388 gboolean is_initiator;
395 389
396 PurpleMediaSessionType type = purple_media_get_session_type(media, sid); 390 PurpleMediaSessionType type = purple_media_get_session_type(media, sid);
397 if (type & PURPLE_MEDIA_AUDIO) { 391 if (type & PURPLE_MEDIA_AUDIO) {
398 if (!audiosendbin && (type & PURPLE_MEDIA_SEND_AUDIO)) { 392 if (!audiosendbin && (type & PURPLE_MEDIA_SEND_AUDIO)) {
404 audiorecvbool = TRUE; 398 audiorecvbool = TRUE;
405 } 399 }
406 } else if (type & PURPLE_MEDIA_VIDEO) { 400 } else if (type & PURPLE_MEDIA_VIDEO) {
407 if (!videosendbin && (type & PURPLE_MEDIA_SEND_VIDEO)) { 401 if (!videosendbin && (type & PURPLE_MEDIA_SEND_VIDEO)) {
408 purple_media_video_init_src(&videosendbin); 402 purple_media_video_init_src(&videosendbin);
409 gst_element_set_locked_state(videosendbin, TRUE);
410 purple_media_set_src(media, sid, videosendbin); 403 purple_media_set_src(media, sid, videosendbin);
404 gst_element_set_state(videosendbin, GST_STATE_PLAYING);
411 } 405 }
412 if (!videorecvbool && (type & PURPLE_MEDIA_RECV_VIDEO)) { 406 if (!videorecvbool && (type & PURPLE_MEDIA_RECV_VIDEO)) {
413 videorecvbool = TRUE; 407 videorecvbool = TRUE;
414 } 408 }
415 } 409 }
430 gtk_widget_show(send_widget); 424 gtk_widget_show(send_widget);
431 } else 425 } else
432 send_widget = gtkmedia->priv->send_widget; 426 send_widget = gtkmedia->priv->send_widget;
433 427
434 if (videorecvbool) { 428 if (videorecvbool) {
429 PidginMediaRealizeData *data;
435 GtkWidget *aspect; 430 GtkWidget *aspect;
436 GtkWidget *remote_video; 431 GtkWidget *remote_video;
437 GtkWidget *plug; 432 GtkWidget *plug;
438 GtkWidget *socket; 433 GtkWidget *socket;
439 434
452 g_signal_connect(G_OBJECT(socket), "plug-removed", 447 g_signal_connect(G_OBJECT(socket), "plug-removed",
453 G_CALLBACK(plug_removed_cb), NULL); 448 G_CALLBACK(plug_removed_cb), NULL);
454 gtk_container_add(GTK_CONTAINER(aspect), socket); 449 gtk_container_add(GTK_CONTAINER(aspect), socket);
455 gtk_widget_show(socket); 450 gtk_widget_show(socket);
456 451
452 data = g_new0(PidginMediaRealizeData, 1);
453 data->gtkmedia = gtkmedia;
454 data->session_id = g_strdup(sid);
455 data->participant = g_strdup(gtkmedia->priv->screenname);
456
457 remote_video = gtk_drawing_area_new(); 457 remote_video = gtk_drawing_area_new();
458 g_signal_connect(G_OBJECT(remote_video), "realize",
459 G_CALLBACK(realize_cb), data);
458 gtk_container_add(GTK_CONTAINER(plug), remote_video); 460 gtk_container_add(GTK_CONTAINER(plug), remote_video);
459 gtk_widget_set_size_request (GTK_WIDGET(remote_video), 100, -1); 461 gtk_widget_set_size_request (GTK_WIDGET(remote_video), 100, -1);
460 gtk_widget_show(remote_video); 462 gtk_widget_show(remote_video);
461 gtk_widget_show(aspect); 463 gtk_widget_show(aspect);
462 464
463 gtkmedia->priv->remote_video = remote_video; 465 gtkmedia->priv->remote_video = remote_video;
464 } 466 }
465 if (videosendbin) { 467 if (videosendbin) {
468 PidginMediaRealizeData *data;
466 GtkWidget *aspect; 469 GtkWidget *aspect;
467 GtkWidget *local_video; 470 GtkWidget *local_video;
468 GtkWidget *plug; 471 GtkWidget *plug;
469 GtkWidget *socket; 472 GtkWidget *socket;
470 473
483 g_signal_connect(G_OBJECT(socket), "plug-removed", 486 g_signal_connect(G_OBJECT(socket), "plug-removed",
484 G_CALLBACK(plug_removed_cb), NULL); 487 G_CALLBACK(plug_removed_cb), NULL);
485 gtk_container_add(GTK_CONTAINER(aspect), socket); 488 gtk_container_add(GTK_CONTAINER(aspect), socket);
486 gtk_widget_show(socket); 489 gtk_widget_show(socket);
487 490
491 data = g_new0(PidginMediaRealizeData, 1);
492 data->gtkmedia = gtkmedia;
493 data->session_id = g_strdup(sid);
494 data->participant = NULL;
495
488 local_video = gtk_drawing_area_new(); 496 local_video = gtk_drawing_area_new();
489 g_signal_connect(G_OBJECT(local_video), "realize", 497 g_signal_connect(G_OBJECT(local_video), "realize",
490 G_CALLBACK(realize_cb), videosendbin); 498 G_CALLBACK(realize_cb), data);
491 gtk_container_add(GTK_CONTAINER(plug), local_video); 499 gtk_container_add(GTK_CONTAINER(plug), local_video);
492 gtk_widget_set_size_request (GTK_WIDGET(local_video), 100, -1); 500 gtk_widget_set_size_request (GTK_WIDGET(local_video), 100, -1);
493 501
494 gtk_widget_show(local_video); 502 gtk_widget_show(local_video);
495 gtk_widget_show(aspect); 503 gtk_widget_show(aspect);
516 gtk_widget_show(gtkmedia->priv->send_progress); 524 gtk_widget_show(gtkmedia->priv->send_progress);
517 525
518 gtk_widget_show(gtkmedia->priv->mute); 526 gtk_widget_show(gtkmedia->priv->mute);
519 } 527 }
520 528
521 bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); 529
522 530 if (audiorecvbool || audiosendbin) {
523 if (videorecvbool || videosendbin) 531 GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
524 g_signal_connect(bus, "sync-message::element",
525 G_CALLBACK(create_window), gtkmedia);
526
527 if (audiorecvbool || audiosendbin)
528 g_signal_connect(G_OBJECT(bus), "message::element", 532 g_signal_connect(G_OBJECT(bus), "message::element",
529 G_CALLBACK(level_message_cb), gtkmedia); 533 G_CALLBACK(level_message_cb), gtkmedia);
530 534 gst_object_unref(bus);
531 gst_object_unref(bus); 535 }
532 536
533 if (send_widget != NULL) 537 if (send_widget != NULL)
534 gtkmedia->priv->send_widget = send_widget; 538 gtkmedia->priv->send_widget = send_widget;
535 if (recv_widget != NULL) 539 if (recv_widget != NULL)
536 gtkmedia->priv->recv_widget = recv_widget; 540 gtkmedia->priv->recv_widget = recv_widget;