blob: 9743ebcb2f57858cf13ee1a4b073de569a9b21e8 [file] [log] [blame]
Andy Wingob0c01cd2002-03-20 21:45:04 +00001/* GStreamer
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +00002 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
Tim-Philipp Müller9e1b75f2012-11-03 20:38:00 +000016 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000018 */
19
Benjamin Ottef4a7caa2003-06-29 19:46:13 +000020#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000023#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <sys/ioctl.h>
27#include <sys/mman.h>
28#include <string.h>
29
Andy Wingo4359de22002-03-19 04:10:06 +000030/*#define DEBUG_ENABLED */
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000031#include <gstqcamsrc.h>
Ronald S. Bultje95011fd2003-07-06 20:49:52 +000032#include <gst/video/video.h>
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000033
34#include "qcamip.h"
35
Thomas Vander Stichelebdb814f2005-12-06 19:55:58 +000036#define AE_NONE 3
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000037
Thomas Vander Stichelebdb814f2005-12-06 19:55:58 +000038#define DEF_WIDTH 320
39#define DEF_HEIGHT 224
40#define DEF_BRIGHTNESS 226
41#define DEF_WHITEBAL 128
42#define DEF_CONTRAST 72
43#define DEF_TOP 1
44#define DEF_LEFT 14
45#define DEF_TRANSFER_SCALE 2
46#define DEF_DEPTH 6
47#define DEF_PORT 0x378
48#define DEF_AUTOEXP AE_NONE
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000049
David Schleefb144bc62003-12-22 01:47:09 +000050static GstStaticPadTemplate gst_qcamsrc_src_factory =
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +000051GST_STATIC_PAD_TEMPLATE ("src",
52 GST_PAD_SRC,
53 GST_PAD_ALWAYS,
54 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
55 );
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000056
57#define GST_TYPE_AUTOEXP_MODE (gst_autoexp_mode_get_type())
58static GType
59gst_autoexp_mode_get_type (void)
60{
61 static GType autoexp_mode_type = 0;
62 static GEnumValue autoexp_modes[] = {
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +000063 {AE_ALL_AVG, "0", "Average Picture"},
64 {AE_CTR_AVG, "1", "Average Center"},
65 {AE_STD_AVG, "2", "Standard Deviation"},
66 {AE_NONE, "3", "None"},
67 {0, NULL, NULL},
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000068 };
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +000069
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000070 if (!autoexp_mode_type) {
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +000071 autoexp_mode_type =
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +000072 g_enum_register_static ("GstAutoExposureMode", autoexp_modes);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000073 }
74 return autoexp_mode_type;
75}
76
77/* QCamSrc signals and args */
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +000078enum
79{
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000080 /* FILL ME */
81 LAST_SIGNAL
82};
83
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +000084enum
85{
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000086 ARG_0,
87 ARG_WIDTH,
88 ARG_HEIGHT,
89 ARG_BRIGHTNESS,
90 ARG_WHITEBAL,
91 ARG_CONTRAST,
92 ARG_TOP,
93 ARG_LEFT,
94 ARG_TRANSFER_SCALE,
95 ARG_DEPTH,
96 ARG_PORT,
Stéphane Loeuillet8ab84442004-05-21 23:53:08 +000097 ARG_AUTOEXP
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +000098};
99
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000100static void gst_qcamsrc_base_init (gpointer g_class);
101static void gst_qcamsrc_class_init (GstQCamSrcClass * klass);
102static void gst_qcamsrc_init (GstQCamSrc * qcamsrc);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000103
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000104static void gst_qcamsrc_set_property (GObject * object, guint prop_id,
105 const GValue * value, GParamSpec * pspec);
106static void gst_qcamsrc_get_property (GObject * object, guint prop_id,
107 GValue * value, GParamSpec * pspec);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000108
Jan Schmidt012dfb82005-09-05 17:20:29 +0000109static GstStateChangeReturn gst_qcamsrc_change_state (GstElement * element,
110 GstStateChange transition);
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000111static void gst_qcamsrc_close (GstQCamSrc * src);
112static gboolean gst_qcamsrc_open (GstQCamSrc * src);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000113
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000114static GstData *gst_qcamsrc_get (GstPad * pad);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000115
116static GstElementClass *parent_class = NULL;
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000117
Andy Wingo4359de22002-03-19 04:10:06 +0000118/*//static guint gst_qcamsrc_signals[LAST_SIGNAL] = { 0 }; */
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000119
120GType
121gst_qcamsrc_get_type (void)
122{
123 static GType qcamsrc_type = 0;
124
125 if (!qcamsrc_type) {
126 static const GTypeInfo qcamsrc_info = {
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000127 sizeof (GstQCamSrcClass),
Benjamin Otteeabfbf12003-11-02 14:47:52 +0000128 gst_qcamsrc_base_init,
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000129 NULL,
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000130 (GClassInitFunc) gst_qcamsrc_class_init,
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000131 NULL,
132 NULL,
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000133 sizeof (GstQCamSrc),
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000134 0,
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000135 (GInstanceInitFunc) gst_qcamsrc_init,
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000136 NULL
137 };
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000138
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000139 qcamsrc_type =
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000140 g_type_register_static (GST_TYPE_ELEMENT, "GstQCamSrc", &qcamsrc_info,
141 0);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000142 }
143 return qcamsrc_type;
144}
Benjamin Otte775c7582010-03-18 17:30:26 +0100145
Benjamin Otteeabfbf12003-11-02 14:47:52 +0000146static void
147gst_qcamsrc_base_init (gpointer g_class)
148{
149 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000150
151 gst_element_class_add_pad_template (element_class,
152 gst_static_pad_template_get (&gst_qcamsrc_src_factory));
Tim-Philipp Müller32ba17c2012-10-17 17:34:26 +0100153 gst_element_class_set_static_metadata (element_class, "QCam Source",
Benjamin Otte775c7582010-03-18 17:30:26 +0100154 "Source/Video",
155 "Read from a QuickCam device", "Wim Taymans <wim.taymans@chello.be>");
Benjamin Otteeabfbf12003-11-02 14:47:52 +0000156}
Benjamin Otte775c7582010-03-18 17:30:26 +0100157
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000158static void
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000159gst_qcamsrc_class_init (GstQCamSrcClass * klass)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000160{
161 GObjectClass *gobject_class;
162 GstElementClass *gstelement_class;
163
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000164 gobject_class = (GObjectClass *) klass;
165 gstelement_class = (GstElementClass *) klass;
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000166
Stefan Kostaa99af62006-04-08 21:48:01 +0000167 parent_class = g_type_class_peek_parent (klass);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000168
169 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_WIDTH,
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000170 g_param_spec_int ("width", "width", "width",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000171 0, 320, DEF_WIDTH, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000172 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HEIGHT,
173 g_param_spec_int ("height", "height", "height",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000174 0, 240, DEF_HEIGHT, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000175 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BRIGHTNESS,
176 g_param_spec_int ("brightness", "brightness", "brightness",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000177 0, 255, DEF_BRIGHTNESS, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000178 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_WHITEBAL,
179 g_param_spec_int ("whitebal", "whitebal", "whitebal",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000180 0, 255, DEF_WHITEBAL, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000181 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CONTRAST,
182 g_param_spec_int ("contrast", "contrast", "contrast",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000183 0, 255, DEF_CONTRAST, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000184 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TOP,
185 g_param_spec_int ("top", "top", "top",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000186 0, 240, DEF_TOP, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000187 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LEFT,
188 g_param_spec_int ("left", "left", "left",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000189 0, 320, DEF_LEFT, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000190 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TRANSFER_SCALE,
191 g_param_spec_int ("transfer_scale", "transfer_scale", "transfer_scale",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000192 1, 4, DEF_TRANSFER_SCALE, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000193 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEPTH,
194 g_param_spec_int ("depth", "depth", "depth",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000195 4, 6, DEF_DEPTH, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000196 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT,
197 g_param_spec_int ("port", "port", "port",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000198 0, G_MAXINT, DEF_PORT, G_PARAM_READWRITE));
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000199 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_AUTOEXP,
200 g_param_spec_enum ("autoexposure", "autoexposure", "autoexposure",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000201 GST_TYPE_AUTOEXP_MODE, DEF_AUTOEXP, G_PARAM_READWRITE));
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000202
203 gobject_class->set_property = gst_qcamsrc_set_property;
204 gobject_class->get_property = gst_qcamsrc_get_property;
205
206 gstelement_class->change_state = gst_qcamsrc_change_state;
207}
208
209static void
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000210gst_qcamsrc_init (GstQCamSrc * qcamsrc)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000211{
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000212 qcamsrc->srcpad =
Edward Herveyb8a18742007-06-22 10:46:33 +0000213 gst_pad_new_from_static_template (&gst_qcamsrc_src_factory, "src");
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000214 gst_element_add_pad (GST_ELEMENT (qcamsrc), qcamsrc->srcpad);
215 gst_pad_set_get_function (qcamsrc->srcpad, gst_qcamsrc_get);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000216
217 /* if the destination cannot say what it wants, we give this */
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000218 qcamsrc->qcam = qc_init ();
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000219 qcamsrc->qcam->port = DEF_PORT;
220 qc_setwidth (qcamsrc->qcam, DEF_WIDTH);
221 qc_setheight (qcamsrc->qcam, DEF_HEIGHT);
222 qc_setbrightness (qcamsrc->qcam, DEF_BRIGHTNESS);
223 qc_setwhitebal (qcamsrc->qcam, DEF_WHITEBAL);
224 qc_setcontrast (qcamsrc->qcam, DEF_CONTRAST);
225 qc_settop (qcamsrc->qcam, DEF_TOP);
226 qc_setleft (qcamsrc->qcam, DEF_LEFT);
227 qc_settransfer_scale (qcamsrc->qcam, DEF_TRANSFER_SCALE);
228 qc_setbitdepth (qcamsrc->qcam, DEF_DEPTH);
229 qcamsrc->autoexposure = DEF_AUTOEXP;
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000230 if (qcamsrc->autoexposure != AE_NONE)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000231 qcip_set_autoexposure_mode (qcamsrc->autoexposure);
232}
233
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000234static GstData *
235gst_qcamsrc_get (GstPad * pad)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000236{
237 GstQCamSrc *qcamsrc;
238 GstBuffer *buf;
239 scanbuf *scan;
240 guchar *outdata;
241 gint i, frame, scale, convert;
242
243 g_return_val_if_fail (pad != NULL, NULL);
244
245 qcamsrc = GST_QCAMSRC (gst_pad_get_parent (pad));
246
247 scale = qc_gettransfer_scale (qcamsrc->qcam);
248
249 frame = qcamsrc->qcam->width * qcamsrc->qcam->height / (scale * scale);
250
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000251 buf = gst_buffer_new ();
252 outdata = GST_BUFFER_DATA (buf) = g_malloc0 ((frame * 3) / 2);
253 GST_BUFFER_SIZE (buf) = (frame * 3) / 2;
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000254
255 qc_set (qcamsrc->qcam);
256 if (!GST_PAD_CAPS (pad)) {
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000257 gst_pad_try_set_caps (pad, gst_caps_new_simple ("video/x-raw-yuv",
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000258 "format", GST_TYPE_FOURCC, "I420",
259 "width", G_TYPE_INT, qcamsrc->qcam->width / scale,
260 "height", G_TYPE_INT, qcamsrc->qcam->height / scale,
261 "framerate", G_TYPE_DOUBLE, 10., NULL));
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000262 }
263 scan = qc_scan (qcamsrc->qcam);
264
Andy Wingo4359de22002-03-19 04:10:06 +0000265 /* FIXME, this doesn't seem to work... */
266 /*fixdark(qcamsrc->qcam, scan); */
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000267
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000268 if (qcamsrc->autoexposure != AE_NONE)
269 qcip_autoexposure (qcamsrc->qcam, scan);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000270
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000271 convert = (qcamsrc->qcam->bpp == 4 ? 4 : 2);
272
273 for (i = frame; i; i--) {
274 outdata[i] = scan[i] << convert;
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000275 }
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000276 memset (outdata + frame, 128, frame >> 1);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000277 g_free (scan);
278
Andy Wingoc07813a2003-10-08 16:08:19 +0000279 return GST_DATA (buf);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000280}
281
282static void
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000283gst_qcamsrc_set_property (GObject * object, guint prop_id, const GValue * value,
284 GParamSpec * pspec)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000285{
286 GstQCamSrc *src;
287
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000288 g_return_if_fail (GST_IS_QCAMSRC (object));
289 src = GST_QCAMSRC (object);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000290
291 switch (prop_id) {
292 case ARG_WIDTH:
293 qc_setwidth (src->qcam, g_value_get_int (value));
294 break;
295 case ARG_HEIGHT:
296 qc_setheight (src->qcam, g_value_get_int (value));
297 break;
298 case ARG_BRIGHTNESS:
299 qc_setbrightness (src->qcam, g_value_get_int (value));
300 break;
301 case ARG_WHITEBAL:
302 qc_setwhitebal (src->qcam, g_value_get_int (value));
303 break;
304 case ARG_CONTRAST:
305 qc_setcontrast (src->qcam, g_value_get_int (value));
306 break;
307 case ARG_TOP:
308 qc_settop (src->qcam, g_value_get_int (value));
309 break;
310 case ARG_LEFT:
311 qc_setleft (src->qcam, g_value_get_int (value));
312 break;
313 case ARG_TRANSFER_SCALE:
314 qc_settransfer_scale (src->qcam, g_value_get_int (value));
315 break;
316 case ARG_DEPTH:
317 qc_setbitdepth (src->qcam, g_value_get_int (value));
318 break;
319 case ARG_PORT:
320 src->qcam->port = g_value_get_int (value);
321 break;
322 case ARG_AUTOEXP:
323 src->autoexposure = g_value_get_enum (value);
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000324 if (src->autoexposure != AE_NONE)
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000325 qcip_set_autoexposure_mode (src->autoexposure);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000326 break;
327 default:
328 break;
329 }
330}
331
332static void
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000333gst_qcamsrc_get_property (GObject * object, guint prop_id, GValue * value,
334 GParamSpec * pspec)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000335{
336 GstQCamSrc *src;
337
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000338 g_return_if_fail (GST_IS_QCAMSRC (object));
339 src = GST_QCAMSRC (object);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000340
341 switch (prop_id) {
342 case ARG_WIDTH:
343 g_value_set_int (value, qc_getwidth (src->qcam));
344 break;
345 case ARG_HEIGHT:
346 g_value_set_int (value, qc_getheight (src->qcam));
347 break;
348 case ARG_BRIGHTNESS:
349 g_value_set_int (value, qc_getbrightness (src->qcam));
350 break;
351 case ARG_WHITEBAL:
352 g_value_set_int (value, qc_getwhitebal (src->qcam));
353 break;
354 case ARG_CONTRAST:
355 g_value_set_int (value, qc_getcontrast (src->qcam));
356 break;
357 case ARG_TOP:
358 g_value_set_int (value, qc_gettop (src->qcam));
359 break;
360 case ARG_LEFT:
361 g_value_set_int (value, qc_getleft (src->qcam));
362 break;
363 case ARG_TRANSFER_SCALE:
364 g_value_set_int (value, qc_gettransfer_scale (src->qcam));
365 break;
366 case ARG_DEPTH:
367 g_value_set_int (value, qc_getbitdepth (src->qcam));
368 break;
369 case ARG_PORT:
370 g_value_set_int (value, src->qcam->port);
371 break;
372 case ARG_AUTOEXP:
373 g_value_set_enum (value, src->autoexposure);
374 break;
375 default:
376 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
377 break;
378 }
379}
380
Jan Schmidt012dfb82005-09-05 17:20:29 +0000381static GstStateChangeReturn
382gst_qcamsrc_change_state (GstElement * element, GstStateChange transition)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000383{
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000384 g_return_val_if_fail (GST_IS_QCAMSRC (element), FALSE);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000385
Jan Schmidt012dfb82005-09-05 17:20:29 +0000386 switch (transition) {
387 case GST_STATE_CHANGE_READY_TO_NULL:
Stefan Kost36c2fc22005-10-12 14:29:55 +0000388 if (GST_OBJECT_FLAG_IS_SET (element, GST_QCAMSRC_OPEN))
Ronald S. Bultje2ccd6d42005-02-03 12:16:00 +0000389 gst_qcamsrc_close (GST_QCAMSRC (element));
390 break;
Jan Schmidt012dfb82005-09-05 17:20:29 +0000391 case GST_STATE_CHANGE_NULL_TO_READY:
Stefan Kost36c2fc22005-10-12 14:29:55 +0000392 if (!GST_OBJECT_FLAG_IS_SET (element, GST_QCAMSRC_OPEN)) {
Ronald S. Bultje2ccd6d42005-02-03 12:16:00 +0000393 GST_DEBUG ("opening");
394 if (!gst_qcamsrc_open (GST_QCAMSRC (element))) {
395 GST_DEBUG ("open failed");
Jan Schmidt012dfb82005-09-05 17:20:29 +0000396 return GST_STATE_CHANGE_FAILURE;
Ronald S. Bultje2ccd6d42005-02-03 12:16:00 +0000397 }
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000398 }
Ronald S. Bultje2ccd6d42005-02-03 12:16:00 +0000399 break;
400 default:
401 break;
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000402 }
403
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000404 if (GST_ELEMENT_CLASS (parent_class)->change_state)
Jan Schmidt012dfb82005-09-05 17:20:29 +0000405 return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000406
Jan Schmidt012dfb82005-09-05 17:20:29 +0000407 return GST_STATE_CHANGE_SUCCESS;
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000408}
409
410static gboolean
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000411gst_qcamsrc_open (GstQCamSrc * qcamsrc)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000412{
413 if (qc_open (qcamsrc->qcam)) {
Ronald S. Bultje2ccd6d42005-02-03 12:16:00 +0000414 GST_ELEMENT_ERROR (qcamsrc, RESOURCE, OPEN_READ, (NULL),
415 ("Failed to open QuickCam"));
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000416 return FALSE;
417 }
418
Stefan Kost36c2fc22005-10-12 14:29:55 +0000419 GST_OBJECT_FLAG_SET (qcamsrc, GST_QCAMSRC_OPEN);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000420
421 return TRUE;
422}
423
424static void
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000425gst_qcamsrc_close (GstQCamSrc * src)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000426{
427 qc_close (src->qcam);
Stefan Kost36c2fc22005-10-12 14:29:55 +0000428 GST_OBJECT_FLAG_UNSET (src, GST_QCAMSRC_OPEN);
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000429}
430
431static gboolean
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000432plugin_init (GstPlugin * plugin)
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000433{
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000434 if (!gst_element_register (plugin, "qcamsrc", GST_RANK_NONE,
Thomas Vander Stichele4fd57bb2004-03-15 19:32:27 +0000435 GST_TYPE_QCAMSRC))
Benjamin Otteeabfbf12003-11-02 14:47:52 +0000436 return FALSE;
Thomas Vander Stichelebb8c1082001-12-17 19:03:13 +0000437
438 return TRUE;
439}
440
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000441GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
442 GST_VERSION_MINOR,
Sebastian Drögecda192b2012-04-05 18:02:56 +0200443 qcamsrc,
Thomas Vander Stichele7a778ee2004-03-14 22:34:33 +0000444 "Read from a QuickCam device",
Thomas Vander Stichele60f80592006-04-01 10:09:11 +0000445 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)