2 * empathy-call-window.c - Source for EmpathyCallWindow
3 * Copyright (C) 2008 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
27 #include <libempathy-gtk/empathy-video-widget.h>
28 #include <libempathy-gtk/empathy-audio-src.h>
29 #include <libempathy-gtk/empathy-audio-sink.h>
30 #include <libempathy-gtk/empathy-video-src.h>
32 #include "empathy-call-window.h"
34 G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW)
43 static guint signals[LAST_SIGNAL] = {0};
47 PROP_CALL_HANDLER = 1,
50 /* private structure */
51 typedef struct _EmpathyCallWindowPriv EmpathyCallWindowPriv;
53 struct _EmpathyCallWindowPriv
55 gboolean dispose_has_run;
56 EmpathyCallHandler *handler;
57 GtkWidget *video_output;
58 GtkWidget *video_preview;
59 GstElement *video_input;
60 GstElement *audio_input;
61 GstElement *audio_output;
63 GstElement *video_tee;
67 (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_CALL_WINDOW, \
68 EmpathyCallWindowPriv))
70 static void empathy_call_window_realized_cb (GtkWidget *widget,
71 EmpathyCallWindow *window);
74 empathy_call_window_init (EmpathyCallWindow *self)
76 EmpathyCallWindowPriv *priv = GET_PRIV (self);
80 priv->pipeline = gst_pipeline_new (NULL);
82 hbox = gtk_hbox_new (TRUE, 3);
83 gtk_container_add (GTK_CONTAINER (self), hbox);
85 bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
87 priv->video_output = empathy_video_widget_new (bus);
89 priv->video_tee = gst_element_factory_make ("tee", NULL);
90 priv->video_input = empathy_video_src_new ();
91 priv->video_preview = empathy_video_widget_new (bus);
93 priv->audio_input = empathy_audio_src_new ();
94 priv->audio_output = empathy_audio_sink_new ();
97 gst_bin_add_many (GST_BIN (priv->pipeline),
98 empathy_gtk_widget_get_element (
99 EMPATHY_GST_GTK_WIDGET (priv->video_preview)),
100 empathy_gtk_widget_get_element (
101 EMPATHY_GST_GTK_WIDGET (priv->video_output)),
108 g_object_unref (bus);
110 gtk_box_pack_start (GTK_BOX (hbox), priv->video_preview, TRUE, TRUE, 3);
111 gtk_box_pack_start (GTK_BOX (hbox), priv->video_output, TRUE, TRUE, 3);
113 gtk_widget_show_all (hbox);
115 g_signal_connect (G_OBJECT (self), "realize",
116 G_CALLBACK (empathy_call_window_realized_cb), self);
119 static void empathy_call_window_dispose (GObject *object);
120 static void empathy_call_window_finalize (GObject *object);
123 empathy_call_window_set_property (GObject *object,
124 guint property_id, const GValue *value, GParamSpec *pspec)
126 EmpathyCallWindowPriv *priv = GET_PRIV (object);
130 case PROP_CALL_HANDLER:
131 priv->handler = g_value_dup_object (value);
134 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
139 empathy_call_window_get_property (GObject *object,
140 guint property_id, GValue *value, GParamSpec *pspec)
142 EmpathyCallWindowPriv *priv = GET_PRIV (object);
146 case PROP_CALL_HANDLER:
147 g_value_set_object (value, priv->handler);
150 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
155 empathy_call_window_class_init (
156 EmpathyCallWindowClass *empathy_call_window_class)
158 GObjectClass *object_class = G_OBJECT_CLASS (empathy_call_window_class);
159 GParamSpec *param_spec;
161 g_type_class_add_private (empathy_call_window_class,
162 sizeof (EmpathyCallWindowPriv));
164 object_class->set_property = empathy_call_window_set_property;
165 object_class->get_property = empathy_call_window_get_property;
167 object_class->dispose = empathy_call_window_dispose;
168 object_class->finalize = empathy_call_window_finalize;
170 param_spec = g_param_spec_object ("handler",
171 "handler", "The call handler",
172 EMPATHY_TYPE_CALL_HANDLER,
173 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
174 g_object_class_install_property (object_class,
175 PROP_CALL_HANDLER, param_spec);
180 empathy_call_window_dispose (GObject *object)
182 EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object);
183 EmpathyCallWindowPriv *priv = GET_PRIV (self);
185 if (priv->dispose_has_run)
188 priv->dispose_has_run = TRUE;
190 if (priv->handler != NULL)
191 g_object_unref (priv->handler);
193 priv->handler = NULL;
195 /* release any references held by the object here */
197 if (G_OBJECT_CLASS (empathy_call_window_parent_class)->dispose)
198 G_OBJECT_CLASS (empathy_call_window_parent_class)->dispose (object);
202 empathy_call_window_finalize (GObject *object)
204 //EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object);
205 //EmpathyCallWindowPriv *priv = GET_PRIV (self);
207 /* free any data held directly by the object here */
209 G_OBJECT_CLASS (empathy_call_window_parent_class)->finalize (object);
214 empathy_call_window_new (EmpathyCallHandler *handler)
216 return EMPATHY_CALL_WINDOW (
217 g_object_new (EMPATHY_TYPE_CALL_WINDOW, "handler", handler, NULL));
221 empathy_call_window_conference_added_cb (EmpathyCallHandler *handler,
222 GstElement *conference, gpointer user_data)
224 EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
225 EmpathyCallWindowPriv *priv = GET_PRIV (self);
227 gst_bin_add (GST_BIN (priv->pipeline), conference);
229 gst_element_set_state (conference, GST_STATE_PLAYING);
231 printf ("ADDING CONFERENCE\n");
235 empathy_call_window_src_added_cb (EmpathyCallHandler *handler,
236 GstPad *src, guint media_type, gpointer user_data)
238 EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
239 EmpathyCallWindowPriv *priv = GET_PRIV (self);
244 printf ("ADDING SRC PAD %d\n", media_type);
248 case TP_MEDIA_STREAM_TYPE_AUDIO:
249 element = priv->audio_output;
251 case TP_MEDIA_STREAM_TYPE_VIDEO:
253 empathy_video_widget_get_element (
254 EMPATHY_VIDEO_WIDGET (priv->video_output));
257 g_assert_not_reached ();
260 gst_bin_add (GST_BIN (priv->pipeline), element);
262 pad = gst_element_get_static_pad (element, "sink");
263 gst_element_set_state (element, GST_STATE_PLAYING);
265 gst_pad_link (src, pad);
269 empathy_call_window_sink_added_cb (EmpathyCallHandler *handler,
270 GstPad *sink, guint media_type, gpointer user_data)
272 EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
273 EmpathyCallWindowPriv *priv = GET_PRIV (self);
276 printf ("ADDING SINK PAD %d\n", media_type);
280 case TP_MEDIA_STREAM_TYPE_AUDIO:
281 gst_bin_add (GST_BIN (priv->pipeline), priv->audio_input);
282 gst_element_set_state (priv->audio_input, GST_STATE_PLAYING);
284 pad = gst_element_get_static_pad (priv->audio_input, "src");
285 gst_pad_link (pad, sink);
287 case TP_MEDIA_STREAM_TYPE_VIDEO:
288 pad = gst_element_get_request_pad (priv->video_tee, "src%d");
289 gst_pad_link (pad, sink);
292 g_assert_not_reached ();
298 empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window)
300 EmpathyCallWindowPriv *priv = GET_PRIV (window);
304 g_signal_connect (priv->handler, "conference-added",
305 G_CALLBACK (empathy_call_window_conference_added_cb), window);
306 g_signal_connect (priv->handler, "src-pad-added",
307 G_CALLBACK (empathy_call_window_src_added_cb), window);
308 g_signal_connect (priv->handler, "sink-pad-added",
309 G_CALLBACK (empathy_call_window_sink_added_cb), window);
311 bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
312 empathy_call_handler_set_bus (priv->handler, bus);
313 empathy_call_handler_start_call (priv->handler);
315 preview = empathy_video_widget_get_element (
316 EMPATHY_VIDEO_WIDGET (priv->video_preview));
318 gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input,
319 priv->video_tee, preview, NULL);
320 gst_element_link_many (priv->video_input, priv->video_tee,
323 gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
325 g_object_unref (bus);