2 * empathy-call-handler.c - Source for EmpathyCallHandler
3 * Copyright (C) 2008-2009 Collabora Ltd.
4 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <telepathy-glib/util.h>
26 #include <telepathy-glib/interfaces.h>
28 #include <telepathy-farsight/channel.h>
29 #include <telepathy-farsight/stream.h>
31 #include "empathy-call-handler.h"
32 #include "empathy-call-factory.h"
33 #include "empathy-dispatcher.h"
34 #include "empathy-marshal.h"
35 #include "empathy-utils.h"
37 G_DEFINE_TYPE(EmpathyCallHandler, empathy_call_handler, G_TYPE_OBJECT)
51 static guint signals[LAST_SIGNAL] = {0};
59 PROP_SEND_AUDIO_CODEC,
60 PROP_SEND_VIDEO_CODEC,
61 PROP_RECV_AUDIO_CODECS,
62 PROP_RECV_VIDEO_CODECS,
63 PROP_AUDIO_REMOTE_CANDIDATE,
64 PROP_VIDEO_REMOTE_CANDIDATE,
65 PROP_AUDIO_LOCAL_CANDIDATE,
66 PROP_VIDEO_LOCAL_CANDIDATE,
69 /* private structure */
72 gboolean dispose_has_run;
74 EmpathyContact *contact;
76 gboolean initial_audio;
77 gboolean initial_video;
79 FsCodec *send_audio_codec;
80 FsCodec *send_video_codec;
81 GList *recv_audio_codecs;
82 GList *recv_video_codecs;
83 FsCandidate *audio_remote_candidate;
84 FsCandidate *video_remote_candidate;
85 FsCandidate *audio_local_candidate;
86 FsCandidate *video_local_candidate;
87 } EmpathyCallHandlerPriv;
89 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyCallHandler)
92 empathy_call_handler_dispose (GObject *object)
94 EmpathyCallHandlerPriv *priv = GET_PRIV (object);
96 if (priv->dispose_has_run)
99 priv->dispose_has_run = TRUE;
101 if (priv->contact != NULL)
102 g_object_unref (priv->contact);
104 priv->contact = NULL;
106 if (priv->tfchannel != NULL)
107 g_object_unref (priv->tfchannel);
109 priv->tfchannel = NULL;
111 if (priv->call != NULL)
113 empathy_tp_call_close (priv->call);
114 g_object_unref (priv->call);
119 /* release any references held by the object here */
120 if (G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose)
121 G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose (object);
125 empathy_call_handler_finalize (GObject *object)
127 EmpathyCallHandlerPriv *priv = GET_PRIV (object);
129 fs_codec_destroy (priv->send_audio_codec);
130 fs_codec_destroy (priv->send_video_codec);
131 fs_codec_list_destroy (priv->recv_audio_codecs);
132 fs_codec_list_destroy (priv->recv_video_codecs);
133 fs_candidate_destroy (priv->audio_remote_candidate);
134 fs_candidate_destroy (priv->video_remote_candidate);
135 fs_candidate_destroy (priv->audio_local_candidate);
136 fs_candidate_destroy (priv->video_local_candidate);
138 if (G_OBJECT_CLASS (empathy_call_handler_parent_class)->finalize)
139 G_OBJECT_CLASS (empathy_call_handler_parent_class)->finalize (object);
143 empathy_call_handler_init (EmpathyCallHandler *obj)
145 EmpathyCallHandlerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (obj,
146 EMPATHY_TYPE_CALL_HANDLER, EmpathyCallHandlerPriv);
152 empathy_call_handler_constructed (GObject *object)
154 EmpathyCallHandlerPriv *priv = GET_PRIV (object);
156 if (priv->contact == NULL)
158 g_object_get (priv->call, "contact", &(priv->contact), NULL);
163 empathy_call_handler_set_property (GObject *object,
164 guint property_id, const GValue *value, GParamSpec *pspec)
166 EmpathyCallHandlerPriv *priv = GET_PRIV (object);
171 priv->contact = g_value_dup_object (value);
174 priv->call = g_value_dup_object (value);
176 case PROP_INITIAL_AUDIO:
177 priv->initial_audio = g_value_get_boolean (value);
179 case PROP_INITIAL_VIDEO:
180 priv->initial_video = g_value_get_boolean (value);
183 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
188 empathy_call_handler_get_property (GObject *object,
189 guint property_id, GValue *value, GParamSpec *pspec)
191 EmpathyCallHandlerPriv *priv = GET_PRIV (object);
196 g_value_set_object (value, priv->contact);
199 g_value_set_object (value, priv->call);
201 case PROP_INITIAL_AUDIO:
202 g_value_set_boolean (value, priv->initial_audio);
204 case PROP_INITIAL_VIDEO:
205 g_value_set_boolean (value, priv->initial_video);
207 case PROP_SEND_AUDIO_CODEC:
208 g_value_set_boxed (value, priv->send_audio_codec);
210 case PROP_SEND_VIDEO_CODEC:
211 g_value_set_boxed (value, priv->send_video_codec);
213 case PROP_RECV_AUDIO_CODECS:
214 g_value_set_boxed (value, priv->recv_audio_codecs);
216 case PROP_RECV_VIDEO_CODECS:
217 g_value_set_boxed (value, priv->recv_video_codecs);
219 case PROP_AUDIO_REMOTE_CANDIDATE:
220 g_value_set_boxed (value, priv->audio_remote_candidate);
222 case PROP_VIDEO_REMOTE_CANDIDATE:
223 g_value_set_boxed (value, priv->video_remote_candidate);
225 case PROP_AUDIO_LOCAL_CANDIDATE:
226 g_value_set_boxed (value, priv->audio_local_candidate);
228 case PROP_VIDEO_LOCAL_CANDIDATE:
229 g_value_set_boxed (value, priv->video_local_candidate);
232 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
238 empathy_call_handler_class_init (EmpathyCallHandlerClass *klass)
240 GObjectClass *object_class = G_OBJECT_CLASS (klass);
241 GParamSpec *param_spec;
243 g_type_class_add_private (klass, sizeof (EmpathyCallHandlerPriv));
245 object_class->constructed = empathy_call_handler_constructed;
246 object_class->set_property = empathy_call_handler_set_property;
247 object_class->get_property = empathy_call_handler_get_property;
248 object_class->dispose = empathy_call_handler_dispose;
249 object_class->finalize = empathy_call_handler_finalize;
251 param_spec = g_param_spec_object ("contact",
252 "contact", "The remote contact",
253 EMPATHY_TYPE_CONTACT,
254 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
255 g_object_class_install_property (object_class, PROP_CONTACT, param_spec);
257 param_spec = g_param_spec_object ("tp-call",
258 "tp-call", "The calls channel wrapper",
259 EMPATHY_TYPE_TP_CALL,
260 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
261 g_object_class_install_property (object_class, PROP_TP_CALL, param_spec);
263 param_spec = g_param_spec_boolean ("initial-audio",
264 "initial-audio", "Whether the call should start with audio",
266 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
267 g_object_class_install_property (object_class, PROP_INITIAL_AUDIO,
270 param_spec = g_param_spec_boolean ("initial-video",
271 "initial-video", "Whether the call should start with video",
273 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
274 g_object_class_install_property (object_class, PROP_INITIAL_VIDEO,
277 param_spec = g_param_spec_boxed ("send-audio-codec",
278 "send audio codec", "Codec used to encode the outgoing video stream",
280 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
281 g_object_class_install_property (object_class, PROP_SEND_AUDIO_CODEC,
284 param_spec = g_param_spec_boxed ("send-video-codec",
285 "send video codec", "Codec used to encode the outgoing video stream",
287 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
288 g_object_class_install_property (object_class, PROP_SEND_VIDEO_CODEC,
291 param_spec = g_param_spec_boxed ("recv-audio-codecs",
292 "recvs audio codec", "Codecs used to decode the incoming audio stream",
294 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
295 g_object_class_install_property (object_class, PROP_RECV_AUDIO_CODECS,
298 param_spec = g_param_spec_boxed ("recv-video-codecs",
299 "recvs video codec", "Codecs used to decode the incoming video stream",
301 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
302 g_object_class_install_property (object_class, PROP_RECV_VIDEO_CODECS,
305 param_spec = g_param_spec_boxed ("audio-remote-candidate",
306 "audio remote candidate",
307 "Remote candidate used for the audio stream",
309 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
310 g_object_class_install_property (object_class,
311 PROP_AUDIO_REMOTE_CANDIDATE, param_spec);
313 param_spec = g_param_spec_boxed ("video-remote-candidate",
314 "video remote candidate",
315 "Remote candidate used for the video stream",
317 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
318 g_object_class_install_property (object_class,
319 PROP_VIDEO_REMOTE_CANDIDATE, param_spec);
321 param_spec = g_param_spec_boxed ("audio-local-candidate",
322 "audio local candidate",
323 "Local candidate used for the audio stream",
325 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
326 g_object_class_install_property (object_class,
327 PROP_AUDIO_REMOTE_CANDIDATE, param_spec);
329 param_spec = g_param_spec_boxed ("video-local-candidate",
330 "video local candidate",
331 "Local candidate used for the video stream",
333 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
334 g_object_class_install_property (object_class,
335 PROP_VIDEO_REMOTE_CANDIDATE, param_spec);
337 signals[CONFERENCE_ADDED] =
338 g_signal_new ("conference-added", G_TYPE_FROM_CLASS (klass),
339 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
340 g_cclosure_marshal_VOID__OBJECT,
342 1, FS_TYPE_CONFERENCE);
344 signals[SRC_PAD_ADDED] =
345 g_signal_new ("src-pad-added", G_TYPE_FROM_CLASS (klass),
346 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
347 _empathy_marshal_BOOLEAN__OBJECT_UINT,
349 2, GST_TYPE_PAD, G_TYPE_UINT);
351 signals[SINK_PAD_ADDED] =
352 g_signal_new ("sink-pad-added", G_TYPE_FROM_CLASS (klass),
353 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
354 _empathy_marshal_BOOLEAN__OBJECT_UINT,
356 2, GST_TYPE_PAD, G_TYPE_UINT);
358 signals[REQUEST_RESOURCE] =
359 g_signal_new ("request-resource", G_TYPE_FROM_CLASS (klass),
360 G_SIGNAL_RUN_LAST, 0,
361 g_signal_accumulator_true_handled, NULL,
362 _empathy_marshal_BOOLEAN__UINT_UINT,
363 G_TYPE_BOOLEAN, 2, G_TYPE_UINT, G_TYPE_UINT);
366 g_signal_new ("closed", G_TYPE_FROM_CLASS (klass),
367 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
368 g_cclosure_marshal_VOID__VOID,
372 signals[STREAM_CLOSED] =
373 g_signal_new ("stream-closed", G_TYPE_FROM_CLASS (klass),
374 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
375 g_cclosure_marshal_VOID__OBJECT,
376 G_TYPE_NONE, 1, TF_TYPE_STREAM);
378 signals[CANDIDATES_CHANGED] =
379 g_signal_new ("candidates-changed", G_TYPE_FROM_CLASS (klass),
380 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
381 g_cclosure_marshal_VOID__UINT,
382 G_TYPE_NONE, 1, G_TYPE_UINT);
386 * empathy_call_handler_new_for_contact:
387 * @contact: an #EmpathyContact
389 * Creates a new #EmpathyCallHandler with contact @contact.
391 * Return value: a new #EmpathyCallHandler
394 empathy_call_handler_new_for_contact (EmpathyContact *contact)
396 return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER,
397 "contact", contact, NULL));
401 empathy_call_handler_new_for_channel (EmpathyTpCall *call)
403 return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER,
405 "initial-video", empathy_tp_call_is_receiving_video (call),
410 update_sending_codec (EmpathyCallHandler *self,
414 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
417 if (codec == NULL || session == NULL)
420 g_object_get (session, "media-type", &type, NULL);
422 if (type == FS_MEDIA_TYPE_AUDIO)
424 priv->send_audio_codec = fs_codec_copy (codec);
425 g_object_notify (G_OBJECT (self), "send-audio-codec");
427 else if (type == FS_MEDIA_TYPE_VIDEO)
429 priv->send_video_codec = fs_codec_copy (codec);
430 g_object_notify (G_OBJECT (self), "send-video-codec");
435 update_receiving_codec (EmpathyCallHandler *self,
439 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
443 if (codecs == NULL || stream == NULL)
446 g_object_get (stream, "session", &session, NULL);
450 g_object_get (session, "media-type", &type, NULL);
452 if (type == FS_MEDIA_TYPE_AUDIO)
454 priv->recv_audio_codecs = fs_codec_list_copy (codecs);
455 g_object_notify (G_OBJECT (self), "recv-audio-codecs");
457 else if (type == FS_MEDIA_TYPE_VIDEO)
459 priv->recv_video_codecs = fs_codec_list_copy (codecs);
460 g_object_notify (G_OBJECT (self), "recv-video-codecs");
463 g_object_unref (session);
467 update_candidates (EmpathyCallHandler *self,
468 FsCandidate *remote_candidate,
469 FsCandidate *local_candidate,
472 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
479 g_object_get (stream, "session", &session, NULL);
483 g_object_get (session, "media-type", &type, NULL);
485 if (type == FS_MEDIA_TYPE_AUDIO)
487 if (remote_candidate != NULL)
489 fs_candidate_destroy (priv->audio_remote_candidate);
490 priv->audio_remote_candidate = fs_candidate_copy (remote_candidate);
491 g_object_notify (G_OBJECT (self), "audio-remote-candidate");
494 if (local_candidate != NULL)
496 fs_candidate_destroy (priv->audio_local_candidate);
497 priv->audio_local_candidate = fs_candidate_copy (local_candidate);
498 g_object_notify (G_OBJECT (self), "audio-local-candidate");
501 g_signal_emit (G_OBJECT (self), signals[CANDIDATES_CHANGED], 0,
502 FS_MEDIA_TYPE_AUDIO);
504 else if (type == FS_MEDIA_TYPE_VIDEO)
506 if (remote_candidate != NULL)
508 fs_candidate_destroy (priv->video_remote_candidate);
509 priv->video_remote_candidate = fs_candidate_copy (remote_candidate);
510 g_object_notify (G_OBJECT (self), "video-remote-candidate");
513 if (local_candidate != NULL)
515 fs_candidate_destroy (priv->video_local_candidate);
516 priv->video_local_candidate = fs_candidate_copy (local_candidate);
517 g_object_notify (G_OBJECT (self), "video-local-candidate");
520 g_signal_emit (G_OBJECT (self), signals[CANDIDATES_CHANGED], 0,
521 FS_MEDIA_TYPE_VIDEO);
524 g_object_unref (session);
528 empathy_call_handler_bus_message (EmpathyCallHandler *handler,
529 GstBus *bus, GstMessage *message)
531 EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
532 const GstStructure *s = gst_message_get_structure (message);
534 if (priv->tfchannel == NULL)
538 gst_structure_has_name (s, "farsight-send-codec-changed"))
544 val = gst_structure_get_value (s, "codec");
545 codec = g_value_get_boxed (val);
547 val = gst_structure_get_value (s, "session");
548 session = g_value_get_object (val);
550 update_sending_codec (handler, codec, session);
552 else if (s != NULL &&
553 gst_structure_has_name (s, "farsight-recv-codecs-changed"))
559 val = gst_structure_get_value (s, "codecs");
560 codecs = g_value_get_boxed (val);
562 val = gst_structure_get_value (s, "stream");
563 stream = g_value_get_object (val);
565 update_receiving_codec (handler, codecs, stream);
567 else if (s != NULL &&
568 gst_structure_has_name (s, "farsight-new-active-candidate-pair"))
571 FsCandidate *remote_candidate, *local_candidate;
574 val = gst_structure_get_value (s, "remote-candidate");
575 remote_candidate = g_value_get_boxed (val);
577 val = gst_structure_get_value (s, "local-candidate");
578 local_candidate = g_value_get_boxed (val);
580 val = gst_structure_get_value (s, "stream");
581 stream = g_value_get_object (val);
583 update_candidates (handler, remote_candidate, local_candidate, stream);
586 tf_channel_bus_message (priv->tfchannel, message);
590 empathy_call_handler_tf_channel_session_created_cb (TfChannel *tfchannel,
591 FsConference *conference, FsParticipant *participant,
592 EmpathyCallHandler *self)
594 g_signal_emit (G_OBJECT (self), signals[CONFERENCE_ADDED], 0,
595 GST_ELEMENT (conference));
599 src_pad_added_error_idle (gpointer data)
601 TfStream *stream = data;
603 tf_stream_error (stream, TP_MEDIA_STREAM_ERROR_MEDIA_ERROR,
604 "Could not link sink");
605 g_object_unref (stream);
611 empathy_call_handler_tf_stream_src_pad_added_cb (TfStream *stream,
612 GstPad *pad, FsCodec *codec, EmpathyCallHandler *handler)
617 g_object_get (stream, "media-type", &media_type, NULL);
619 g_signal_emit (G_OBJECT (handler), signals[SRC_PAD_ADDED], 0,
620 pad, media_type, &retval);
623 g_idle_add (src_pad_added_error_idle, g_object_ref (stream));
628 empathy_call_handler_tf_stream_request_resource_cb (TfStream *stream,
629 guint direction, EmpathyTpCall *call)
634 g_object_get (G_OBJECT (stream), "media-type", &media_type, NULL);
636 g_signal_emit (G_OBJECT (call),
637 signals[REQUEST_RESOURCE], 0, media_type, direction, &ret);
643 empathy_call_handler_tf_stream_closed_cb (TfStream *stream,
644 EmpathyCallHandler *handler)
646 g_signal_emit (handler, signals[STREAM_CLOSED], 0, stream);
650 empathy_call_handler_tf_channel_stream_created_cb (TfChannel *tfchannel,
651 TfStream *stream, EmpathyCallHandler *handler)
661 g_signal_connect (stream, "src-pad-added",
662 G_CALLBACK (empathy_call_handler_tf_stream_src_pad_added_cb), handler);
663 g_signal_connect (stream, "request-resource",
664 G_CALLBACK (empathy_call_handler_tf_stream_request_resource_cb),
666 g_signal_connect (stream, "closed",
667 G_CALLBACK (empathy_call_handler_tf_stream_closed_cb), handler);
669 g_object_get (stream, "media-type", &media_type,
670 "sink-pad", &spad, NULL);
672 g_signal_emit (G_OBJECT (handler), signals[SINK_PAD_ADDED], 0,
673 spad, media_type, &retval);
676 tf_stream_error (stream, TP_MEDIA_STREAM_ERROR_MEDIA_ERROR,
677 "Could not link source");
679 /* Get sending codec */
680 g_object_get (stream, "farsight-session", &session, NULL);
681 g_object_get (session, "current-send-codec", &codec, NULL);
683 update_sending_codec (handler, codec, session);
685 tp_clear_object (&session);
686 tp_clear_object (&codec);
688 /* Get receiving codec */
689 g_object_get (stream, "farsight-stream", &fs_stream, NULL);
690 g_object_get (fs_stream, "current-recv-codecs", &codecs, NULL);
692 update_receiving_codec (handler, codecs, fs_stream);
694 fs_codec_list_destroy (codecs);
695 tp_clear_object (&fs_stream);
697 gst_object_unref (spad);
701 empathy_call_handler_tf_channel_closed_cb (TfChannel *tfchannel,
702 EmpathyCallHandler *handler)
704 g_signal_emit (G_OBJECT (handler), signals[CLOSED], 0);
708 empathy_call_handler_tf_channel_codec_config_cb (TfChannel *channel,
709 guint stream_id, FsMediaType media_type, guint direction, gpointer user_data)
711 gchar *filename = empathy_file_lookup ("codec-preferences", "data");
713 GError *error = NULL;
715 codecs = fs_codec_list_from_keyfile (filename, &error);
720 g_warning ("No codec-preferences file: %s",
721 error ? error->message : "No error message");
723 g_clear_error (&error);
729 empathy_call_handler_start_tpfs (EmpathyCallHandler *self)
731 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
734 g_object_get (priv->call, "channel", &channel, NULL);
736 g_assert (channel != NULL);
738 priv->tfchannel = tf_channel_new (channel);
740 /* Set up the telepathy farsight channel */
741 g_signal_connect (priv->tfchannel, "session-created",
742 G_CALLBACK (empathy_call_handler_tf_channel_session_created_cb), self);
743 g_signal_connect (priv->tfchannel, "stream-created",
744 G_CALLBACK (empathy_call_handler_tf_channel_stream_created_cb), self);
745 g_signal_connect (priv->tfchannel, "closed",
746 G_CALLBACK (empathy_call_handler_tf_channel_closed_cb), self);
747 g_signal_connect (priv->tfchannel, "stream-get-codec-config",
748 G_CALLBACK (empathy_call_handler_tf_channel_codec_config_cb), self);
750 g_object_unref (channel);
754 empathy_call_handler_request_cb (EmpathyDispatchOperation *operation,
758 EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (user_data);
759 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
765 channel = empathy_dispatch_operation_get_channel (operation);
766 g_assert (channel != NULL);
768 priv->call = empathy_tp_call_new (channel);
770 g_object_notify (G_OBJECT (self), "tp-call");
772 empathy_call_handler_start_tpfs (self);
774 empathy_dispatch_operation_claim (operation);
778 empathy_call_handler_start_call (EmpathyCallHandler *handler,
782 EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
784 if (priv->call != NULL)
786 empathy_call_handler_start_tpfs (handler);
787 empathy_tp_call_accept_incoming_call (priv->call);
791 /* No TpCall object (we are redialing). Request a new media channel that
792 * will be used to create a new EmpathyTpCall. */
793 g_assert (priv->contact != NULL);
795 empathy_call_factory_new_call_with_streams (priv->contact,
796 priv->initial_audio, priv->initial_video, timestamp,
797 empathy_call_handler_request_cb, handler);
801 * empathy_call_handler_stop_call:
802 * @handler: an #EmpathyCallHandler
804 * Closes the #EmpathyCallHandler's call and frees its resources.
807 empathy_call_handler_stop_call (EmpathyCallHandler *handler)
809 EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
811 if (priv->call != NULL)
813 empathy_tp_call_leave (priv->call);
814 g_object_unref (priv->call);
821 * empathy_call_handler_has_initial_video:
822 * @handler: an #EmpathyCallHandler
824 * Return %TRUE if the call managed by this #EmpathyCallHandler was
825 * created with video enabled
827 * Return value: %TRUE if the call was created as a video conversation.
830 empathy_call_handler_has_initial_video (EmpathyCallHandler *handler)
832 EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
834 return priv->initial_video;
838 empathy_call_handler_get_send_audio_codec (EmpathyCallHandler *self)
840 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
842 return priv->send_audio_codec;
846 empathy_call_handler_get_send_video_codec (EmpathyCallHandler *self)
848 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
850 return priv->send_video_codec;
854 empathy_call_handler_get_recv_audio_codecs (EmpathyCallHandler *self)
856 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
858 return priv->recv_audio_codecs;
862 empathy_call_handler_get_recv_video_codecs (EmpathyCallHandler *self)
864 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
866 return priv->recv_video_codecs;
870 empathy_call_handler_get_audio_remote_candidate (
871 EmpathyCallHandler *self)
873 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
875 return priv->audio_remote_candidate;
879 empathy_call_handler_get_audio_local_candidate (
880 EmpathyCallHandler *self)
882 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
884 return priv->audio_local_candidate;
888 empathy_call_handler_get_video_remote_candidate (
889 EmpathyCallHandler *self)
891 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
893 return priv->video_remote_candidate;
897 empathy_call_handler_get_video_local_candidate (
898 EmpathyCallHandler *self)
900 EmpathyCallHandlerPriv *priv = GET_PRIV (self);
902 return priv->video_local_candidate;