#include <gtk/gtk.h>
#include <glib/gi18n.h>
+#include <telepathy-glib/util.h>
#include <telepathy-farsight/channel.h>
+#include <telepathy-glib/util.h>
#include <gst/farsight/fs-element-added-notifier.h>
#include <libempathy-gtk/empathy-ui-utils.h>
#include <libempathy-gtk/empathy-sound.h>
#include <libempathy-gtk/empathy-geometry.h>
+#include <libempathy-gtk/empathy-images.h>
#define DEBUG_FLAG EMPATHY_DEBUG_VOIP
#include <libempathy/empathy-debug.h>
/* TRUE if the call should be started when the pipeline is playing */
gboolean start_call_when_playing;
+ /* TRUE if we requested to set the pipeline in the playing state */
+ gboolean pipeline_playing;
};
#define GET_PRIV(o) \
gst_object_ref (priv->audio_input);
gst_object_sink (priv->audio_input);
- empathy_signal_connect_weak (priv->audio_input, "peak-level-changed",
+ tp_g_signal_connect_object (priv->audio_input, "peak-level-changed",
G_CALLBACK (empathy_call_window_audio_input_level_changed_cb),
- G_OBJECT (self));
+ self, 0);
}
static void
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);
+
+ if (!gst_bin_add (GST_BIN (priv->pipeline), priv->video_input))
+ {
+ g_warning ("Could not add video input to pipeline");
+ return;
+ }
+
+ if (!gst_bin_add (GST_BIN (priv->pipeline), priv->video_tee))
+ {
+ g_warning ("Could not add video tee to pipeline");
+ return;
+ }
+
+ if (!gst_bin_add (GST_BIN (priv->pipeline), preview))
+ {
+ g_warning ("Could not add video preview to pipeline");
+ return;
+ }
+
+ if (!gst_element_link (priv->video_input, priv->video_tee))
+ {
+ g_warning ("Could not link video input to video tee");
+ return;
+ }
+
+ if (!gst_element_link (priv->video_tee, preview))
+ {
+ g_warning ("Could not link video tee to video preview");
+ return;
+ }
}
static void
DEBUG ("Show self avatar");
if (priv->video_preview != NULL)
- gtk_widget_hide (priv->video_preview);
- play_camera (self, FALSE);
+ {
+ gtk_widget_hide (priv->video_preview);
+ play_camera (self, FALSE);
+ }
gtk_widget_show (priv->self_user_avatar_widget);
}
}
if (priv->camera_state == CAMERA_STATE_ON)
return;
+ if (priv->video_input == NULL)
+ {
+ DEBUG ("Can't enable camera, no input");
+ return;
+ }
+
+
DEBUG ("Enable camera");
empathy_call_window_set_send_video (self, TRUE);
g_assert (priv->pipeline == NULL);
priv->pipeline = gst_pipeline_new (NULL);
+ priv->pipeline_playing = FALSE;
+
bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
priv->bus_message_source_id = gst_bus_add_watch (bus,
empathy_call_window_bus_message, self);
if (pixbuf_avatar == NULL)
{
- pixbuf_avatar = empathy_pixbuf_from_icon_name_sized ("stock_person",
- size);
+ pixbuf_avatar = empathy_pixbuf_from_icon_name_sized (
+ EMPATHY_IMAGE_AVATAR_DEFAULT, size);
}
gtk_image_set_from_pixbuf (GTK_IMAGE (image_widget), pixbuf_avatar);
+
+ if (pixbuf_avatar != NULL)
+ g_object_unref (pixbuf_avatar);
}
static void
if (call != NULL)
{
- g_signal_handlers_disconnect_by_func (call,
- empathy_call_window_video_stream_changed_cb, object);
g_object_unref (call);
}
}
priv->handler = NULL;
+ if (priv->bus_message_source_id != 0)
+ {
+ g_source_remove (priv->bus_message_source_id);
+ priv->bus_message_source_id = 0;
+ }
+
if (priv->pipeline != NULL)
g_object_unref (priv->pipeline);
priv->pipeline = NULL;
g_object_unref (priv->video_tee);
priv->video_tee = NULL;
+ if (priv->liveadder != NULL)
+ gst_object_unref (priv->liveadder);
+ priv->liveadder = NULL;
+
if (priv->fsnotifier != NULL)
g_object_unref (priv->fsnotifier);
priv->fsnotifier = NULL;
g_object_unref (priv->ui_manager);
priv->ui_manager = NULL;
+ if (priv->fullscreen != NULL)
+ g_object_unref (priv->fullscreen);
+ priv->fullscreen = NULL;
+
if (priv->contact != NULL)
{
g_signal_handlers_disconnect_by_func (priv->contact,
priv->video_output_motion_handler_id = 0;
}
- if (priv->bus_message_source_id != 0)
- {
- g_source_remove (priv->bus_message_source_id);
- priv->bus_message_source_id = 0;
- }
-
/* free any data held directly by the object here */
g_mutex_free (priv->lock);
}
static gboolean
-empathy_call_window_disconnected (EmpathyCallWindow *self)
+empathy_call_window_disconnected (EmpathyCallWindow *self,
+ gboolean restart)
{
gboolean could_disconnect = FALSE;
EmpathyCallWindowPriv *priv = GET_PRIV (self);
g_mutex_unlock (priv->lock);
+ if (!restart)
+ /* We are about to destroy the window, no need to update it or create
+ * a video preview */
+ return TRUE;
+
empathy_call_window_status_message (self, _("Disconnected"));
gtk_action_set_sensitive (priv->redial, TRUE);
EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
EmpathyCallWindowPriv *priv = GET_PRIV (self);
- if (empathy_call_window_disconnected (self) && priv->call_state == REDIALING)
+ if (empathy_call_window_disconnected (self, TRUE) &&
+ priv->call_state == REDIALING)
empathy_call_window_restart_call (self);
}
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);
+ tp_g_signal_connect_object (call, "notify::video-stream",
+ G_CALLBACK (empathy_call_window_video_stream_changed_cb),
+ self, 0);
if (empathy_tp_call_has_dtmf (call))
gtk_widget_set_sensitive (priv->dtmf_panel, TRUE);
g_warning ("Could not link videp soure input pipeline");
break;
}
+ gst_object_unref (pad);
}
retval = TRUE;
EmpathyCallWindowPriv *priv = GET_PRIV (self);
GstElement *preview;
+ disable_camera (self);
+
DEBUG ("remove video input");
preview = empathy_video_widget_get_element (
EMPATHY_VIDEO_WIDGET (priv->video_preview));
gtk_widget_destroy (priv->video_preview);
priv->video_preview = NULL;
- gtk_toggle_tool_button_set_active (
- GTK_TOGGLE_TOOL_BUTTON (priv->tool_button_camera_on), FALSE);
gtk_widget_set_sensitive (priv->tool_button_camera_on, FALSE);
-
- gtk_widget_show (priv->self_user_avatar_widget);
+ gtk_widget_set_sensitive (priv->tool_button_camera_preview, FALSE);
}
static void
EmpathyCallWindowPriv *priv = GET_PRIV (self);
priv->call_started = TRUE;
- empathy_call_handler_start_call (priv->handler);
+ empathy_call_handler_start_call (priv->handler,
+ gtk_get_current_event_time ());
if (empathy_call_handler_has_initial_video (priv->handler))
{
if (newstate == GST_STATE_PAUSED)
{
gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
+ priv->pipeline_playing = TRUE;
if (priv->start_call_when_playing)
start_call (self);
}
else
{
- empathy_call_window_disconnected (self);
+ empathy_call_window_disconnected (self, TRUE);
}
g_error_free (error);
g_free (debug);
if (call == NULL)
return;
- empathy_signal_connect_weak (call, "audio-stream-error",
- G_CALLBACK (empathy_call_window_audio_stream_error), G_OBJECT (self));
- empathy_signal_connect_weak (call, "video-stream-error",
- G_CALLBACK (empathy_call_window_video_stream_error), G_OBJECT (self));
+ tp_g_signal_connect_object (call, "audio-stream-error",
+ G_CALLBACK (empathy_call_window_audio_stream_error), self, 0);
+ tp_g_signal_connect_object (call, "video-stream-error",
+ G_CALLBACK (empathy_call_window_video_stream_error), self, 0);
g_object_unref (call);
}
g_object_get (priv->handler, "tp-call", &call, NULL);
if (call != NULL)
{
- empathy_signal_connect_weak (call, "audio-stream-error",
- G_CALLBACK (empathy_call_window_audio_stream_error), G_OBJECT (window));
- empathy_signal_connect_weak (call, "video-stream-error",
- G_CALLBACK (empathy_call_window_video_stream_error), G_OBJECT (window));
+ tp_g_signal_connect_object (call, "audio-stream-error",
+ G_CALLBACK (empathy_call_window_audio_stream_error), window,
+ 0);
+ tp_g_signal_connect_object (call, "video-stream-error",
+ G_CALLBACK (empathy_call_window_video_stream_error), window,
+ 0);
g_object_unref (call);
}
empathy_call_handler_stop_call (priv->handler);
- if (empathy_call_window_disconnected (window))
+ if (empathy_call_window_disconnected (window, FALSE))
gtk_widget_destroy (GTK_WIDGET (window));
}
priv->outgoing = TRUE;
empathy_call_window_set_state_connecting (window);
- start_call (window);
+ if (priv->pipeline_playing)
+ start_call (window);
+ else
+ /* call will be started when the pipeline is ready */
+ priv->start_call_when_playing = TRUE;
+
+
empathy_call_window_setup_avatars (window, priv->handler);
gtk_action_set_sensitive (priv->redial, FALSE);