From f5e304dcc87509e2fb521969ef08c71cb1770758 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Tue, 3 Feb 2009 09:03:06 +0000 Subject: [PATCH] Move the TpFarsight code from TpCall to CallHandler Signed-off-by: Sjoerd Simons svn path=/trunk/; revision=2387 --- libempathy/empathy-call-handler.c | 319 ++++++++++++++++++++++++++++-- libempathy/empathy-call-handler.h | 6 + libempathy/empathy-tp-call.c | 141 +------------ libempathy/empathy-tp-call.h | 3 +- 4 files changed, 309 insertions(+), 160 deletions(-) diff --git a/libempathy/empathy-call-handler.c b/libempathy/empathy-call-handler.c index 2c08a874..1fba9317 100644 --- a/libempathy/empathy-call-handler.c +++ b/libempathy/empathy-call-handler.c @@ -22,36 +22,54 @@ #include #include +#include + +#include +#include + #include "empathy-call-handler.h" +#include "empathy-dispatcher.h" +#include "empathy-marshal.h" G_DEFINE_TYPE(EmpathyCallHandler, empathy_call_handler, G_TYPE_OBJECT) -#if 0 /* signal enum */ enum { - LAST_SIGNAL + CONFERENCE_ADDED, + SRC_PAD_ADDED, + SINK_PAD_ADDED, + LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {0}; -#endif + +enum { + PROP_TP_CALL = 1, + PROP_GST_BUS, + PROP_CONTACT +}; /* private structure */ -typedef struct _EmpathyCallHandlerPrivate EmpathyCallHandlerPrivate; +typedef struct _EmpathyCallHandlerPriv EmpathyCallHandlerPriv; -struct _EmpathyCallHandlerPrivate +struct _EmpathyCallHandlerPriv { gboolean dispose_has_run; + EmpathyTpCall *call; + EmpathyContact *contact; + TfChannel *tfchannel; + GstBus *bus; }; -#define EMPATHY_CALL_HANDLER_GET_PRIVATE(o) \ +#define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_CALL_HANDLER,\ - EmpathyCallHandlerPrivate)) + EmpathyCallHandlerPriv)) static void empathy_call_handler_init (EmpathyCallHandler *obj) { - //EmpathyCallHandlerPrivate *priv = EMPATHY_CALL_HANDLER_GET_PRIVATE (obj); + //EmpathyCallHandlerPriv *priv = GET_PRIV (obj); /* allocate any data required by the object here */ } @@ -60,32 +78,125 @@ static void empathy_call_handler_dispose (GObject *object); static void empathy_call_handler_finalize (GObject *object); static void -empathy_call_handler_class_init ( - EmpathyCallHandlerClass *empathy_call_handler_class) +empathy_call_handler_set_property (GObject *object, + guint property_id, const GValue *value, GParamSpec *pspec) +{ + EmpathyCallHandlerPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_CONTACT: + priv->contact = g_value_dup_object (value); + break; + case PROP_TP_CALL: + priv->call = g_value_dup_object (value); + break; + case PROP_GST_BUS: + priv->bus = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +empathy_call_handler_get_property (GObject *object, + guint property_id, GValue *value, GParamSpec *pspec) +{ + EmpathyCallHandlerPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_CONTACT: + g_value_set_object (value, priv->contact); + break; + case PROP_TP_CALL: + g_value_set_object (value, priv->call); + break; + case PROP_GST_BUS: + g_value_set_object (value, priv->bus); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + + +static void +empathy_call_handler_class_init (EmpathyCallHandlerClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (empathy_call_handler_class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GParamSpec *param_spec; - g_type_class_add_private (empathy_call_handler_class, - sizeof (EmpathyCallHandlerPrivate)); + g_type_class_add_private (klass, sizeof (EmpathyCallHandlerPriv)); + object_class->set_property = empathy_call_handler_set_property; + object_class->get_property = empathy_call_handler_get_property; object_class->dispose = empathy_call_handler_dispose; object_class->finalize = empathy_call_handler_finalize; + param_spec = g_param_spec_object ("contact", + "contact", "The remote contact", + EMPATHY_TYPE_CONTACT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_CONTACT, param_spec); + + param_spec = g_param_spec_object ("gst-bus", + "gst-bus", "The gstreamer bus", + GST_TYPE_BUS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_GST_BUS, param_spec); + + param_spec = g_param_spec_object ("tp-call", + "tp-call", "The calls channel wrapper", + EMPATHY_TYPE_CONTACT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_TP_CALL, param_spec); + + signals[CONFERENCE_ADDED] = + g_signal_new ("conference-added", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, FS_TYPE_CONFERENCE); + + signals[SRC_PAD_ADDED] = + g_signal_new ("src-pad-added", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + _empathy_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, + 2, GST_TYPE_PAD, G_TYPE_UINT); + + signals[SINK_PAD_ADDED] = + g_signal_new ("sink-pad-added", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + _empathy_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, + 2, GST_TYPE_PAD, G_TYPE_UINT); } void empathy_call_handler_dispose (GObject *object) { EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (object); - EmpathyCallHandlerPrivate *priv = EMPATHY_CALL_HANDLER_GET_PRIVATE (self); + EmpathyCallHandlerPriv *priv = GET_PRIV (self); if (priv->dispose_has_run) return; priv->dispose_has_run = TRUE; - /* release any references held by the object here */ + if (priv->contact != NULL) + g_object_unref (priv->contact); + + /* FIXME close the call ? */ + if (priv->call != NULL) + g_object_unref (priv->call); + + priv->call = NULL; + + /* release any references held by the object here */ if (G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose) G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose (object); } @@ -94,22 +205,192 @@ void empathy_call_handler_finalize (GObject *object) { //EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (object); - //EmpathyCallHandlerPrivate *priv = EMPATHY_CALL_HANDLER_GET_PRIVATE (self); + //EmpathyCallHandlerPriv *priv = GET_PRIV (self); /* free any data held directly by the object here */ G_OBJECT_CLASS (empathy_call_handler_parent_class)->finalize (object); } - EmpathyCallHandler * empathy_call_handler_new_for_contact (EmpathyContact *contact) { - return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER, NULL)); + return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER, + "contact", contact, NULL)); } EmpathyCallHandler * empathy_call_handler_new_for_channel (EmpathyTpCall *call) { - return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER, NULL)); + return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER, + "tp-call", call, NULL)); +} + +static gboolean +empathy_call_handler_pipeline_bus_watch (GstBus *bus, GstMessage *message, + gpointer user_data) +{ + EmpathyCallHandler *handler = EMPATHY_CALL_HANDLER (user_data); + EmpathyCallHandlerPriv *priv = GET_PRIV (handler); + + g_assert (priv->tfchannel != NULL); + + tf_channel_bus_message (priv->tfchannel, message); + + return TRUE; +} + +static void +empathy_call_handler_tf_channel_session_created_cb (TfChannel *tfchannel, + FsConference *conference, FsParticipant *participant, + EmpathyCallHandler *self) +{ + EmpathyCallHandlerPriv *priv = GET_PRIV (self); + + //gst_bus_enable_essage_emission (priv->bus); + + gst_bus_add_watch (priv->bus, empathy_call_handler_pipeline_bus_watch, self); + + g_signal_emit (G_OBJECT (self), signals[CONFERENCE_ADDED], 0, + GST_ELEMENT (conference)); +} + +static void +empathy_call_handler_tf_stream_src_pad_added_cb (TfStream *stream, + GstPad *pad, FsCodec *codec, EmpathyCallHandler *handler) +{ + guint media_type; + + g_object_get (stream, "media-type", &media_type, NULL); + + g_signal_emit (G_OBJECT (handler), signals[SRC_PAD_ADDED], 0, + pad, media_type); +} + + +static gboolean +empathy_call_handler_tf_stream_request_resource_cb (TfStream *stream, + guint direction, EmpathyTpCall *call) +{ + return TRUE; +} + +static void +empathy_call_handler_tf_channel_stream_created_cb (TfChannel *tfchannel, + TfStream *stream, EmpathyCallHandler *handler) +{ + guint media_type; + GstPad *spad; + + g_signal_connect (stream, "src-pad-added", + G_CALLBACK (empathy_call_handler_tf_stream_src_pad_added_cb), handler); + g_signal_connect (stream, "request-resource", + G_CALLBACK (empathy_call_handler_tf_stream_request_resource_cb), + handler); + + g_object_get (stream, "media-type", &media_type, + "sink-pad", &spad, NULL); + + g_signal_emit (G_OBJECT (handler), signals[SINK_PAD_ADDED], 0, + spad, media_type); + + gst_object_unref (spad); +} + + +static void +empathy_call_handler_request_cb (EmpathyDispatchOperation *operation, + const GError *error, gpointer user_data) +{ + EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (user_data); + EmpathyCallHandlerPriv *priv = GET_PRIV (self); + + if (error != NULL) + return; + + priv->call = EMPATHY_TP_CALL ( + empathy_dispatch_operation_get_channel_wrapper (operation)); + g_object_ref (priv->call); + + priv->tfchannel = tf_channel_new ( + empathy_dispatch_operation_get_channel (operation)); + + /* Set up the telepathy farsight channel */ + g_signal_connect (priv->tfchannel, "session-created", + G_CALLBACK (empathy_call_handler_tf_channel_session_created_cb), self); + g_signal_connect (priv->tfchannel, "stream-created", + G_CALLBACK (empathy_call_handler_tf_channel_stream_created_cb), self); + + empathy_tp_call_to (priv->call, priv->contact); + + empathy_dispatch_operation_claim (operation); +} + +static void +empathy_call_handler_contact_ready_cb (EmpathyContact *contact, + const GError *error, gpointer user_data, GObject *object) +{ + EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (object); + EmpathyCallHandlerPriv *priv = GET_PRIV (self); + EmpathyDispatcher *dispatcher; + McAccount *account; + GStrv allowed; + GValue *value; + GHashTable *request = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, + (GDestroyNotify) tp_g_value_slice_free); + + g_assert (priv->contact != NULL); + + dispatcher = empathy_dispatcher_dup_singleton (); + account = empathy_contact_get_account (priv->contact); + allowed = empathy_dispatcher_find_channel_class (dispatcher, account, + TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, TP_HANDLE_TYPE_CONTACT); + + if (!tp_strv_contains ((const gchar * const *)allowed, + TP_IFACE_CHANNEL ".TargetHandle")) + g_assert_not_reached (); + + /* org.freedesktop.Telepathy.Channel.ChannelType */ + value = tp_g_value_slice_new (G_TYPE_STRING); + g_value_set_string (value, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA); + g_hash_table_insert (request, TP_IFACE_CHANNEL ".ChannelType", value); + + /* org.freedesktop.Telepathy.Channel.TargetHandleType */ + value = tp_g_value_slice_new (G_TYPE_UINT); + g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT); + g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandleType", value); + + /* org.freedesktop.Telepathy.Channel.TargetHandle*/ + value = tp_g_value_slice_new (G_TYPE_UINT); + g_value_set_uint (value, empathy_contact_get_handle (priv->contact)); + g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value); + + empathy_dispatcher_create_channel (dispatcher, account, + request, empathy_call_handler_request_cb, self); + + g_object_unref (dispatcher); +} + +void +empathy_call_handler_start_call (EmpathyCallHandler *handler) +{ + + EmpathyCallHandlerPriv *priv = GET_PRIV (handler); + + g_assert (priv->contact != NULL); + + empathy_contact_call_when_ready (priv->contact, + EMPATHY_CONTACT_READY_ID, + empathy_call_handler_contact_ready_cb, NULL, NULL, G_OBJECT (handler)); +} + +void +empathy_call_handler_set_bus (EmpathyCallHandler *handler, GstBus *bus) +{ + EmpathyCallHandlerPriv *priv = GET_PRIV (handler); + + g_assert (priv->bus == NULL); + + priv->bus = g_object_ref (bus); } + diff --git a/libempathy/empathy-call-handler.h b/libempathy/empathy-call-handler.h index c095e513..00243b69 100644 --- a/libempathy/empathy-call-handler.h +++ b/libempathy/empathy-call-handler.h @@ -23,6 +23,8 @@ #include +#include + #include #include @@ -64,6 +66,10 @@ EmpathyCallHandler * empathy_call_handler_new_for_contact ( EmpathyCallHandler * empathy_call_handler_new_for_channel ( EmpathyTpCall *call); +void empathy_call_handler_start_call (EmpathyCallHandler *handler); +void empathy_call_handler_set_bus (EmpathyCallHandler *handler, + GstBus *bus); + G_END_DECLS #endif /* #ifndef __EMPATHY_CALL_HANDLER_H__*/ diff --git a/libempathy/empathy-tp-call.c b/libempathy/empathy-tp-call.c index 41f573fd..a3c31b61 100644 --- a/libempathy/empathy-tp-call.c +++ b/libempathy/empathy-tp-call.c @@ -25,10 +25,6 @@ #include #include #include -#include -#include - -#include #include "empathy-tp-call.h" #include "empathy-contact-factory.h" @@ -42,13 +38,10 @@ typedef struct { gboolean dispose_has_run; TpChannel *channel; - TfChannel *tfchannel; EmpathyContact *contact; gboolean is_incoming; guint status; - GstElement *pipeline; - EmpathyTpCallStream *audio; EmpathyTpCallStream *video; } EmpathyTpCallPriv; @@ -342,7 +335,7 @@ empathy_tp_call_to (EmpathyTpCall *call, EmpathyContact *contact) g_object_notify (G_OBJECT (call), "contact"); g_object_notify (G_OBJECT (call), "status"); tp_call_request_streams_for_capabilities (call, - EMPATHY_CAPABILITIES_AUDIO); + EMPATHY_CAPABILITIES_VIDEO | EMPATHY_CAPABILITIES_AUDIO); } static void @@ -386,117 +379,6 @@ tp_call_close_channel (EmpathyTpCall *call) g_object_notify (G_OBJECT (call), "status"); } -static gboolean -tp_call_pipeline_bus_watch (GstBus *bus, GstMessage *message, - gpointer user_data) -{ - EmpathyTpCall *call = EMPATHY_TP_CALL (user_data); - EmpathyTpCallPriv *priv = GET_PRIV (call); - - g_assert (priv->tfchannel != NULL); - - tf_channel_bus_message (priv->tfchannel, message); - - return TRUE; -} - -static void -tp_call_tf_channel_session_created_cb (TfChannel *tfchannel, - FsConference *conference, FsParticipant *participant, EmpathyTpCall *call) -{ - EmpathyTpCallPriv *priv = GET_PRIV (call); - GstBus *bus; - - g_assert (priv->pipeline == NULL); - - priv->pipeline = gst_pipeline_new ("call-pipeline"); - - bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - gst_bus_add_watch (bus, tp_call_pipeline_bus_watch, call); - gst_object_unref (bus); - - gst_bin_add ( GST_BIN (priv->pipeline), GST_ELEMENT (conference)); - gst_element_set_state ( GST_ELEMENT(priv->pipeline), GST_STATE_PLAYING); -} - -static void -tp_call_tf_stream_src_pad_added_cb (TfStream *stream, GstPad *pad, - FsCodec *codec, EmpathyTpCall *call) -{ - EmpathyTpCallPriv *priv = GET_PRIV (call); - guint media_type; - GstElement *sink; - GstPad *spad; - - g_object_get (stream, "media-type", &media_type, NULL); - - switch (media_type) - { - case TP_MEDIA_STREAM_TYPE_AUDIO: - sink = gst_element_factory_make ("gconfaudiosink", NULL); - break; - case TP_MEDIA_STREAM_TYPE_VIDEO: - sink = gst_element_factory_make ("gconfvideosink", NULL); - break; - default: - g_assert_not_reached(); - } - - gst_bin_add ( GST_BIN (priv->pipeline), sink); - gst_element_set_state (sink, GST_STATE_PLAYING); - - spad = gst_element_get_static_pad (sink, "sink"); - gst_pad_link (pad, spad); - gst_object_unref (spad); -} - - -static gboolean -tp_call_tf_stream_request_resource_cb (TfStream *stream, - guint direction, EmpathyTpCall *call) -{ - return TRUE; -} - -static void -tp_call_tf_channel_stream_created_cb (TfChannel *tfchannel, TfStream *stream, - EmpathyTpCall *call) -{ - EmpathyTpCallPriv *priv = GET_PRIV (call); - guint media_type; - GstElement *src; - GstPad *pad, *spad; - - g_signal_connect (stream, "src-pad-added", - G_CALLBACK (tp_call_tf_stream_src_pad_added_cb), call); - g_signal_connect (stream, "request-resource", - G_CALLBACK (tp_call_tf_stream_request_resource_cb), call); - - - g_object_get (stream, "media-type", &media_type, - "sink-pad", &spad, NULL); - - switch (media_type) - { - case TP_MEDIA_STREAM_TYPE_AUDIO: - src = gst_element_factory_make ("gconfaudiosrc", NULL); - break; - case TP_MEDIA_STREAM_TYPE_VIDEO: - src = gst_element_factory_make ("gconfvideosrc", NULL); - break; - default: - g_assert_not_reached(); - } - - gst_bin_add (GST_BIN (priv->pipeline), src); - - pad = gst_element_get_static_pad (src, "src"); - gst_pad_link (pad, spad); - gst_object_unref (spad); - - gst_element_set_state (src, GST_STATE_PLAYING); -} - static GObject * tp_call_constructor (GType type, guint n_construct_params, @@ -531,14 +413,6 @@ tp_call_constructor (GType type, g_signal_connect (priv->channel, "group-members-changed", G_CALLBACK (tp_call_members_changed_cb), call); - - /* Set up the telepathy farsight channel */ - priv->tfchannel = tf_channel_new (priv->channel); - g_signal_connect (priv->tfchannel, "session-created", - G_CALLBACK (tp_call_tf_channel_session_created_cb), call); - g_signal_connect (priv->tfchannel, "stream-created", - G_CALLBACK (tp_call_tf_channel_stream_created_cb), call); - return object; } static void @@ -565,19 +439,6 @@ tp_call_dispose (GObject *object) priv->channel = NULL; } - if (priv->pipeline != NULL) - { - gst_element_set_state (priv->pipeline, GST_STATE_NULL); - gst_object_unref (priv->pipeline); - priv->pipeline = NULL; - } - - if (priv->tfchannel != NULL) - { - g_object_unref (priv->tfchannel); - priv->tfchannel = NULL; - } - if (priv->contact != NULL) g_object_unref (priv->contact); diff --git a/libempathy/empathy-tp-call.h b/libempathy/empathy-tp-call.h index 5724963f..599bfac1 100644 --- a/libempathy/empathy-tp-call.h +++ b/libempathy/empathy-tp-call.h @@ -40,7 +40,8 @@ G_BEGIN_DECLS EMPATHY_TYPE_TP_CALL)) #define EMPATHY_IS_TP_CALL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ EMPATHY_TYPE_TP_CALL)) -#define EMPATHY_TP_CALL_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), \ +#define EMPATHY_TP_CALL_GET_CLASS(object) \ + (G_TYPE_INSTANCE_GET_CLASS ((object), \ EMPATHY_TYPE_TP_CALL, EmpathyTpCallClass)) typedef struct _EmpathyTpCall EmpathyTpCall; -- 2.39.2