]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-video-src.c
add myself to AUTHORS
[empathy.git] / libempathy-gtk / empathy-video-src.c
1 /*
2  * empathy-gst-video-src.c - Source for EmpathyGstVideoSrc
3  * Copyright (C) 2008 Collabora Ltd.
4  * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
5  *
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.
10  *
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.
15  *
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
19  */
20
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include <gst/interfaces/colorbalance.h>
26
27 #include "empathy-video-src.h"
28
29 G_DEFINE_TYPE(EmpathyGstVideoSrc, empathy_video_src, GST_TYPE_BIN)
30
31 /* Keep in sync with EmpathyGstVideoSrcChannel */
32 static gchar *channel_names[NR_EMPATHY_GST_VIDEO_SRC_CHANNELS] = { "contrast",
33   "brightness", "gamma" };
34
35 /* signal enum */
36 #if 0
37 enum
38 {
39     LAST_SIGNAL
40 };
41
42 static guint signals[LAST_SIGNAL] = {0};
43 #endif
44
45 /* private structure */
46 typedef struct _EmpathyGstVideoSrcPrivate EmpathyGstVideoSrcPrivate;
47
48 struct _EmpathyGstVideoSrcPrivate
49 {
50   gboolean dispose_has_run;
51   GstElement *src;
52   /* Element implementing a ColorBalance interface */
53   GstElement *balance;
54 };
55
56 #define EMPATHY_GST_VIDEO_SRC_GET_PRIVATE(o) \
57   (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_GST_VIDEO_SRC, \
58     EmpathyGstVideoSrcPrivate))
59
60 static void
61 empathy_video_src_init (EmpathyGstVideoSrc *obj)
62 {
63   EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (obj);
64   GstElement *scale, *colorspace, *capsfilter;
65   GstPad *ghost, *src;
66   GstCaps *caps;
67
68   /* allocate any data required by the object here */
69   scale = gst_element_factory_make ("videoscale", NULL);
70   colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
71
72   capsfilter = gst_element_factory_make ("capsfilter", NULL);
73   caps = gst_caps_new_simple ("video/x-raw-yuv",
74     "width", G_TYPE_INT, 320,
75     "height", G_TYPE_INT, 240,
76     NULL);
77
78   g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL);
79
80   priv->src = gst_element_factory_make ("gconfvideosrc", NULL);
81
82   gst_bin_add_many (GST_BIN (obj), priv->src, scale, colorspace, capsfilter,
83     NULL);
84   gst_element_link_many (priv->src, scale, colorspace, capsfilter, NULL);
85
86   src = gst_element_get_static_pad (capsfilter, "src");
87
88   ghost = gst_ghost_pad_new ("src", src);
89   gst_element_add_pad (GST_ELEMENT (obj), ghost);
90
91   gst_object_unref (G_OBJECT (src));
92 }
93
94 static void empathy_video_src_dispose (GObject *object);
95 static void empathy_video_src_finalize (GObject *object);
96
97 static void
98 empathy_video_src_class_init (EmpathyGstVideoSrcClass *empathy_video_src_class)
99 {
100   GObjectClass *object_class = G_OBJECT_CLASS (empathy_video_src_class);
101
102   g_type_class_add_private (empathy_video_src_class,
103     sizeof (EmpathyGstVideoSrcPrivate));
104
105   object_class->dispose = empathy_video_src_dispose;
106   object_class->finalize = empathy_video_src_finalize;
107 }
108
109 void
110 empathy_video_src_dispose (GObject *object)
111 {
112   EmpathyGstVideoSrc *self = EMPATHY_GST_VIDEO_SRC (object);
113   EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (self);
114
115   if (priv->dispose_has_run)
116     return;
117
118   priv->dispose_has_run = TRUE;
119
120   /* release any references held by the object here */
121
122   if (G_OBJECT_CLASS (empathy_video_src_parent_class)->dispose)
123     G_OBJECT_CLASS (empathy_video_src_parent_class)->dispose (object);
124 }
125
126 void
127 empathy_video_src_finalize (GObject *object)
128 {
129   //EmpathyGstVideoSrc *self = EMPATHY_GST_VIDEO_SRC (object);
130   //EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (self);
131
132   /* free any data held directly by the object here */
133
134   G_OBJECT_CLASS (empathy_video_src_parent_class)->finalize (object);
135 }
136
137 GstElement *
138 empathy_video_src_new (void)
139 {
140   static gboolean registered = FALSE;
141
142   if (!registered) {
143     if (!gst_element_register (NULL, "empathyvideosrc",
144             GST_RANK_NONE, EMPATHY_TYPE_GST_VIDEO_SRC))
145       return NULL;
146     registered = TRUE;
147   }
148   return gst_element_factory_make ("empathyvideosrc", NULL);
149 }
150
151 void
152 empathy_video_src_set_channel (GstElement *src,
153   EmpathyGstVideoSrcChannel channel, guint percent)
154 {
155   GstElement *color;
156   GstColorBalance *balance;
157   const GList *channels;
158   GList *l;
159
160   /* Find something supporting GstColorBalance */
161   color = gst_bin_get_by_interface (GST_BIN (src), GST_TYPE_COLOR_BALANCE);
162
163   if (color == NULL)
164     return;
165
166   balance = GST_COLOR_BALANCE (color);
167
168   channels = gst_color_balance_list_channels (balance);
169
170   for (l = (GList *) channels; l != NULL; l = g_list_next (l))
171     {
172       GstColorBalanceChannel *c = GST_COLOR_BALANCE_CHANNEL (l->data);
173
174       if (g_ascii_strcasecmp (c->label, channel_names[channel]) == 0)
175         {
176           gst_color_balance_set_value (balance, c,
177             ((c->max_value - c->min_value) * percent)/100
178               + c->min_value);
179           break;
180         }
181     }
182
183   g_object_unref (color);
184 }
185
186 guint
187 empathy_video_src_get_channel (GstElement *src,
188   EmpathyGstVideoSrcChannel channel)
189 {
190   GstElement *color;
191   GstColorBalance *balance;
192   const GList *channels;
193   GList *l;
194   guint percent = 0;
195
196   /* Find something supporting GstColorBalance */
197   color = gst_bin_get_by_interface (GST_BIN (src), GST_TYPE_COLOR_BALANCE);
198
199   if (color == NULL)
200     return percent;
201
202   balance = GST_COLOR_BALANCE (color);
203
204   channels = gst_color_balance_list_channels (balance);
205
206   for (l = (GList *) channels; l != NULL; l = g_list_next (l))
207     {
208       GstColorBalanceChannel *c = GST_COLOR_BALANCE_CHANNEL (l->data);
209
210       if (g_ascii_strcasecmp (c->label, channel_names[channel]) == 0)
211         {
212           percent =
213             ((gst_color_balance_get_value (balance, c)
214                 - c->min_value) * 100) /
215               (c->max_value - c->min_value);
216
217           break;
218         }
219     }
220
221   g_object_unref (color);
222
223   return percent;
224 }
225
226
227 guint
228 empathy_video_src_get_supported_channels (GstElement *src)
229 {
230   GstElement *color;
231   GstColorBalance *balance;
232   const GList *channels;
233   GList *l;
234   guint result = 0;
235
236   /* Find something supporting GstColorBalance */
237   color = gst_bin_get_by_interface (GST_BIN (src), GST_TYPE_COLOR_BALANCE);
238
239   if (color == NULL)
240     goto out;
241
242   balance = GST_COLOR_BALANCE (color);
243
244   channels = gst_color_balance_list_channels (balance);
245
246   for (l = (GList *) channels; l != NULL; l = g_list_next (l))
247     {
248       GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (l->data);
249       int i;
250
251       for (i = 0; i < NR_EMPATHY_GST_VIDEO_SRC_CHANNELS; i++)
252         {
253           if (g_ascii_strcasecmp (channel->label, channel_names[i]) == 0)
254             {
255               result |= (1 << i);
256               break;
257             }
258         }
259     }
260
261   g_object_unref (color);
262
263 out:
264   return result;
265 }
266