From 62ed123c83ff2de84622abe1e2cb972a409c43ae Mon Sep 17 00:00:00 2001 From: Jonathan Tellier Date: Wed, 20 May 2009 13:49:02 -0400 Subject: When no video is received or sent we show contacts' avatars instead of showing black widgets. --- src/empathy-call-window.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'src') diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index 0ce80c97c..eec0e5845 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -229,6 +229,9 @@ static void empathy_call_window_restart_call (EmpathyCallWindow *window); static void empathy_call_window_status_message (EmpathyCallWindow *window, gchar *message); +static void empathy_call_window_update_avatars_visibility (EmpathyTpCall *call, + EmpathyCallWindow *window); + static gboolean empathy_call_window_bus_message (GstBus *bus, GstMessage *message, gpointer user_data); @@ -1229,6 +1232,8 @@ empathy_call_window_connected (gpointer user_data) gtk_action_set_sensitive (priv->redial, FALSE); gtk_widget_set_sensitive (priv->redial_button, FALSE); + empathy_call_window_update_avatars_visibility (call, self); + g_object_unref (call); g_mutex_lock (priv->lock); @@ -1442,6 +1447,48 @@ empathy_call_window_bus_message (GstBus *bus, GstMessage *message, return TRUE; } +static void +empathy_call_window_update_avatars_visibility (EmpathyTpCall *call, + EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + if (empathy_tp_call_is_receiving_video (call)) + { + gtk_widget_hide (priv->remote_user_avatar_widget); + gtk_widget_show (priv->video_output); + } + else + { + gtk_widget_hide (priv->video_output); + gtk_widget_show (priv->remote_user_avatar_widget); + } + + if (empathy_tp_call_is_sending_video (call)) + { + gtk_widget_hide (priv->self_user_avatar_widget); + gtk_widget_show (priv->video_preview); + } + else + { + gtk_widget_hide (priv->video_preview); + gtk_widget_show (priv->self_user_avatar_widget); + } +} + +static void +empathy_call_window_video_stream_changed_cb (EmpathyCallHandler *handler, + EmpathyCallWindow *window) +{ + EmpathyTpCall *call; + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + g_object_get (priv->handler, "tp-call", &call, NULL); + + empathy_call_window_update_avatars_visibility (call, window); + g_object_unref (call); +} + static void empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) { @@ -1457,6 +1504,8 @@ empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) G_CALLBACK (empathy_call_window_src_added_cb), window); g_signal_connect (priv->handler, "sink-pad-added", G_CALLBACK (empathy_call_window_sink_added_cb), window); + g_signal_connect (priv->handler, "video-stream-changed", + G_CALLBACK (empathy_call_window_video_stream_changed_cb), window); empathy_call_window_setup_video_preview (window); -- cgit v1.2.3 From d9a8b7a80525e4faa908c5eb0bf1f8fb89c49dfe Mon Sep 17 00:00:00 2001 From: Jonathan Tellier Date: Wed, 20 May 2009 13:49:02 -0400 Subject: Implemented the call window's "View -> Video preview" option. --- src/empathy-call-window.c | 36 +++++++++++++++++++++++++++++++++++- src/empathy-call-window.ui | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index eec0e5845..c24262a6c 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -90,6 +90,7 @@ struct _EmpathyCallWindowPriv gboolean connected; GtkUIManager *ui_manager; + GtkWidget *self_user_output_frame; GtkWidget *video_output; GtkWidget *video_preview; GtkWidget *remote_user_avatar_widget; @@ -103,6 +104,7 @@ struct _EmpathyCallWindowPriv GtkWidget *camera_button; GtkWidget *toolbar; GtkWidget *pane; + GtkAction *show_preview; GtkAction *send_video; GtkAction *redial; GtkAction *menu_fullscreen; @@ -645,6 +647,7 @@ empathy_call_window_init (EmpathyCallWindow *self) "toolbar", &priv->toolbar, "send_video", &priv->send_video, "menuredial", &priv->redial, + "show_preview", &priv->show_preview, "ui_manager", &priv->ui_manager, "menufullscreen", &priv->menu_fullscreen, NULL); @@ -1223,6 +1226,19 @@ empathy_call_window_connected (gpointer user_data) if (empathy_tp_call_has_dtmf (call)) gtk_widget_set_sensitive (priv->dtmf_panel, TRUE); + + priv->sending_video = empathy_tp_call_is_sending_video (call); + + if (priv->sending_video) + { + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), + TRUE); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), + TRUE); + gtk_toggle_tool_button_set_active ( + GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), TRUE); + } + if (priv->video_input != NULL) { gtk_widget_set_sensitive (priv->camera_button, TRUE); @@ -1682,6 +1698,11 @@ empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle, return; priv->sending_video = active; + /* When we start sending video, we want to show the video preview by + default. */ + if (priv->sending_video) + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), TRUE); + empathy_call_window_set_send_video (window, active); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), active); } @@ -1699,6 +1720,11 @@ empathy_call_window_send_video_toggled_cb (GtkToggleAction *toggle, return; priv->sending_video = active; + /* When we start sending video, we want to show the video preview by + default. */ + if (priv->sending_video) + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), TRUE); + empathy_call_window_set_send_video (window, active); gtk_toggle_tool_button_set_active ( GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), active); @@ -1708,7 +1734,15 @@ static void empathy_call_window_show_preview_toggled_cb (GtkToggleAction *toggle, EmpathyCallWindow *window) { - /* FIXME: Not implemented */ + gboolean show_preview_toggled; + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + show_preview_toggled = gtk_toggle_action_get_active (toggle); + + if (show_preview_toggled) + gtk_widget_show (priv->self_user_output_frame); + else + gtk_widget_hide (priv->self_user_output_frame); } static void diff --git a/src/empathy-call-window.ui b/src/empathy-call-window.ui index 3e67c7670..57d9efced 100644 --- a/src/empathy-call-window.ui +++ b/src/empathy-call-window.ui @@ -42,6 +42,7 @@ show_preview Video preview + True -- cgit v1.2.3 From c5c09d7a6a0161b66f1747e3496cb1365f6f35bc Mon Sep 17 00:00:00 2001 From: Jonathan Tellier Date: Fri, 5 Jun 2009 14:56:09 -0400 Subject: Not creating the video preview if we don't want to show it (in audio calls for instance). --- src/empathy-call-window.c | 153 +++++++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index c24262a6c..c1728f8fa 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -90,7 +90,6 @@ struct _EmpathyCallWindowPriv gboolean connected; GtkUIManager *ui_manager; - GtkWidget *self_user_output_frame; GtkWidget *video_output; GtkWidget *video_preview; GtkWidget *remote_user_avatar_widget; @@ -579,23 +578,14 @@ empathy_call_window_setup_self_frame (GstBus *bus, EmpathyCallWindow *self) EmpathyCallWindowPriv *priv = GET_PRIV (self); /* Initializing all the content (UI and input gst elements) related to the - self contact*/ - priv->video_tee = gst_element_factory_make ("tee", NULL); - gst_object_ref (priv->video_tee); - gst_object_sink (priv->video_tee); - + self contact, except for the video preview widget. This widget is only + initialized when the "show video preview" option is activated */ priv->self_user_output_hbox = gtk_hbox_new (FALSE, 0); priv->self_user_avatar_widget = gtk_image_new (); gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), priv->self_user_avatar_widget, TRUE, TRUE, 0); - priv->video_preview = empathy_video_widget_new_with_size (bus, - SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); - g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); - gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), - priv->video_preview, TRUE, TRUE, 0); - gtk_container_add (GTK_CONTAINER (priv->self_user_output_frame), priv->self_user_output_hbox); @@ -614,14 +604,32 @@ empathy_call_window_setup_self_frame (GstBus *bus, EmpathyCallWindow *self) static void empathy_call_window_setup_video_preview (EmpathyCallWindow *window) { + GstElement *preview; EmpathyCallWindowPriv *priv = GET_PRIV (window); + GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); + + priv->video_tee = gst_element_factory_make ("tee", NULL); + gst_object_ref (priv->video_tee); + gst_object_sink (priv->video_tee); + + priv->video_preview = empathy_video_widget_new_with_size (bus, + SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); + g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); + gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), + priv->video_preview, TRUE, TRUE, 0); + + g_object_unref (bus); - GstElement *preview = empathy_video_widget_get_element ( + preview = empathy_video_widget_get_element ( EMPATHY_VIDEO_WIDGET (priv->video_preview)); gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input, priv->video_tee, preview, NULL); gst_element_link_many (priv->video_input, priv->video_tee, preview, NULL); + + gst_element_set_state (preview, GST_STATE_PLAYING); + gst_element_set_state (priv->video_input, GST_STATE_PLAYING); + gst_element_set_state (priv->video_tee, GST_STATE_PLAYING); } static void @@ -829,14 +837,12 @@ empathy_call_window_got_self_contact_cb (EmpathyTpContactFactory *factory, } static void -empathy_call_window_constructed (GObject *object) +empathy_call_window_setup_avatars (EmpathyCallWindow *self, + EmpathyCallHandler *handler) { - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object); EmpathyCallWindowPriv *priv = GET_PRIV (self); - g_assert (priv->handler != NULL); - - g_object_get (priv->handler, "contact", &(priv->contact), NULL); + g_object_get (handler, "contact", &(priv->contact), NULL); if (priv->contact != NULL) { @@ -876,15 +882,43 @@ empathy_call_window_constructed (GObject *object) priv->remote_user_avatar_widget, MIN (REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH, REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT)); - /* We hide the self avatar. It will be shown if a problem is - encountered when we try to send video. As for the remote avatar, it - is shown by default and will be hidden when we receive video from - the remote side. */ - gtk_widget_hide (priv->self_user_avatar_widget); + /* The remote avatar is shown by default and will be hidden when we receive + video from the remote side. */ gtk_widget_hide (priv->video_output); gtk_widget_show (priv->remote_user_avatar_widget); } +static void +empathy_call_window_setup_video_preview_visibility (EmpathyCallWindow *self, + EmpathyCallHandler *handler) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (self); + gboolean initial_video = empathy_call_handler_has_initial_video (priv->handler); + + if (initial_video) + { + empathy_call_window_setup_video_preview (self); + gtk_widget_hide (priv->self_user_avatar_widget); + gtk_widget_show (priv->video_preview); + } + else + gtk_widget_show (priv->self_user_avatar_widget); + + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), + initial_video); +} + +static void +empathy_call_window_constructed (GObject *object) +{ + EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object); + EmpathyCallWindowPriv *priv = GET_PRIV (self); + + g_assert (priv->handler != NULL); + empathy_call_window_setup_avatars (self, priv->handler); + empathy_call_window_setup_video_preview_visibility (self, priv->handler); +} + static void empathy_call_window_dispose (GObject *object); static void empathy_call_window_finalize (GObject *object); @@ -1226,18 +1260,14 @@ empathy_call_window_connected (gpointer user_data) if (empathy_tp_call_has_dtmf (call)) gtk_widget_set_sensitive (priv->dtmf_panel, TRUE); - priv->sending_video = empathy_tp_call_is_sending_video (call); - if (priv->sending_video) - { - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), - TRUE); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), - TRUE); - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), TRUE); - } + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), + priv->sending_video); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), + priv->sending_video); + gtk_toggle_tool_button_set_active ( + GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), priv->sending_video); if (priv->video_input != NULL) { @@ -1326,6 +1356,14 @@ empathy_call_window_sink_added_cb (EmpathyCallHandler *handler, case TP_MEDIA_STREAM_TYPE_VIDEO: if (priv->video_input != NULL) { + if (priv->video_tee == NULL) + empathy_call_window_setup_video_preview (self); + + gtk_toggle_action_set_active ( + GTK_TOGGLE_ACTION (priv->show_preview),TRUE); + gtk_widget_show (priv->video_preview); + gtk_widget_hide (priv->self_user_avatar_widget); + pad = gst_element_get_request_pad (priv->video_tee, "src%d"); gst_pad_link (pad, sink); } @@ -1480,15 +1518,18 @@ empathy_call_window_update_avatars_visibility (EmpathyTpCall *call, gtk_widget_show (priv->remote_user_avatar_widget); } - if (empathy_tp_call_is_sending_video (call)) - { - gtk_widget_hide (priv->self_user_avatar_widget); - gtk_widget_show (priv->video_preview); - } - else + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (priv->show_preview))) { - gtk_widget_hide (priv->video_preview); - gtk_widget_show (priv->self_user_avatar_widget); + if (empathy_tp_call_is_sending_video (call)) + { + gtk_widget_hide (priv->self_user_avatar_widget); + gtk_widget_show (priv->video_preview); + } + else + { + gtk_widget_hide (priv->video_preview); + gtk_widget_show (priv->self_user_avatar_widget); + } } } @@ -1523,8 +1564,6 @@ empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) g_signal_connect (priv->handler, "video-stream-changed", G_CALLBACK (empathy_call_window_video_stream_changed_cb), window); - empathy_call_window_setup_video_preview (window); - gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); } @@ -1534,7 +1573,8 @@ empathy_call_window_delete_cb (GtkWidget *widget, GdkEvent*event, { EmpathyCallWindowPriv *priv = GET_PRIV (window); - gst_element_set_state (priv->pipeline, GST_STATE_NULL); + if (priv->pipeline != NULL) + gst_element_set_state (priv->pipeline, GST_STATE_NULL); return FALSE; } @@ -1680,6 +1720,19 @@ empathy_call_window_set_send_video (EmpathyCallWindow *window, EmpathyCallWindowPriv *priv = GET_PRIV (window); EmpathyTpCall *call; + priv->sending_video = send; + + /* When we start sending video, we want to show the video preview by + default. */ + if (send) + { + if (priv->video_preview == NULL) + empathy_call_window_setup_video_preview (window); + + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), + TRUE); + } + g_object_get (priv->handler, "tp-call", &call, NULL); empathy_tp_call_request_video_stream_direction (call, send); g_object_unref (call); @@ -1696,12 +1749,6 @@ empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle, if (priv->sending_video == active) return; - priv->sending_video = active; - - /* When we start sending video, we want to show the video preview by - default. */ - if (priv->sending_video) - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), TRUE); empathy_call_window_set_send_video (window, active); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), active); @@ -1718,12 +1765,6 @@ empathy_call_window_send_video_toggled_cb (GtkToggleAction *toggle, if (priv->sending_video == active) return; - priv->sending_video = active; - - /* When we start sending video, we want to show the video preview by - default. */ - if (priv->sending_video) - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), TRUE); empathy_call_window_set_send_video (window, active); gtk_toggle_tool_button_set_active ( -- cgit v1.2.3 From c65de38d223ada5dfcf2d74b25a6af520143f3c5 Mon Sep 17 00:00:00 2001 From: Jonathan Tellier Date: Wed, 10 Jun 2009 15:36:01 -0400 Subject: Better implemented empathy_tp_call_is_receiving_video and empathy_tp_call_is_sending_video. Removed the "video-stream-changed" from EmpathyCallHandler Corrected gtk-doc in EmpathyCallHandler. empathy_call_window_stup_video_preview now checks the status of the video_tee and the video_preview. empathy_call_window_sink_added_cb does not automatically starts the preview. --- src/empathy-call-window.c | 125 +++++++++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index c1728f8fa..7bf9c5dd6 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -604,32 +604,36 @@ empathy_call_window_setup_self_frame (GstBus *bus, EmpathyCallWindow *self) static void empathy_call_window_setup_video_preview (EmpathyCallWindow *window) { - GstElement *preview; EmpathyCallWindowPriv *priv = GET_PRIV (window); - GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - - priv->video_tee = gst_element_factory_make ("tee", NULL); - gst_object_ref (priv->video_tee); - gst_object_sink (priv->video_tee); - - priv->video_preview = empathy_video_widget_new_with_size (bus, - SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); - g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); - gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), - priv->video_preview, TRUE, TRUE, 0); - g_object_unref (bus); - - preview = empathy_video_widget_get_element ( - EMPATHY_VIDEO_WIDGET (priv->video_preview)); - gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input, - priv->video_tee, preview, NULL); - gst_element_link_many (priv->video_input, priv->video_tee, - preview, NULL); - - gst_element_set_state (preview, GST_STATE_PLAYING); - gst_element_set_state (priv->video_input, GST_STATE_PLAYING); - gst_element_set_state (priv->video_tee, GST_STATE_PLAYING); + if (priv->video_tee == NULL && priv->video_preview == NULL) + { + GstElement *preview; + GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); + + priv->video_tee = gst_element_factory_make ("tee", NULL); + gst_object_ref (priv->video_tee); + gst_object_sink (priv->video_tee); + + priv->video_preview = empathy_video_widget_new_with_size (bus, + SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); + g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); + gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), + priv->video_preview, TRUE, TRUE, 0); + + preview = empathy_video_widget_get_element ( + EMPATHY_VIDEO_WIDGET (priv->video_preview)); + gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input, + priv->video_tee, preview, NULL); + gst_element_link_many (priv->video_input, priv->video_tee, + preview, NULL); + + g_object_unref (bus); + + gst_element_set_state (preview, GST_STATE_PLAYING); + gst_element_set_state (priv->video_input, GST_STATE_PLAYING); + gst_element_set_state (priv->video_tee, GST_STATE_PLAYING); + } } static void @@ -980,9 +984,17 @@ empathy_call_window_class_init ( } +static void +empathy_call_window_video_stream_changed_cb (EmpathyTpCall *call, + GParamSpec *property, EmpathyCallWindow *self) +{ + empathy_call_window_update_avatars_visibility (call, self); +} + void empathy_call_window_dispose (GObject *object) { + EmpathyTpCall *call; EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object); EmpathyCallWindowPriv *priv = GET_PRIV (self); @@ -991,6 +1003,16 @@ empathy_call_window_dispose (GObject *object) priv->dispose_has_run = TRUE; + g_object_get (priv->handler, "tp-call", &call, NULL); + + if (call != NULL) + { + g_signal_handlers_disconnect_by_func (call, + empathy_call_window_video_stream_changed_cb, object); + } + + g_object_unref (call); + if (priv->handler != NULL) g_object_unref (priv->handler); @@ -1111,6 +1133,8 @@ empathy_call_window_reset_pipeline (EmpathyCallWindow *self) { priv->liveadder = NULL; priv->funnel = NULL; + priv->video_preview = NULL; + priv->video_tee = NULL; g_object_unref (priv->pipeline); priv->pipeline = NULL; @@ -1257,6 +1281,9 @@ empathy_call_window_connected (gpointer user_data) g_object_get (priv->handler, "tp-call", &call, NULL); + g_signal_connect (call, "notify::video-stream", + G_CALLBACK (empathy_call_window_video_stream_changed_cb), self); + if (empathy_tp_call_has_dtmf (call)) gtk_widget_set_sensitive (priv->dtmf_panel, TRUE); @@ -1356,16 +1383,26 @@ empathy_call_window_sink_added_cb (EmpathyCallHandler *handler, case TP_MEDIA_STREAM_TYPE_VIDEO: if (priv->video_input != NULL) { - if (priv->video_tee == NULL) - empathy_call_window_setup_video_preview (self); + EmpathyTpCall *call; + g_object_get (priv->handler, "tp-call", &call, NULL); - gtk_toggle_action_set_active ( - GTK_TOGGLE_ACTION (priv->show_preview),TRUE); - gtk_widget_show (priv->video_preview); - gtk_widget_hide (priv->self_user_avatar_widget); + if (empathy_tp_call_is_sending_video (call)) + { + empathy_call_window_setup_video_preview (self); + + gtk_toggle_action_set_active ( + GTK_TOGGLE_ACTION (priv->show_preview),TRUE); + gtk_widget_show (priv->video_preview); + gtk_widget_hide (priv->self_user_avatar_widget); + } - pad = gst_element_get_request_pad (priv->video_tee, "src%d"); - gst_pad_link (pad, sink); + g_object_unref (call); + + if (priv->video_tee != NULL) + { + pad = gst_element_get_request_pad (priv->video_tee, "src%d"); + gst_pad_link (pad, sink); + } } break; default: @@ -1527,25 +1564,14 @@ empathy_call_window_update_avatars_visibility (EmpathyTpCall *call, } else { - gtk_widget_hide (priv->video_preview); + if (priv->video_preview != NULL) + gtk_widget_hide (priv->video_preview); + gtk_widget_show (priv->self_user_avatar_widget); } } } -static void -empathy_call_window_video_stream_changed_cb (EmpathyCallHandler *handler, - EmpathyCallWindow *window) -{ - EmpathyTpCall *call; - EmpathyCallWindowPriv *priv = GET_PRIV (window); - - g_object_get (priv->handler, "tp-call", &call, NULL); - - empathy_call_window_update_avatars_visibility (call, window); - g_object_unref (call); -} - static void empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) { @@ -1561,8 +1587,6 @@ empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) G_CALLBACK (empathy_call_window_src_added_cb), window); g_signal_connect (priv->handler, "sink-pad-added", G_CALLBACK (empathy_call_window_sink_added_cb), window); - g_signal_connect (priv->handler, "video-stream-changed", - G_CALLBACK (empathy_call_window_video_stream_changed_cb), window); gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); } @@ -1726,9 +1750,7 @@ empathy_call_window_set_send_video (EmpathyCallWindow *window, default. */ if (send) { - if (priv->video_preview == NULL) - empathy_call_window_setup_video_preview (window); - + empathy_call_window_setup_video_preview (window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), TRUE); } @@ -1857,7 +1879,6 @@ empathy_call_window_restart_call (EmpathyCallWindow *window) empathy_call_window_setup_remote_frame (bus, window); empathy_call_window_setup_self_frame (bus, window); - empathy_call_window_setup_video_preview (window); g_object_unref (bus); -- cgit v1.2.3 From 3719c62c3f34e11dbdcdff741eb2aadf69c9c202 Mon Sep 17 00:00:00 2001 From: Jonathan Tellier Date: Thu, 11 Jun 2009 10:12:26 -0400 Subject: Added an early return in empathy_call_window_setup_video_preview. Code style correction in empathy_call_window_setup_video_preview_visibility. Corrected a bug which prevented a user with no video input to redial video calls. The "Send video" option should be properly disabled when we can't send video. --- src/empathy-call-window.c | 183 ++++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index 7bf9c5dd6..4b4f53f85 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -62,6 +62,9 @@ #define CONNECTING_STATUS_TEXT _("Connecting...") +/* If an video input error occurs, the error message will start with "v4l" */ +#define VIDEO_INPUT_ERROR_PREFIX "v4l" + G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW) /* signal enum */ @@ -187,6 +190,9 @@ static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle, static void empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle, EmpathyCallWindow *window); +static void empathy_call_window_set_send_video (EmpathyCallWindow *window, + gboolean send); + static void empathy_call_window_send_video_toggled_cb (GtkToggleAction *toggle, EmpathyCallWindow *window); @@ -606,34 +612,40 @@ empathy_call_window_setup_video_preview (EmpathyCallWindow *window) { EmpathyCallWindowPriv *priv = GET_PRIV (window); - if (priv->video_tee == NULL && priv->video_preview == NULL) + if (priv->video_preview != NULL) { - GstElement *preview; - GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - - priv->video_tee = gst_element_factory_make ("tee", NULL); - gst_object_ref (priv->video_tee); - gst_object_sink (priv->video_tee); - - priv->video_preview = empathy_video_widget_new_with_size (bus, - SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); - g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); - gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), - priv->video_preview, TRUE, TRUE, 0); - - preview = empathy_video_widget_get_element ( - EMPATHY_VIDEO_WIDGET (priv->video_preview)); - gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input, - priv->video_tee, preview, NULL); - gst_element_link_many (priv->video_input, priv->video_tee, - preview, NULL); - - g_object_unref (bus); - - gst_element_set_state (preview, GST_STATE_PLAYING); - gst_element_set_state (priv->video_input, GST_STATE_PLAYING); - gst_element_set_state (priv->video_tee, GST_STATE_PLAYING); + /* Since the video preview and the video tee are initialized and freed + at the same time, if one is initialized, then the other one should + be too. */ + g_assert (priv->video_tee != NULL); + return; } + + GstElement *preview; + GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); + + priv->video_tee = gst_element_factory_make ("tee", NULL); + gst_object_ref (priv->video_tee); + gst_object_sink (priv->video_tee); + + priv->video_preview = empathy_video_widget_new_with_size (bus, + SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); + g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); + gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), + priv->video_preview, TRUE, TRUE, 0); + + preview = empathy_video_widget_get_element ( + EMPATHY_VIDEO_WIDGET (priv->video_preview)); + gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input, + priv->video_tee, preview, NULL); + gst_element_link_many (priv->video_input, priv->video_tee, + preview, NULL); + + g_object_unref (bus); + + gst_element_set_state (preview, GST_STATE_PLAYING); + gst_element_set_state (priv->video_input, GST_STATE_PLAYING); + gst_element_set_state (priv->video_tee, GST_STATE_PLAYING); } static void @@ -903,10 +915,14 @@ empathy_call_window_setup_video_preview_visibility (EmpathyCallWindow *self, { empathy_call_window_setup_video_preview (self); gtk_widget_hide (priv->self_user_avatar_widget); - gtk_widget_show (priv->video_preview); + + if (priv->video_preview != NULL) + gtk_widget_show (priv->video_preview); } else + { gtk_widget_show (priv->self_user_avatar_widget); + } gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), initial_video); @@ -1131,12 +1147,32 @@ empathy_call_window_reset_pipeline (EmpathyCallWindow *self) if (state_change_return == GST_STATE_CHANGE_SUCCESS || state_change_return == GST_STATE_CHANGE_NO_PREROLL) { + if (priv->pipeline != NULL) + g_object_unref (priv->pipeline); + priv->pipeline = NULL; + + if (priv->video_input != NULL) + g_object_unref (priv->video_input); + priv->video_input = NULL; + + if (priv->audio_input != NULL) + g_object_unref (priv->audio_input); + priv->audio_input = NULL; + + if (priv->audio_output != NULL) + g_object_unref (priv->audio_output); + priv->audio_output = NULL; + + if (priv->video_tee != NULL) + g_object_unref (priv->video_tee); + priv->video_tee = NULL; + + if (priv->video_preview != NULL) + gtk_widget_destroy (priv->video_preview); + priv->video_preview = NULL; + priv->liveadder = NULL; priv->funnel = NULL; - priv->video_preview = NULL; - priv->video_tee = NULL; - g_object_unref (priv->pipeline); - priv->pipeline = NULL; return TRUE; } @@ -1287,20 +1323,20 @@ empathy_call_window_connected (gpointer user_data) if (empathy_tp_call_has_dtmf (call)) gtk_widget_set_sensitive (priv->dtmf_panel, TRUE); + if (priv->video_input == NULL) + empathy_call_window_set_send_video (self, FALSE); + priv->sending_video = empathy_tp_call_is_sending_video (call); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), priv->sending_video); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), - priv->sending_video); + priv->sending_video && priv->video_input != NULL); gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), priv->sending_video); - - if (priv->video_input != NULL) - { - gtk_widget_set_sensitive (priv->camera_button, TRUE); - gtk_action_set_sensitive (priv->send_video, TRUE); - } + GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), + priv->sending_video && priv->video_input != NULL); + gtk_widget_set_sensitive (priv->camera_button, priv->video_input != NULL); + gtk_action_set_sensitive (priv->send_video, priv->video_input != NULL); gtk_action_set_sensitive (priv->redial, FALSE); gtk_widget_set_sensitive (priv->redial_button, FALSE); @@ -1391,8 +1427,10 @@ empathy_call_window_sink_added_cb (EmpathyCallHandler *handler, empathy_call_window_setup_video_preview (self); gtk_toggle_action_set_active ( - GTK_TOGGLE_ACTION (priv->show_preview),TRUE); - gtk_widget_show (priv->video_preview); + GTK_TOGGLE_ACTION (priv->show_preview), TRUE); + + if (priv->video_preview != NULL) + gtk_widget_show (priv->video_preview); gtk_widget_hide (priv->self_user_avatar_widget); } @@ -1411,45 +1449,6 @@ empathy_call_window_sink_added_cb (EmpathyCallHandler *handler, } -static gboolean -empathy_gst_bin_has_child (GstBin *bin, GstElement *element) -{ - GstIterator *it; - gboolean ret = FALSE; - GstElement *item; - - it = gst_bin_iterate_recurse (bin); - - for (;;) - { - switch (gst_iterator_next (it, (gpointer *)&item)) - { - case GST_ITERATOR_OK: - if (item == element) - { - gst_object_unref (GST_OBJECT (item)); - ret = TRUE; - goto out; - } - gst_object_unref (GST_OBJECT (item)); - break; - case GST_ITERATOR_RESYNC: - gst_iterator_resync (it); - break; - case GST_ITERATOR_ERROR: - g_assert_not_reached (); - /* fallthrough */ - case GST_ITERATOR_DONE: - goto out; - break; - } - } - gst_iterator_free (it); - -out: - return ret; -} - static void empathy_call_window_remove_video_input (EmpathyCallWindow *self) { @@ -1470,8 +1469,15 @@ empathy_call_window_remove_video_input (EmpathyCallWindow *self) priv->video_input = NULL; g_object_unref (priv->video_tee); priv->video_tee = NULL; + gtk_widget_destroy (priv->video_preview); + priv->video_preview = NULL; + + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), FALSE); + gtk_toggle_tool_button_set_active ( + GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), FALSE); + gtk_widget_set_sensitive (priv->camera_button, FALSE); + gtk_action_set_sensitive (priv->send_video, FALSE); - gtk_widget_hide (priv->video_preview); gtk_widget_show (priv->self_user_avatar_widget); } @@ -1510,19 +1516,21 @@ empathy_call_window_bus_message (GstBus *bus, GstMessage *message, case GST_MESSAGE_ERROR: { GError *error = NULL; + GstElement *gst_error; gchar *debug; gst_message_parse_error (message, &error, &debug); + gst_error = GST_ELEMENT (GST_MESSAGE_SRC (message)); g_message ("Element error: %s -- %s\n", error->message, debug); - if (priv->video_input != NULL && - empathy_gst_bin_has_child (GST_BIN (priv->video_input), - GST_ELEMENT (GST_MESSAGE_SRC (message)))) + if (g_str_has_prefix (gst_element_get_name (gst_error), + VIDEO_INPUT_ERROR_PREFIX)) { /* Remove the video input and continue */ - empathy_call_window_remove_video_input (self); - gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); + if (priv->video_input != NULL) + empathy_call_window_remove_video_input (self); + gst_element_set_state (priv->pipeline, GST_STATE_PLAYING); } else { @@ -1557,7 +1565,8 @@ empathy_call_window_update_avatars_visibility (EmpathyTpCall *call, if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (priv->show_preview))) { - if (empathy_tp_call_is_sending_video (call)) + if (priv->video_preview != NULL + && empathy_tp_call_is_sending_video (call)) { gtk_widget_hide (priv->self_user_avatar_widget); gtk_widget_show (priv->video_preview); -- cgit v1.2.3 From 1a2da857a423d46a4496064078c92fd3214ebf3e Mon Sep 17 00:00:00 2001 From: Jonathan Tellier Date: Fri, 12 Jun 2009 10:55:05 -0400 Subject: Corrected code style in empathy_call_window_setup_video_preview. The video preview is now shown no matter if we are sending video or not. --- src/empathy-call-window.c | 101 +++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index 4b4f53f85..749f9eb6a 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -611,41 +611,39 @@ static void empathy_call_window_setup_video_preview (EmpathyCallWindow *window) { EmpathyCallWindowPriv *priv = GET_PRIV (window); + GstElement *preview; + GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - if (priv->video_preview != NULL) - { - /* Since the video preview and the video tee are initialized and freed - at the same time, if one is initialized, then the other one should - be too. */ - g_assert (priv->video_tee != NULL); - return; - } + /* Since the video preview and the video tee are initialized and freed at + the same time, if one is initialized, then the other one should be too. */ + g_assert ((priv->video_preview != NULL && priv->video_tee != NULL) + || (priv->video_preview == NULL && priv->video_tee == NULL)); - GstElement *preview; - GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); + if (priv->video_preview != NULL) + return; - priv->video_tee = gst_element_factory_make ("tee", NULL); - gst_object_ref (priv->video_tee); - gst_object_sink (priv->video_tee); + priv->video_tee = gst_element_factory_make ("tee", NULL); + gst_object_ref (priv->video_tee); + gst_object_sink (priv->video_tee); - priv->video_preview = empathy_video_widget_new_with_size (bus, - SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); - g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); - gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), - priv->video_preview, TRUE, TRUE, 0); + priv->video_preview = empathy_video_widget_new_with_size (bus, + SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); + g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); + gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), + priv->video_preview, TRUE, TRUE, 0); - preview = empathy_video_widget_get_element ( - EMPATHY_VIDEO_WIDGET (priv->video_preview)); - gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input, - priv->video_tee, preview, NULL); - gst_element_link_many (priv->video_input, priv->video_tee, - preview, NULL); + preview = empathy_video_widget_get_element ( + EMPATHY_VIDEO_WIDGET (priv->video_preview)); + gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input, + priv->video_tee, preview, NULL); + gst_element_link_many (priv->video_input, priv->video_tee, + preview, NULL); - g_object_unref (bus); + g_object_unref (bus); - gst_element_set_state (preview, GST_STATE_PLAYING); - gst_element_set_state (priv->video_input, GST_STATE_PLAYING); - gst_element_set_state (priv->video_tee, GST_STATE_PLAYING); + gst_element_set_state (preview, GST_STATE_PLAYING); + gst_element_set_state (priv->video_input, GST_STATE_PLAYING); + gst_element_set_state (priv->video_tee, GST_STATE_PLAYING); } static void @@ -1547,26 +1545,13 @@ empathy_call_window_bus_message (GstBus *bus, GstMessage *message, } static void -empathy_call_window_update_avatars_visibility (EmpathyTpCall *call, - EmpathyCallWindow *window) +empathy_call_window_update_self_avatar_visibility (EmpathyCallWindow *window) { EmpathyCallWindowPriv *priv = GET_PRIV (window); - if (empathy_tp_call_is_receiving_video (call)) - { - gtk_widget_hide (priv->remote_user_avatar_widget); - gtk_widget_show (priv->video_output); - } - else - { - gtk_widget_hide (priv->video_output); - gtk_widget_show (priv->remote_user_avatar_widget); - } - if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (priv->show_preview))) { - if (priv->video_preview != NULL - && empathy_tp_call_is_sending_video (call)) + if (priv->video_preview != NULL) { gtk_widget_hide (priv->self_user_avatar_widget); gtk_widget_show (priv->video_preview); @@ -1581,6 +1566,26 @@ empathy_call_window_update_avatars_visibility (EmpathyTpCall *call, } } +static void +empathy_call_window_update_avatars_visibility (EmpathyTpCall *call, + EmpathyCallWindow *window) +{ + EmpathyCallWindowPriv *priv = GET_PRIV (window); + + if (empathy_tp_call_is_receiving_video (call)) + { + gtk_widget_hide (priv->remote_user_avatar_widget); + gtk_widget_show (priv->video_output); + } + else + { + gtk_widget_hide (priv->video_output); + gtk_widget_show (priv->remote_user_avatar_widget); + } + + empathy_call_window_update_self_avatar_visibility (window); +} + static void empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) { @@ -1812,9 +1817,15 @@ empathy_call_window_show_preview_toggled_cb (GtkToggleAction *toggle, show_preview_toggled = gtk_toggle_action_get_active (toggle); if (show_preview_toggled) - gtk_widget_show (priv->self_user_output_frame); + { + empathy_call_window_setup_video_preview (window); + gtk_widget_show (priv->self_user_output_frame); + empathy_call_window_update_self_avatar_visibility (window); + } else - gtk_widget_hide (priv->self_user_output_frame); + { + gtk_widget_hide (priv->self_user_output_frame); + } } static void -- cgit v1.2.3 From e5989d0face9edde213e0530ba6c886d61a1276f Mon Sep 17 00:00:00 2001 From: Jonathan Tellier Date: Fri, 12 Jun 2009 14:27:12 -0400 Subject: The video preview is no longer hidden when we get connected to a audio only call. --- src/empathy-call-window.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index 749f9eb6a..9946dd320 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -614,13 +614,16 @@ empathy_call_window_setup_video_preview (EmpathyCallWindow *window) GstElement *preview; GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - /* Since the video preview and the video tee are initialized and freed at - the same time, if one is initialized, then the other one should be too. */ - g_assert ((priv->video_preview != NULL && priv->video_tee != NULL) - || (priv->video_preview == NULL && priv->video_tee == NULL)); - if (priv->video_preview != NULL) - return; + { + /* Since the video preview and the video tee are initialized and freed + at the same time, if one is initialized, then the other one should + be too. */ + g_assert (priv->video_tee != NULL); + return; + } + + g_assert (priv->video_tee == NULL); priv->video_tee = gst_element_factory_make ("tee", NULL); gst_object_ref (priv->video_tee); @@ -909,19 +912,6 @@ empathy_call_window_setup_video_preview_visibility (EmpathyCallWindow *self, EmpathyCallWindowPriv *priv = GET_PRIV (self); gboolean initial_video = empathy_call_handler_has_initial_video (priv->handler); - if (initial_video) - { - empathy_call_window_setup_video_preview (self); - gtk_widget_hide (priv->self_user_avatar_widget); - - if (priv->video_preview != NULL) - gtk_widget_show (priv->video_preview); - } - else - { - gtk_widget_show (priv->self_user_avatar_widget); - } - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), initial_video); } @@ -1327,7 +1317,8 @@ empathy_call_window_connected (gpointer user_data) priv->sending_video = empathy_tp_call_is_sending_video (call); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), - priv->sending_video); + priv->sending_video + || gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (priv->show_preview))); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), priv->sending_video && priv->video_input != NULL); gtk_toggle_tool_button_set_active ( @@ -1904,6 +1895,9 @@ empathy_call_window_restart_call (EmpathyCallWindow *window) gtk_widget_show_all (priv->content_hbox); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->show_preview), + gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (priv->show_preview))); + empathy_call_window_status_message (window, CONNECTING_STATUS_TEXT); priv->call_started = TRUE; empathy_call_handler_start_call (priv->handler); -- cgit v1.2.3