2 * empathy-gst-video-src.c - Source for EmpathyGstVideoSrc
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
25 #include <gst/interfaces/colorbalance.h>
27 #include "empathy-video-src.h"
29 G_DEFINE_TYPE(EmpathyGstVideoSrc, empathy_video_src, GST_TYPE_BIN)
31 /* Keep in sync with EmpathyGstVideoSrcChannel */
32 static const gchar *channel_names[NR_EMPATHY_GST_VIDEO_SRC_CHANNELS] = {
33 "contrast", "brightness", "gamma" };
42 static guint signals[LAST_SIGNAL] = {0};
45 /* private structure */
46 typedef struct _EmpathyGstVideoSrcPrivate EmpathyGstVideoSrcPrivate;
48 struct _EmpathyGstVideoSrcPrivate
50 gboolean dispose_has_run;
52 /* Element implementing a ColorBalance interface */
56 #define EMPATHY_GST_VIDEO_SRC_GET_PRIVATE(o) \
57 (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_GST_VIDEO_SRC, \
58 EmpathyGstVideoSrcPrivate))
60 * empathy_gst_add_to_bin - create a new gst element, add to bin and link it.
61 * @bin - bin to add the new element to.
62 * @src - src element for the new element (may be NULL).
63 * @name - name of the factory for the new element
65 * Returns: The newly created element ot %NULL on failure
68 empathy_gst_add_to_bin (GstBin *bin,
70 const gchar *factoryname)
74 if ((ret = gst_element_factory_make (factoryname, NULL)) == NULL)
76 g_message ("Element factory \"%s\" not found.", factoryname);
80 if (!gst_bin_add (bin, ret))
82 g_warning ("Couldn't add \"%s\" to bin.", factoryname);
86 /* do not link if src == NULL, just exit here */
90 if (!gst_element_link (src, ret))
92 g_warning ("Failed to link \"%s\".", factoryname);
93 gst_bin_remove (bin, ret);
101 gst_object_unref (ret);
107 empathy_video_src_init (EmpathyGstVideoSrc *obj)
109 EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (obj);
110 GstElement *element, *element_back;
115 /* allocate caps here, so we can update it by optional elements */
116 caps = gst_caps_new_simple ("video/x-raw-yuv",
117 "width", G_TYPE_INT, 320,
118 "height", G_TYPE_INT, 240,
121 /* allocate any data required by the object here */
122 if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
123 NULL, "gconfvideosrc")) == NULL)
124 g_error ("Couldn't add \"gconfvideosrc\" (gst-plugins-good missing?)");
126 /* we need to save our source to priv->src */
129 /* videomaxrate is optional as it's part of gst-plugins-bad. So don't
130 * fail if it doesn't exist. */
131 element_back = element;
132 if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
133 element, "videomaxrate")) == NULL)
135 g_message ("Couldn't add \"videomaxrate\" (gst-plugins-bad missing?)");
136 element = element_back;
140 gst_caps_set_simple (caps,
141 "framerate", GST_TYPE_FRACTION, 15, 1,
145 str = gst_caps_to_string (caps);
146 g_debug ("Current video src caps are : %s", str);
149 if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
150 element, "ffmpegcolorspace")) == NULL)
151 g_error ("Failed to add \"ffmpegcolorspace\" (gst-plugins-base missing?)");
153 if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
154 element, "videoscale")) == NULL)
155 g_error ("Failed to add \"videoscale\", (gst-plugins-base missing?)");
157 if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
158 element, "capsfilter")) == NULL)
160 "Failed to add \"capsfilter\" (gstreamer core elements missing?)");
162 g_object_set (G_OBJECT (element), "caps", caps, NULL);
165 /* optionally add postproc_tmpnoise to improve the performance of encoders */
166 element_back = element;
167 if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
168 element, "postproc_tmpnoise")) == NULL)
170 g_message ("Failed to add \"postproc_tmpnoise\" (gst-ffmpeg missing?)");
171 element = element_back;
174 src = gst_element_get_static_pad (element, "src");
175 g_assert (src != NULL);
177 ghost = gst_ghost_pad_new ("src", src);
179 g_error ("Unable to create ghost pad for the videosrc");
181 if (!gst_element_add_pad (GST_ELEMENT (obj), ghost))
182 g_error ("pad with the same name already existed or "
183 "the pad already had another parent.");
185 gst_object_unref (G_OBJECT (src));
188 static void empathy_video_src_dispose (GObject *object);
189 static void empathy_video_src_finalize (GObject *object);
192 empathy_video_src_class_init (EmpathyGstVideoSrcClass *empathy_video_src_class)
194 GObjectClass *object_class = G_OBJECT_CLASS (empathy_video_src_class);
196 g_type_class_add_private (empathy_video_src_class,
197 sizeof (EmpathyGstVideoSrcPrivate));
199 object_class->dispose = empathy_video_src_dispose;
200 object_class->finalize = empathy_video_src_finalize;
204 empathy_video_src_dispose (GObject *object)
206 EmpathyGstVideoSrc *self = EMPATHY_GST_VIDEO_SRC (object);
207 EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (self);
209 if (priv->dispose_has_run)
212 priv->dispose_has_run = TRUE;
214 /* release any references held by the object here */
216 if (G_OBJECT_CLASS (empathy_video_src_parent_class)->dispose)
217 G_OBJECT_CLASS (empathy_video_src_parent_class)->dispose (object);
221 empathy_video_src_finalize (GObject *object)
223 //EmpathyGstVideoSrc *self = EMPATHY_GST_VIDEO_SRC (object);
224 //EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (self);
226 /* free any data held directly by the object here */
228 G_OBJECT_CLASS (empathy_video_src_parent_class)->finalize (object);
232 empathy_video_src_new (void)
234 static gboolean registered = FALSE;
237 if (!gst_element_register (NULL, "empathyvideosrc",
238 GST_RANK_NONE, EMPATHY_TYPE_GST_VIDEO_SRC))
242 return gst_element_factory_make ("empathyvideosrc", NULL);
246 empathy_video_src_set_channel (GstElement *src,
247 EmpathyGstVideoSrcChannel channel, guint percent)
250 GstColorBalance *balance;
251 const GList *channels;
254 /* Find something supporting GstColorBalance */
255 color = gst_bin_get_by_interface (GST_BIN (src), GST_TYPE_COLOR_BALANCE);
260 balance = GST_COLOR_BALANCE (color);
262 channels = gst_color_balance_list_channels (balance);
264 for (l = (GList *) channels; l != NULL; l = g_list_next (l))
266 GstColorBalanceChannel *c = GST_COLOR_BALANCE_CHANNEL (l->data);
268 if (g_ascii_strcasecmp (c->label, channel_names[channel]) == 0)
270 gst_color_balance_set_value (balance, c,
271 ((c->max_value - c->min_value) * percent)/100
277 g_object_unref (color);
281 empathy_video_src_get_channel (GstElement *src,
282 EmpathyGstVideoSrcChannel channel)
285 GstColorBalance *balance;
286 const GList *channels;
290 /* Find something supporting GstColorBalance */
291 color = gst_bin_get_by_interface (GST_BIN (src), GST_TYPE_COLOR_BALANCE);
296 balance = GST_COLOR_BALANCE (color);
298 channels = gst_color_balance_list_channels (balance);
300 for (l = (GList *) channels; l != NULL; l = g_list_next (l))
302 GstColorBalanceChannel *c = GST_COLOR_BALANCE_CHANNEL (l->data);
304 if (g_ascii_strcasecmp (c->label, channel_names[channel]) == 0)
307 ((gst_color_balance_get_value (balance, c)
308 - c->min_value) * 100) /
309 (c->max_value - c->min_value);
315 g_object_unref (color);
322 empathy_video_src_get_supported_channels (GstElement *src)
325 GstColorBalance *balance;
326 const GList *channels;
330 /* Find something supporting GstColorBalance */
331 color = gst_bin_get_by_interface (GST_BIN (src), GST_TYPE_COLOR_BALANCE);
336 balance = GST_COLOR_BALANCE (color);
338 channels = gst_color_balance_list_channels (balance);
340 for (l = (GList *) channels; l != NULL; l = g_list_next (l))
342 GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (l->data);
345 for (i = 0; i < NR_EMPATHY_GST_VIDEO_SRC_CHANNELS; i++)
347 if (g_ascii_strcasecmp (channel->label, channel_names[i]) == 0)
355 g_object_unref (color);