Mercurial > pidgin.yaz
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; |