b189d9258dee8a518a7a8fc853cd0e6602cc09fa
[adaptation/intel_mfld/gst-plugins-atomisp.git] / gst / mfldv4l2cam / gstv4l2camsrc.c
1 /* GStreamer V4L2 camera source
2  * Copyright (C) 2010 Nokia Corporation <multimedia@maemo.org>
3  *               2010 Intel Corporation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * SECTION:element-mfldcamsrc
23  * @short_description: Medfield V4L2 camera source
24  * @see_also: #GstCameraSrc
25  *
26  * <refsect2>
27  * <para>
28  * Bla bla...
29  * </para>
30  * <para>
31  * Foo bar
32  * </para>
33  * <title>Example launch line</title>
34  * <para>
35  * <programlisting>
36  * gst-launch mfldv4l2camsrc ! xvimagesink
37  * </programlisting>
38  * </para>
39  * </refsect2>
40  */
41
42 #include <string.h>
43
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47
48 #include <linux/videodev2.h>
49 #include "gstv4l2camsrc.h"
50 #include "v4l2camsrc_calls.h"
51 #include "gstv4l2camvidorient.h"
52 #include <mfld_cam.h>
53
54 #define MFLD_ADVCI_PATH "/usr/lib/"
55 #define MFLD_V4L2CAMSRC_VERSION "85de990a519ae021f0bf4ec89c0e352ec76f6965"
56 #define FOCUS_POSITION_MIN      0
57 #define FOCUS_POSITION_MAX      512
58
59 GST_DEBUG_CATEGORY (gst_v4l2camsrc_debug);
60 #define GST_CAT_DEFAULT gst_v4l2camsrc_debug
61
62 static gboolean gst_v4l2camsrc_is_open (GstCameraSrc * camsrc);
63 static void gst_v4l2camsrc_finalize (GObject * object);
64 static void gst_v4l2camsrc_dispose (GObject * object);
65 static void gst_v4l2camsrc_set_property (GObject * object,
66     guint prop_id, const GValue * value, GParamSpec * pspec);
67 static void gst_v4l2camsrc_get_property (GObject * object,
68     guint prop_id, GValue * value, GParamSpec * pspec);
69 static gboolean gst_v4l2camsrc_unlock (GstCameraSrc * src);
70 static gboolean gst_v4l2camsrc_unlock_stop (GstCameraSrc * src);
71 static gboolean gst_v4l2camsrc_set_zoom (GstCameraSrc * camsrc, gfloat zoom);
72 static gboolean gst_v4l2camsrc_set_ae_mode (GstCameraSrc * camsrc, int mode);
73 static gboolean gst_v4l2camsrc_get_ae_mode (GstCameraSrc * camsrc, int *mode);
74
75 static gboolean gst_v4l2camsrc_iface_supported (GstImplementsInterface * iface,
76     GType iface_type);
77 static gboolean gst_v4l2camsrc_get_makernote (GstCameraSrc * camsrc, unsigned char *buf, unsigned size);
78 static gboolean gst_v4l2camsrc_makernote_init(GstCameraSrc * camsrc,
79                                                       unsigned * buf_size,
80                                                       unsigned num_afwindows,
81                                                       unsigned num_faces,
82                                                       unsigned num_eyes,
83                                                       unsigned num_grid,
84                                                       int *handle);
85 static gboolean gst_v4l2camsrc_makernote_deal(GstCameraSrc * camsrc,
86                                                       GstBuffer *pmakerbuf,
87                                                       unsigned num_afwindows,
88                                                       unsigned num_grid,
89                                                       int handle);
90 static gboolean gst_v4l2camsrc_makernote_uninit(GstCameraSrc * camsrc,
91                                                         int handle);
92
93 typedef enum
94 {
95   PROP_0,
96   PROP_DEVICE,
97   PROP_DEVICE_FD,
98   PROP_DEVICE_NAME,
99   PROP_QUEUE_SIZE,
100   PROP_INPUT_SENSOR,
101   PROP_USE_MMAP,
102   PROP_USE_COPY,
103   PROP_AE,
104   PROP_AE_METERING_MODE,
105   PROP_AE_WINDOW,
106   PROP_AE_MODE,
107   PROP_AF,
108   PROP_AF_METERING_MODE,
109   PROP_AF_WINDOW,
110   PROP_AWB,
111   PROP_STILL_AF,
112   PROP_FOCUS_POSITION,
113   PROP_VFLIP,
114   PROP_HFLIP,
115   PROP_BAYER_DOWNSCALING,
116   PROP_CAPTURE_CORRECTION_GDC,
117   PROP_CAPTURE_CORRECTION_CAC,
118   PROP_CAPTURE_CORRECTION_RER,
119   PROP_CAPTURE_CORRECTION_DIS,
120   PROP_CAPTURE_CORRECTION_DVS,
121   PROP_CAPTURE_CORRECTION_EDGE_ENHANCEMENT,
122   PROP_CAPTURE_CORRECTION_SHADING_CORRECTION,
123   PROP_CAPTURE_CORRECTION_BLACK_LEVEL_COMPENSATION,
124   PROP_CAPTURE_CORRECTION_BAD_PIXEL_DETECTION,
125   PROP_CAPTURE_CORRECTION_GAMMA,
126   PROP_CAPTURE_CORRECTION_CONTRAST,
127   PROP_CAPTURE_CORRECTION_BRIGHTNESS,
128   PROP_DUMP_RAW,
129   PROP_DUMP_IMAGE,
130   PROP_DEBUG_FLAGS,
131   PROP_DISABLE_LOW_RES_CROP,
132   PROP_DRAW_CORNER_MARKERS,
133 } GstV4L2CamSrcProperties;
134
135
136
137
138 #define DEFAULT_PROP_DEVICE_NAME  NULL
139 #define DEFAULT_PROP_DEVICE       "/dev/video0"
140 #define DEFAULT_PROP_DEVICE_FD    -1
141 #define DEFAULT_PROP_AE_WINDOW  "x_left=0,x_right=0,y_bottom=0,y_top=0"
142 #define DEFAULT_PROP_AF_WINDOW  "x_left=0,x_right=0,y_bottom=0,y_top=0"
143 #define DEFAULT_DEBUG_FLAGS     0
144 #define C_FLAGS(v) ((guint) v)
145
146
147 static const char* surface_string =
148     "video/x-vaapi-sharing, "
149     "type = vaapi, "
150     "width  = (int) [ 1, MAX ], "
151     "height = (int) [ 1, MAX ], "
152     "framerate = (fraction) [ 0, MAX ]";
153
154
155 GType
156 gst_camera_input_sensor_get_type (void)
157 {
158   static GType gst_camera_input_sensor_type = 0;
159   static GEnumValue gst_camera_input_sensors[] = {
160     {GST_CAMERA_INPUT_SENSOR_PRIMARY, "Primary Sensor", "primary"},
161     {GST_CAMERA_INPUT_SENSOR_SECONDARY, "Sencondary Sensor", "second"},
162     {0, NULL, NULL},
163   };
164
165   if (G_UNLIKELY (!gst_camera_input_sensor_type)) {
166     gst_camera_input_sensor_type =
167         g_enum_register_static ("GstCameraInputSensor",
168         gst_camera_input_sensors);
169   }
170   return gst_camera_input_sensor_type;
171 }
172
173 GType
174 gst_camera_ae_metering_mode_get_type(void)
175 {
176   static GType gst_camera_ae_metering_mode_type = 0;
177   static GEnumValue gst_camera_ae_metering_mode[] = {
178     {GST_CAMERA_AE_METERING_AUTO, "AE auto metering", "auto"},
179     {GST_CAMERA_AE_METERING_SPOT, "AE spot metering", "spot"},
180     {GST_CAMERA_AE_METERING_CENTER, "AE center metering", "center"},
181     {GST_CAMERA_AE_METERING_CUSTOMIZED, "AE customized metering", "customized"},
182     {0, NULL, NULL},
183   };
184
185   if (G_UNLIKELY (!gst_camera_ae_metering_mode_type)) {
186     gst_camera_ae_metering_mode_type=
187         g_enum_register_static ("GstCameraAEMeteringMode",
188         gst_camera_ae_metering_mode);
189   }
190   return  gst_camera_ae_metering_mode_type;
191 }
192
193 GType
194 gst_camera_ae_mode_get_type(void)
195 {
196   static GType gst_camera_ae_mode_type = 0;
197   static GEnumValue gst_camera_ae_mode[] = {
198     {GST_CAMERA_AE_MODE_AUTO, "AE auto", "auto"},
199     {GST_CAMERA_AE_MODE_MANUAL, "AE manual", "manual"},
200     {GST_CAMERA_AE_MODE_SHUTTER_PRIORITY, "AE shutter priority", "shutter"},
201     {GST_CAMERA_AE_MODE_APERTURE_PRIORITY, "AE aperture priority", "aperture"},
202     {0, NULL, NULL},
203   };
204
205   if (G_UNLIKELY (!gst_camera_ae_mode_type)) {
206     gst_camera_ae_mode_type=
207         g_enum_register_static ("GstCameraAEMode",
208         gst_camera_ae_mode);
209   }
210   return  gst_camera_ae_mode_type;
211 }
212
213 GType
214 gst_camera_af_metering_mode_get_type(void)
215 {
216   static GType gst_camera_af_metering_mode_type = 0;
217   static GEnumValue gst_camera_af_metering_mode[] = {
218     {GST_CAMERA_AF_METERING_AUTO, "AF auto metering", "auto"},
219     {GST_CAMERA_AF_METERING_SPOT, "AF spot metering", "spot"},
220     {GST_CAMERA_AF_METERING_CENTER, "AF center metering", "center"},
221     {GST_CAMERA_AF_METERING_CUSTOMIZED, "AF customized metering", "customized"},
222     {0, NULL, NULL},
223   };
224
225   if (G_UNLIKELY (!gst_camera_af_metering_mode_type)) {
226     gst_camera_af_metering_mode_type=
227         g_enum_register_static ("GstCameraAFMeteringMode",
228         gst_camera_af_metering_mode);
229   }
230   return  gst_camera_af_metering_mode_type;
231 }
232
233 GType
234 gst_camerasrc_debug_flags_get_type (void)
235 {
236   static GType gst_camerasrc_debug_flags = 0;
237   static const GFlagsValue values [] = {
238     {C_FLAGS (GST_CAMERASRC_DEBUG_FLAGS_PERFORMANCE), "Debug flags for performance tuning",
239       "performance"},
240     {C_FLAGS (GST_CAMERASRC_DEBUG_FLAGS_MAKER_NOTE), "Debug flags for maker note",
241       "maker-note"},
242     {C_FLAGS (GST_CAMERASRC_DEBUG_FLAGS_AUTO_FOCUS), "Debug flags for auto focus",
243       "auto-focus"},
244     {0, NULL, NULL},
245   };
246
247   if (G_UNLIKELY (!gst_camerasrc_debug_flags)) {
248     gst_camerasrc_debug_flags =
249         g_flags_register_static ("GstCameraSrcDebugFlags", values);
250   }
251   return  gst_camerasrc_debug_flags;
252 }
253
254
255
256 GST_IMPLEMENT_V4L2CAMSRC_VIDORIENT_METHODS (GstMFLDV4l2CamSrc, gst_v4l2camsrc);
257
258
259 static void
260 gst_v4l2camsrc_interface_init (GstImplementsInterfaceClass * klass)
261 {
262   /*
263    * default virtual functions
264    */
265   klass->supported = gst_v4l2camsrc_iface_supported;
266 }
267
268 void
269 gst_v4l2camsrc_init_interfaces (GType type)
270 {
271   static const GInterfaceInfo v4l2camsrc_iface_info = {
272     (GInterfaceInitFunc) gst_v4l2camsrc_interface_init,
273     NULL,
274     NULL,
275   };
276   static const GInterfaceInfo v4l2camsrc_videoorientation_info = {
277     (GInterfaceInitFunc) gst_v4l2camsrc_video_orientation_interface_init,
278     NULL,
279     NULL,
280   };
281
282   g_type_add_interface_static (type,
283       GST_TYPE_IMPLEMENTS_INTERFACE, &v4l2camsrc_iface_info);
284   g_type_add_interface_static (type,
285       GST_TYPE_VIDEO_ORIENTATION, &v4l2camsrc_videoorientation_info);
286 }
287
288
289 GST_BOILERPLATE_FULL (GstMFLDV4l2CamSrc, gst_v4l2camsrc, GstCameraSrc,
290     GST_TYPE_CAMERA_SRC, gst_v4l2camsrc_init_interfaces);
291
292
293
294 static gboolean
295 gst_v4l2camsrc_iface_supported (GstImplementsInterface * iface,
296     GType iface_type)
297 {
298   GstCameraSrc *camsrc = GST_CAMERA_SRC (iface);
299
300   if (gst_v4l2camsrc_is_open (camsrc) &&
301       iface_type == GST_TYPE_VIDEO_ORIENTATION) {
302     return TRUE;
303   }
304
305   else if (GST_IS_IMPLEMENTS_INTERFACE (camsrc)) {
306     GstImplementsInterfaceClass *parent_klass;
307
308     parent_klass =
309         g_type_interface_peek (parent_class, GST_TYPE_IMPLEMENTS_INTERFACE);
310     return parent_klass->supported (iface, iface_type);
311   }
312
313   return FALSE;
314 }
315
316
317 /*
318  * gst_v4l2camsrc_is_open:
319  *
320  */
321 static gboolean
322 gst_v4l2camsrc_is_open (GstCameraSrc * camsrc)
323 {
324   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc);
325
326   return GST_V4L2CAMSRC_IS_OPEN (v4l2camsrc);
327 }
328
329 /*
330  * gst_v4l2camsrc_is_active:
331  *
332  */
333 static gboolean
334 gst_v4l2camsrc_is_active (GstCameraSrc * camsrc)
335 {
336   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc);
337
338   return GST_V4L2CAMSRC_IS_ACTIVE (v4l2camsrc);
339 }
340
341 /*
342  * gst_v4l2camsrc_v4l2fourcc_to_structure:
343  *
344  */
345 static GstStructure *
346 gst_v4l2camsrc_v4l2fourcc_to_structure (guint32 fourcc)
347 {
348   GstStructure *structure = NULL;
349
350   switch (fourcc) {
351     case V4L2_PIX_FMT_MJPEG:   /* Motion-JPEG */
352     case V4L2_PIX_FMT_JPEG:    /* JFIF JPEG */
353       structure = gst_structure_new ("image/jpeg", NULL);
354       break;
355     case V4L2_PIX_FMT_RGB332:
356     case V4L2_PIX_FMT_RGB555:
357     case V4L2_PIX_FMT_RGB555X:
358     case V4L2_PIX_FMT_RGB565:
359     case V4L2_PIX_FMT_RGB565X:
360     case V4L2_PIX_FMT_RGB24:
361     case V4L2_PIX_FMT_BGR24:
362     case V4L2_PIX_FMT_RGB32:
363     case V4L2_PIX_FMT_BGR32:{
364       guint depth = 0, bpp = 0;
365
366       gint endianness = 0;
367
368       guint32 r_mask = 0, b_mask = 0, g_mask = 0;
369
370       switch (fourcc) {
371         case V4L2_PIX_FMT_RGB332:
372           bpp = depth = 8;
373           endianness = G_BYTE_ORDER;    /* 'like, whatever' */
374           r_mask = 0xe0;
375           g_mask = 0x1c;
376           b_mask = 0x03;
377           break;
378         case V4L2_PIX_FMT_RGB555:
379         case V4L2_PIX_FMT_RGB555X:
380           bpp = 16;
381           depth = 15;
382           endianness =
383               fourcc == V4L2_PIX_FMT_RGB555X ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
384           r_mask = 0x7c00;
385           g_mask = 0x03e0;
386           b_mask = 0x001f;
387           break;
388         case V4L2_PIX_FMT_RGB565:
389         case V4L2_PIX_FMT_RGB565X:
390           bpp = depth = 16;
391           endianness =
392               fourcc == V4L2_PIX_FMT_RGB565X ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
393           r_mask = 0xf800;
394           g_mask = 0x07e0;
395           b_mask = 0x001f;
396           break;
397         case V4L2_PIX_FMT_RGB24:
398           bpp = depth = 24;
399           endianness = G_BIG_ENDIAN;
400           r_mask = 0xff0000;
401           g_mask = 0x00ff00;
402           b_mask = 0x0000ff;
403           break;
404         case V4L2_PIX_FMT_BGR24:
405           bpp = depth = 24;
406           endianness = G_BIG_ENDIAN;
407           r_mask = 0x0000ff;
408           g_mask = 0x00ff00;
409           b_mask = 0xff0000;
410           break;
411         case V4L2_PIX_FMT_RGB32:
412           bpp = depth = 32;
413           endianness = G_BIG_ENDIAN;
414           r_mask = 0xff000000;
415           g_mask = 0x00ff0000;
416           b_mask = 0x0000ff00;
417           break;
418         case V4L2_PIX_FMT_BGR32:
419           bpp = depth = 32;
420           endianness = G_BIG_ENDIAN;
421           r_mask = 0x000000ff;
422           g_mask = 0x0000ff00;
423           b_mask = 0x00ff0000;
424           break;
425         default:
426           g_assert_not_reached ();
427           break;
428       }
429       structure = gst_structure_new ("video/x-raw-rgb",
430           "bpp", G_TYPE_INT, bpp,
431           "depth", G_TYPE_INT, depth,
432           "red_mask", G_TYPE_INT, r_mask,
433           "green_mask", G_TYPE_INT, g_mask,
434           "blue_mask", G_TYPE_INT, b_mask,
435           "endianness", G_TYPE_INT, endianness, NULL);
436       break;
437     }
438     case V4L2_PIX_FMT_GREY:    /*  8  Greyscale     */
439       structure = gst_structure_new ("video/x-raw-gray",
440           "bpp", G_TYPE_INT, 8, NULL);
441       break;
442     case V4L2_PIX_FMT_YYUV:    /* 16  YUV 4:2:2     */
443     case V4L2_PIX_FMT_HI240:   /*  8  8-bit color   */
444       /* FIXME: get correct fourccs here */
445       break;
446     case V4L2_PIX_FMT_NV12:    /* 12  Y/CbCr 4:2:0  */
447     case V4L2_PIX_FMT_NV21:    /* 12  Y/CrCb 4:2:0  */
448     case V4L2_PIX_FMT_NV61:
449     case V4L2_PIX_FMT_NV16:
450     case V4L2_PIX_FMT_YVU410:
451     case V4L2_PIX_FMT_YUV410:
452     case V4L2_PIX_FMT_YUV420:  /* I420/IYUV */
453     case V4L2_PIX_FMT_YUYV:
454     case V4L2_PIX_FMT_YVU420:
455     case V4L2_PIX_FMT_UYVY:
456     case V4L2_PIX_FMT_Y41P:
457     case V4L2_PIX_FMT_YUV422P:
458     case V4L2_PIX_FMT_YUV444:
459 #ifdef V4L2_PIX_FMT_YVYU
460     case V4L2_PIX_FMT_YVYU:
461 #endif
462     case V4L2_PIX_FMT_YUV411P:{
463       guint32 fcc = 0;
464
465       switch (fourcc) {
466         case V4L2_PIX_FMT_NV12:
467           fcc = GST_MAKE_FOURCC ('N', 'V', '1', '2');
468           break;
469         case V4L2_PIX_FMT_NV21:
470           fcc = GST_MAKE_FOURCC ('N', 'V', '2', '1');
471           break;
472         case V4L2_PIX_FMT_NV16:
473           fcc = GST_MAKE_FOURCC ('N', 'V', '1', '6');
474           break;
475         case V4L2_PIX_FMT_NV61:
476           fcc = GST_MAKE_FOURCC ('N', 'V', '6', '1');
477           break;
478         case V4L2_PIX_FMT_YVU410:
479           fcc = GST_MAKE_FOURCC ('Y', 'V', 'U', '9');
480           break;
481         case V4L2_PIX_FMT_YUV410:
482           fcc = GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
483           break;
484         case V4L2_PIX_FMT_YUV420:
485           fcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
486           break;
487         case V4L2_PIX_FMT_YUYV:
488           fcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
489           break;
490         case V4L2_PIX_FMT_YVU420:
491           fcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
492           break;
493         case V4L2_PIX_FMT_UYVY:
494           fcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
495           break;
496         case V4L2_PIX_FMT_Y41P:
497           fcc = GST_MAKE_FOURCC ('Y', '4', '1', 'P');
498           break;
499         case V4L2_PIX_FMT_YUV411P:
500           fcc = GST_MAKE_FOURCC ('Y', '4', '1', 'B');
501           break;
502         case V4L2_PIX_FMT_YUV422P:
503           fcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
504           break;
505         case V4L2_PIX_FMT_YUV444:
506           fcc = GST_MAKE_FOURCC ('Y', '4', '4', '4');
507           break;
508 #ifdef V4L2_PIX_FMT_YVYU
509         case V4L2_PIX_FMT_YVYU:
510           fcc = GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U');
511           break;
512 #endif
513         default:
514           g_assert_not_reached ();
515           break;
516       }
517       structure = gst_structure_new ("video/x-raw-yuv",
518           "format", GST_TYPE_FOURCC, fcc, NULL);
519       break;
520     }
521     case V4L2_PIX_FMT_SBGGR8:
522     case V4L2_PIX_FMT_SGBRG8:
523     case V4L2_PIX_FMT_SGRBG8:
524     case V4L2_PIX_FMT_SRGGB8:
525     case V4L2_PIX_FMT_SBGGR10:
526     case V4L2_PIX_FMT_SGBRG10:
527     case V4L2_PIX_FMT_SGRBG10:
528     case V4L2_PIX_FMT_SRGGB10:
529 #ifdef V4L2_PIX_FMT_SBGGR16
530     case V4L2_PIX_FMT_SBGGR16:{
531 #endif
532       guint32 fcc = 0;
533       switch (fourcc) {
534         case V4L2_PIX_FMT_SBGGR8:
535           fcc = GST_MAKE_FOURCC ('B', 'A', '8', '1');
536           break;
537         case V4L2_PIX_FMT_SGBRG8:
538           fcc = GST_MAKE_FOURCC ('G', 'B', 'R', 'G');
539           break;
540         case V4L2_PIX_FMT_SGRBG8:
541           fcc = GST_MAKE_FOURCC ('G', 'R', 'B', 'G');
542           break;
543         case V4L2_PIX_FMT_SRGGB8:
544           fcc = GST_MAKE_FOURCC ('R', 'G', 'G', 'B');
545           break;
546         case V4L2_PIX_FMT_SBGGR10:
547           fcc = GST_MAKE_FOURCC ('B', 'G', '1', '0');
548           break;
549         case V4L2_PIX_FMT_SGBRG10:
550           fcc = GST_MAKE_FOURCC ('G', 'B', '1', '0');
551           break;
552         case V4L2_PIX_FMT_SGRBG10:
553           fcc = GST_MAKE_FOURCC ('B', 'A', '1', '0');
554           break;
555         case V4L2_PIX_FMT_SRGGB10:
556           fcc = GST_MAKE_FOURCC ('R', 'G', '1', '0');
557           break;
558         case V4L2_PIX_FMT_SBGGR16:
559           fcc = GST_MAKE_FOURCC ('B', 'Y', 'R', '2');
560           break;
561         default:
562           g_assert_not_reached ();
563           break;
564       }
565       structure = gst_structure_new ("video/x-raw-bayer",
566           "format", GST_TYPE_FOURCC, fcc, NULL);
567       break;
568     }
569     default:
570       GST_DEBUG ("Unknown fourcc 0x%08x %" GST_FOURCC_FORMAT,
571           fourcc, GST_FOURCC_ARGS (fourcc));
572       break;
573   }
574
575   return structure;
576 }
577
578 /*
579  * gst_v4l2camsrc_get_caps:
580  *
581  */
582 static GstCaps *
583 gst_v4l2camsrc_get_caps (GstCameraSrc * camsrc)
584 {
585   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc);
586   GstStructure *template;
587   GstCaps *ret;
588   GSList *walk;
589
590   if (!gst_v4l2camsrc_is_open (camsrc)) {
591     /* FIXME: should it probe the device? */
592     return NULL;
593   }
594
595   if (!v4l2camsrc->formats)
596     gst_v4l2camsrc_fill_format_list (v4l2camsrc);
597
598   ret = gst_caps_new_empty ();
599
600   for (walk = v4l2camsrc->formats; walk; walk = walk->next) {
601     struct v4l2_fmtdesc *format;
602
603     /* FIXME: Introduce own format structure */
604     format = (struct v4l2_fmtdesc *) walk->data;
605
606     template = gst_v4l2camsrc_v4l2fourcc_to_structure (format->pixelformat);
607
608     if (template) {
609       GstCaps *tmp;
610
611       tmp = gst_v4l2camsrc_probe_caps_for_format (v4l2camsrc,
612           format->pixelformat, template);
613       if (tmp)
614         gst_caps_append (ret, tmp);
615
616       gst_structure_free (template);
617     } else {
618       GST_DEBUG_OBJECT (v4l2camsrc, "unknown format %u", format->pixelformat);
619     }
620   }
621
622   GstStructure * structure = gst_structure_from_string(surface_string, NULL);
623   gst_caps_append_structure (ret, structure);
624
625   v4l2camsrc->probed_caps = gst_caps_ref (ret);
626
627   GST_INFO_OBJECT(v4l2camsrc, "use GST_DEBUG >= 5 for probed caps");
628   GST_LOG_OBJECT (v4l2camsrc, "probed caps: %" GST_PTR_FORMAT, ret);
629
630   return ret;
631 }
632
633 /*
634  * gst_v4l2camsrc_get_num_buffers:
635  *
636  */
637 static guint
638 gst_v4l2camsrc_get_num_buffers (GstCameraSrc * camsrc)
639 {
640   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc);
641
642   return v4l2camsrc->num_buffers;
643 }
644
645 /*
646  * common format / caps utilities:
647  */
648 typedef struct
649 {
650   guint32 format;
651   gboolean dimensions;
652 } GstV4L2FormatDesc;
653
654 static const GstV4L2FormatDesc gst_v4l2_formats[] = {
655   /* from Linux 2.6.15 videodev2.h */
656   {V4L2_PIX_FMT_YUV420, TRUE},
657   {V4L2_PIX_FMT_YVU420, TRUE},
658   {V4L2_PIX_FMT_YUV422P, TRUE},
659   {V4L2_PIX_FMT_YUV444, TRUE},
660
661   {V4L2_PIX_FMT_NV12, TRUE},
662   {V4L2_PIX_FMT_NV21, TRUE},
663
664   {V4L2_PIX_FMT_NV16, TRUE},
665   {V4L2_PIX_FMT_NV61, TRUE},
666
667   {V4L2_PIX_FMT_YUYV, TRUE},
668   {V4L2_PIX_FMT_UYVY, TRUE},
669
670   {V4L2_PIX_FMT_SBGGR16, TRUE},
671
672   {V4L2_PIX_FMT_SBGGR8, TRUE},
673   {V4L2_PIX_FMT_SGBRG8, TRUE},
674   {V4L2_PIX_FMT_SGRBG8, TRUE},
675   {V4L2_PIX_FMT_SRGGB8, TRUE},
676
677   {V4L2_PIX_FMT_SBGGR10, TRUE},
678   {V4L2_PIX_FMT_SGBRG10, TRUE},
679   {V4L2_PIX_FMT_SGRBG10, TRUE},
680   {V4L2_PIX_FMT_SRGGB10, TRUE},
681
682   {V4L2_PIX_FMT_RGB24, TRUE},
683   {V4L2_PIX_FMT_RGB32, TRUE},
684   {V4L2_PIX_FMT_RGB565, TRUE},
685 };
686
687 #define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats))
688 #define GST_V4L2_MAX_SIZE (1<<15)       /* 2^15 == 32768 */
689
690 GstCaps *
691 gst_v4l2camsrc_get_all_caps (void)
692 {
693   static GstCaps *caps = NULL;
694
695   if (caps == NULL) {
696     GstStructure *structure;
697
698     guint i;
699
700     caps = gst_caps_new_empty ();
701     for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {
702       structure =
703           gst_v4l2camsrc_v4l2fourcc_to_structure (gst_v4l2_formats[i].format);
704       if (structure) {
705         if (gst_v4l2_formats[i].dimensions) {
706           gst_structure_set (structure,
707               "width", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
708               "height", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
709               "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1, NULL);
710         }
711         gst_caps_append_structure (caps, structure);
712       }
713     }
714     structure = gst_structure_from_string(surface_string, NULL);
715     gst_caps_append_structure (caps, structure);
716   }
717
718   return gst_caps_ref (caps);
719 }
720
721
722 /*
723  * gst_v4l2camsrc_base_init:
724  * @klass: #GstElementClass.
725  *
726  */
727 static void
728 gst_v4l2camsrc_base_init (gpointer klass)
729 {
730   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
731
732   gst_element_class_set_details_simple (element_class,
733       "V4L2 camera source",
734       "Video/Src",
735       "Video4Linux2 camera source element",
736       "Maemo Multimedia <multimedia@maemo.org>");
737
738   gst_element_class_add_pad_template (element_class,
739       gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
740           gst_v4l2camsrc_get_all_caps ()));
741 }
742
743 gboolean gst_v4l2camsrc_set_autofocus (GstCameraSrc * camsrc, gboolean on);
744 gboolean gst_v4l2camsrc_set_autoexposure (GstCameraSrc * camsrc, gboolean on);
745 GstPhotoCaps gst_v4l2camsrc_get_capabilities (GstCameraSrc * camsrc);
746 gboolean gst_v4l2camsrc_set_capture_mode (GstCameraSrc * camsrc,
747     GstCameraSrcCaptureMode mode);
748 gboolean
749 gst_v4l2camsrc_read_settings (GstCameraSrc * camsrc,
750     GstPhotoSettings * photoconf);
751 gboolean gst_v4l2camsrc_write_settings (GstCameraSrc * camsrc,
752     GstPhotoSettings * photoconf, gboolean scene_override);
753 gboolean
754 gst_v4l2camsrc_set_flash_mode (GstCameraSrc *camsrc, int value);
755 gboolean
756 gst_v4l2camsrc_read_exif (GstCameraSrc *camsrc, 
757     GstCameraControlExifInfo *exif_info);
758 gboolean
759 gst_v4l2camsrc_set_strobe_state (GstCameraSrc *camsrc, gboolean state);
760
761 gboolean 
762 gst_v4l2camsrc_set_AeAafwindow (GstCameraSrc * camsrc, GstCameraSrc3a_window window);
763
764 /*
765  * gst_v4l2camsrc_class_init:
766  * @klass: #GstMFLDV4l2CamSrcClass.
767  *
768  */
769 static void
770 gst_v4l2camsrc_class_init (GstMFLDV4l2CamSrcClass * klass)
771 {
772   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
773   GstCameraSrcClass *camera_class = GST_CAMERA_SRC_CLASS (klass);
774
775   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_property);
776   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_get_property);
777   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_dispose);
778   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_finalize);
779
780   g_object_class_install_property (gobject_class, PROP_DEVICE,
781       g_param_spec_string ("device", "Device", "Device location",
782           DEFAULT_PROP_DEVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
783
784   g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
785       g_param_spec_string ("device-name", "Device name",
786           "Name of the device", DEFAULT_PROP_DEVICE_NAME,
787           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
788
789   g_object_class_install_property (gobject_class, PROP_DEVICE_FD,
790       g_param_spec_int ("device-fd", "File descriptor",
791           "File descriptor of the device", -1, G_MAXINT, DEFAULT_PROP_DEVICE_FD,
792           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
793
794   g_object_class_install_property (gobject_class, PROP_QUEUE_SIZE,
795       g_param_spec_uint ("queue-size", "Queue size",
796           "Number of buffers to be enqueud in the driver",
797           GST_V4L2CAMSRC_MIN_BUFFERS, GST_V4L2CAMSRC_MAX_BUFFERS,
798           GST_V4L2CAMSRC_DEFAULT_BUFFERS,
799           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
800
801   g_object_class_install_property (gobject_class, PROP_INPUT_SENSOR,
802       g_param_spec_enum ("camera-id", "Camera Id",
803           "Which sensor is the input of the ISP",
804           GST_TYPE_CAMERA_INPUT_SENSOR,
805           GST_CAMERA_INPUT_SENSOR_PRIMARY,
806           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
807
808   g_object_class_install_property (gobject_class, PROP_USE_MMAP,
809       g_param_spec_boolean ("use-mmap", "Use Mmap",
810           "Whether use mmap memory method", FALSE, G_PARAM_READWRITE));
811
812   g_object_class_install_property (gobject_class, PROP_USE_COPY,
813       g_param_spec_boolean ("use-copy", "Use Copy",
814           "Whether copy the buffer from driver, debug only", FALSE, G_PARAM_READWRITE));
815
816   /* AE, AF, and AWB settings */
817   g_object_class_install_property (gobject_class, PROP_AE,
818       g_param_spec_boolean ("ae", "Auto Exposure",
819           "Auto Exposure is On or Off", TRUE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
820
821   g_object_class_install_property (gobject_class, PROP_AE_METERING_MODE,
822       g_param_spec_enum ("ae-metering-mode", "AE Metering Mode",
823           "Select AE Metering Mode",
824           GST_TYPE_CAMERA_AE_METERING_MODE,
825           GST_CAMERA_AE_METERING_AUTO,
826           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
827
828   g_object_class_install_property (gobject_class, PROP_AE_MODE,
829       g_param_spec_enum ("ae-mode", "AE Mode",
830           "Select AE Mode",
831           GST_TYPE_CAMERA_AE_MODE,
832           GST_CAMERA_AE_MODE_AUTO,
833           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
834
835  g_object_class_install_property (gobject_class, PROP_AE_WINDOW,
836       g_param_spec_string("ae-window", "AE Window",
837           "Set AE Window Coordinates in format: x_left=value,x_right=value,"
838           "y_bottom=value,y_top=value",
839           DEFAULT_PROP_AE_WINDOW,
840           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
841
842
843   g_object_class_install_property (gobject_class, PROP_AF,
844       g_param_spec_boolean ("af", "Auto Focus",
845           "Auto Focus is On or Off", TRUE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
846
847   g_object_class_install_property (gobject_class, PROP_AF_METERING_MODE,
848       g_param_spec_enum ("af-metering-mode", "AF Metering Mode",
849           "Select AF Metering Mode",
850           GST_TYPE_CAMERA_AF_METERING_MODE,
851           GST_CAMERA_AF_METERING_AUTO,
852           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
853
854  g_object_class_install_property (gobject_class, PROP_AF_WINDOW,
855       g_param_spec_string("af-window", "AF Window",
856           "Set AF Window Coordinates in format: x_left=value,x_right=value,"
857           "y_bottom=value,y_top=value",
858           DEFAULT_PROP_AF_WINDOW,
859           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
860
861   g_object_class_install_property (gobject_class, PROP_AWB,
862       g_param_spec_boolean ("awb", "White Balance",
863           "White Balance is On or Off",
864           TRUE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
865
866   g_object_class_install_property (gobject_class, PROP_STILL_AF,
867       g_param_spec_boolean ("still-af", "still image slow focus",
868           "Turn On or Off slow focus when doing the still image capture",
869           TRUE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
870
871   g_object_class_install_property (gobject_class, PROP_FOCUS_POSITION,
872       g_param_spec_int ("focus-posi", "Focus Position",
873           "Focus absolute position set to Sensor.", FOCUS_POSITION_MIN,
874           FOCUS_POSITION_MAX, 0,
875           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
876
877   g_object_class_install_property (gobject_class, PROP_BAYER_DOWNSCALING,
878       g_param_spec_boolean ("bayer-downscaling", "Bayer Downscaling crop",
879           "Turn On or Off Bayer Downscaling", TRUE, G_PARAM_READWRITE));
880
881   /* These are advanced ISP features for MFLD camera only */
882   g_object_class_install_property (gobject_class, PROP_CAPTURE_CORRECTION_GDC,
883       g_param_spec_boolean ("GDC", "GDC",
884           "Capture Correction for Lens Geometry Distortion Correction",
885           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
886
887   g_object_class_install_property (gobject_class, PROP_CAPTURE_CORRECTION_CAC,
888       g_param_spec_boolean ("CAC", "CAC",
889           "Capture Correction for Chromatic Aberration Correction",
890           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
891
892   g_object_class_install_property (gobject_class, PROP_CAPTURE_CORRECTION_RER,
893       g_param_spec_boolean ("redeye-reduction", "Redeye reduction",
894           "Capture Correction for Redeye reduction",
895           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
896
897   g_object_class_install_property (gobject_class, PROP_CAPTURE_CORRECTION_DIS,
898       g_param_spec_boolean ("still-stable", "Still stabilization",
899           "Capture Correction for still image stabilization", FALSE,
900           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
901
902   g_object_class_install_property (gobject_class, PROP_CAPTURE_CORRECTION_DVS,
903       g_param_spec_boolean ("video-stable", "Video stabilization",
904           "Capture Correction for video capture stabilization", FALSE,
905           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
906
907   g_object_class_install_property (gobject_class,
908       PROP_CAPTURE_CORRECTION_EDGE_ENHANCEMENT,
909       g_param_spec_boolean ("edge-enhancement", "Edge Enhancement",
910           "Capture Correction for edge enhancement", TRUE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
911
912   g_object_class_install_property (gobject_class,
913       PROP_CAPTURE_CORRECTION_SHADING_CORRECTION,
914       g_param_spec_boolean ("shading-correction", "Shading Correction",
915           "Capture Correction for shading correction", TRUE,
916           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
917
918   g_object_class_install_property (gobject_class,
919       PROP_CAPTURE_CORRECTION_BLACK_LEVEL_COMPENSATION,
920       g_param_spec_boolean ("black-level-compensation", "Black Level Compensation",
921           "Capture Correction for Black Level Compensation", FALSE,
922           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
923
924   g_object_class_install_property (gobject_class,
925       PROP_CAPTURE_CORRECTION_BAD_PIXEL_DETECTION,
926       g_param_spec_boolean ("bad-pixel-detection", "Bad Pixel Detection",
927           "Capture Correction for Bad Pixel Detection", TRUE,
928           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
929
930   g_object_class_install_property (gobject_class, PROP_CAPTURE_CORRECTION_GAMMA,
931       g_param_spec_float ("gamma", "Gamma",
932           "Gamma Values", 1.0, 2.4, 2.2,
933           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
934
935   g_object_class_install_property (gobject_class,
936       PROP_CAPTURE_CORRECTION_CONTRAST, g_param_spec_int ("contrast",
937           "Contrast", "Contrast Values", 0, 2048, 256,
938           G_PARAM_READWRITE |G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
939
940   g_object_class_install_property (gobject_class,
941       PROP_CAPTURE_CORRECTION_BRIGHTNESS, g_param_spec_int ("brightness",
942           "Brightness", "Brightness Values", -255, 255, 0,
943           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
944
945   g_object_class_install_property (gobject_class, PROP_DUMP_RAW,
946       g_param_spec_boolean ("dump-raw", "Dump RAW images simultanious",
947           "Whether dump the raw images as output when during the jpeg capture",
948           FALSE, G_PARAM_READWRITE));
949
950   g_object_class_install_property (gobject_class, PROP_DUMP_IMAGE,
951       g_param_spec_boolean ("dump-image", "Dump images simultanious in pipeline",
952           "Whether dump the  images as output in pipeline, debug only,"
953           "output the image in current directory",
954           FALSE, G_PARAM_READWRITE));
955
956   g_object_class_install_property (gobject_class, PROP_DEBUG_FLAGS,
957       g_param_spec_flags ("debug-flags", "debug flags",
958           "debug flags for development and performance tuning usage",
959           GST_TYPE_CAMERASRC_DEBUG_FLAGS, DEFAULT_DEBUG_FLAGS,
960           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
961
962   g_object_class_install_property (gobject_class,
963       PROP_VFLIP,
964       g_param_spec_boolean ("vflip", "Vertical Flip",
965           "Vertical flip", FALSE,
966           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
967
968   g_object_class_install_property (gobject_class,
969       PROP_HFLIP,
970       g_param_spec_boolean ("hflip", "Horisontal Flip",
971           "Horisontal flip", FALSE,
972           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
973
974   g_object_class_install_property (gobject_class,
975       PROP_DISABLE_LOW_RES_CROP,
976       g_param_spec_boolean ("disable-low-res-crop", "disable low resolution crop",
977           "disable software crop on unsupported low resolution frame size", FALSE,
978           G_PARAM_READWRITE));
979
980   g_object_class_install_property (gobject_class,
981       PROP_DRAW_CORNER_MARKERS,
982       g_param_spec_boolean ("draw-corner-markers", "draw markers in frame corners",
983           "draw markers in frame corners", FALSE,
984           G_PARAM_READWRITE));
985
986   camera_class->is_open = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_is_open);
987   camera_class->open = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_open);
988   camera_class->close = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_close);
989   camera_class->get_attribute =
990       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_get_attribute);
991   camera_class->set_attribute =
992       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_attribute);
993   camera_class->set_capture = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_capture);
994   camera_class->start = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_capture_start);
995   camera_class->is_active = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_is_active);
996   camera_class->grab_frame = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_grab_frame);
997   camera_class->stop = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_capture_stop);
998   camera_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_get_caps);
999   camera_class->get_num_buffers =
1000       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_get_num_buffers);
1001   camera_class->unlock = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_unlock);
1002   camera_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_unlock_stop);
1003
1004   camera_class->set_capture_mode =
1005       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_capture_mode);
1006 //  camera_class->set_vfinder_mode = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_set_viewfinder_mode);
1007   camera_class->set_autofocus =
1008       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_autofocus);
1009   camera_class->set_autoexposure =
1010       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_autoexposure);
1011   camera_class->read_settings =
1012       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_read_settings);
1013   camera_class->write_settings =
1014       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_write_settings);
1015   camera_class->get_capabilities =
1016       GST_DEBUG_FUNCPTR (gst_v4l2camsrc_get_capabilities);
1017   camera_class->set_zoom = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_zoom);
1018   camera_class->set_AeAafwindow = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_AeAafwindow);
1019   camera_class->set_ae_mode = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_set_ae_mode);
1020   camera_class->get_ae_mode = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_get_ae_mode);
1021
1022   camera_class->get_makernote = GST_DEBUG_FUNCPTR (gst_v4l2camsrc_get_makernote);
1023   camera_class->makernote_init = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_makernote_init);
1024   camera_class->makernote_deal = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_makernote_deal);
1025   camera_class->makernote_uninit = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_makernote_uninit);
1026   camera_class->set_flash_mode = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_set_flash_mode);
1027   camera_class->read_exif = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_read_exif);
1028
1029   camera_class->set_strobe_state = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_set_strobe_state);
1030
1031 //camera_class->fill_image_tags = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_fill_image_tags);
1032 //camera_class->get_preview_image = GST_DEBUG_FUNCPTR(gst_v4l2camsrc_get_preview_image);
1033 }
1034
1035 /*
1036  * gst_v4l2camsrc_driver_wrapper_load:
1037  * Create the mfldadvci object. The function in libmfldadvci can
1038  * be called from this source element now
1039  */
1040 GstV4l2MFLDAdvCI *
1041 gst_v4l2camsrc_mfldadvci_wrapper_load (GstMFLDV4l2CamSrc * v4l2camsrc)
1042 {
1043   GstV4l2MFLDAdvCI *mfldadvci;
1044
1045   mfldadvci = g_new0 (GstV4l2MFLDAdvCI, 1);
1046   wrapper_default_link_functions_init(mfldadvci);
1047
1048 #ifdef USE_DYNAMIC_3A
1049   if (g_module_supported ()) {
1050     gchar *module_file;
1051     module_file = g_module_build_path (MFLD_ADVCI_PATH, "libmfldadvci.so.0");
1052     GST_DEBUG_OBJECT (v4l2camsrc, "Loading %s", module_file);
1053
1054     v4l2camsrc->module = g_module_open (module_file, G_MODULE_BIND_LOCAL);
1055
1056     /* Open again if libmfldadvci.so.0 doesn't exist */
1057     if (!v4l2camsrc->module) {
1058       module_file = g_module_build_path (MFLD_ADVCI_PATH, "libmfldadvci.so");
1059       v4l2camsrc->module = g_module_open (module_file, G_MODULE_BIND_LOCAL);
1060       GST_DEBUG_OBJECT (v4l2camsrc, "Loading %s", module_file);
1061     }
1062     GST_DEBUG_OBJECT(v4l2camsrc, "Camera Source Interface version is %d\n", LIBMFLDADVCI_VERSION);
1063     if (v4l2camsrc->module) {
1064       lib_3a_link_functions_init(mfldadvci, v4l2camsrc->module);
1065     }
1066   }
1067 #endif /* USE_DYNAMIC_3A */
1068
1069   return mfldadvci;
1070 }
1071
1072 /*
1073  * gst_v4l2camsrc_mfldadvci_wrapper_unload:
1074  * Unload the libmfldadvci and free its resource
1075  */
1076 void
1077 gst_v4l2camsrc_mfldadvci_wrapper_unload (GstMFLDV4l2CamSrc * v4l2camsrc)
1078 {
1079   GstV4l2MFLDAdvCI *mfldadvci = v4l2camsrc->mfldadvci;
1080
1081   GST_DEBUG ("mfldadvci unload");
1082   g_module_close (v4l2camsrc->module);
1083   v4l2camsrc->module = NULL;
1084
1085   g_free (mfldadvci);
1086
1087 }
1088
1089
1090
1091 /*
1092  * gst_v4l2camsrc_init:
1093  * @v4l2camsrc: #GstMFLDV4l2CamSrc.
1094  * @klass: #GstMFLDV4l2CamSrcClass.
1095  *
1096  */
1097 static void
1098 gst_v4l2camsrc_init (GstMFLDV4l2CamSrc * v4l2camsrc,
1099     GstMFLDV4l2CamSrcClass * klass)
1100 {
1101   v4l2camsrc->num_buffers = GST_V4L2CAMSRC_DEFAULT_BUFFERS;
1102   v4l2camsrc->tmp_num_buffers = v4l2camsrc->num_buffers;
1103   v4l2camsrc->videodev = g_strdup (DEFAULT_PROP_DEVICE);
1104   v4l2camsrc->video_fd = DEFAULT_PROP_DEVICE_FD;
1105   v4l2camsrc->poll = gst_poll_new (TRUE);
1106   v4l2camsrc->buffer = NULL;
1107   v4l2camsrc->crop_supported = FALSE;
1108   v4l2camsrc->max_zoom_factor = MAX_RESIZER_FACTOR;
1109   v4l2camsrc->zoom_factor = DEFAULT_RESIZER_FACTOR;
1110   v4l2camsrc->use_mmap = TRUE;
1111   v4l2camsrc->use_copy = FALSE;
1112   v4l2camsrc->capture_mode = GST_CAMERA_SRC_CAPTURE_MODE_VIEWFINDER;
1113   /* MFLD camera Advanced features status */
1114   v4l2camsrc->gdc_enabled = FALSE;
1115   v4l2camsrc->rer_enabled = FALSE;
1116   v4l2camsrc->cac_enabled = FALSE;
1117   v4l2camsrc->dvs_enabled = FALSE;
1118   v4l2camsrc->dis_enabled = FALSE;
1119   v4l2camsrc->ee_enabled = TRUE;
1120   v4l2camsrc->sc_enabled = TRUE;
1121   v4l2camsrc->cc_updated = FALSE;
1122   v4l2camsrc->gamma_updated = FALSE;
1123   v4l2camsrc->ae_enabled = TRUE;
1124   v4l2camsrc->af_enabled = TRUE;
1125   v4l2camsrc->awb_enabled = TRUE;
1126   v4l2camsrc->still_af = FALSE;
1127   v4l2camsrc->bayer_downscaling = FALSE;
1128   v4l2camsrc->tone.gamma = 2.2;
1129   v4l2camsrc->tone.brightness = 0;
1130   v4l2camsrc->tone.contrast = 256;
1131
1132   v4l2camsrc->preflash_enabled = FALSE;
1133   v4l2camsrc->capflash_enabled = FALSE;
1134   v4l2camsrc->preflash_analoggain = 0;
1135
1136   v4l2camsrc->dump_raw = FALSE;
1137   v4l2camsrc->dump_image = FALSE;
1138   v4l2camsrc->raw_output_size = 0;
1139   v4l2camsrc->debug_flags = DEFAULT_DEBUG_FLAGS;
1140   v4l2camsrc->disable_low_res_crop = FALSE;
1141   v4l2camsrc->draw_corner_markers = FALSE;
1142
1143   v4l2camsrc->device_mutex = g_mutex_new ();
1144
1145   v4l2camsrc->mfldadvci = gst_v4l2camsrc_mfldadvci_wrapper_load (v4l2camsrc);
1146
1147   v4l2camsrc->input_sensor = GST_CAMERA_INPUT_SENSOR_PRIMARY;
1148   v4l2camsrc->ae_metering_mode = GST_CAMERA_AE_METERING_AUTO;
1149   v4l2camsrc->ae_mode = GST_CAMERA_AE_MODE_AUTO;
1150   v4l2camsrc->af_metering_mode = GST_CAMERA_AF_METERING_AUTO;
1151
1152   v4l2camsrc->ae_window.x_left = 0;
1153   v4l2camsrc->ae_window.x_right = 0;
1154   v4l2camsrc->ae_window.y_bottom = 0;
1155   v4l2camsrc->ae_window.y_top = 0;
1156   v4l2camsrc->ae_window.weight= 0x8000;
1157   v4l2camsrc->af_window.x_left = 0;
1158   v4l2camsrc->af_window.x_right = 0;
1159   v4l2camsrc->af_window.y_bottom = 0;
1160   v4l2camsrc->af_window.y_top = 0;
1161   v4l2camsrc->af_window.weight= 0x8000;
1162
1163   libmfld_cam_init (v4l2camsrc->mfldadvci);
1164
1165   GST_DEBUG ("initialized to commit %s", MFLD_V4L2CAMSRC_VERSION);
1166 }
1167
1168
1169 static void
1170 gst_v4l2camsrc_dispose (GObject * object)
1171 {
1172   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (object);
1173
1174   if (v4l2camsrc->formats) {
1175     gst_v4l2camsrc_clear_format_list (v4l2camsrc);
1176   }
1177
1178   if (v4l2camsrc->probed_caps) {
1179     gst_caps_unref (v4l2camsrc->probed_caps);
1180     v4l2camsrc->probed_caps = NULL;
1181   }
1182
1183   /* FIXME: driver cleanup function */
1184   if (v4l2camsrc->videodev) {
1185     g_free (v4l2camsrc->videodev);
1186     v4l2camsrc->videodev = NULL;
1187   }
1188
1189   if (v4l2camsrc->poll) {
1190     gst_poll_free (v4l2camsrc->poll);
1191   }
1192
1193   g_mutex_free (v4l2camsrc->device_mutex);
1194
1195   G_OBJECT_CLASS (parent_class)->dispose (object);
1196   libmfld_cam_dispose ();
1197   gst_v4l2camsrc_mfldadvci_wrapper_unload(v4l2camsrc);
1198 }
1199
1200
1201 /*
1202  * gst_v4l2camsrc_finalize:
1203  * @object:
1204  *
1205  */
1206 static void
1207 gst_v4l2camsrc_finalize (GObject * object)
1208 {
1209   G_OBJECT_CLASS (parent_class)->finalize (object);
1210 }
1211
1212
1213
1214 /*
1215  */
1216 static void
1217 gst_v4l2camsrc_set_property (GObject * object,
1218     guint prop_id, const GValue * value, GParamSpec * pspec)
1219 {
1220   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (object);
1221   gboolean opened = GST_V4L2CAMSRC_IS_OPEN (v4l2camsrc);
1222
1223   switch (prop_id) {
1224     case PROP_DEVICE:
1225       g_free (v4l2camsrc->videodev);
1226       v4l2camsrc->videodev = g_value_dup_string (value);
1227       break;
1228     case PROP_QUEUE_SIZE:
1229       v4l2camsrc->num_buffers = g_value_get_uint (value);
1230       v4l2camsrc->tmp_num_buffers = v4l2camsrc->num_buffers;
1231       break;
1232     case PROP_INPUT_SENSOR:
1233       v4l2camsrc->input_sensor = g_value_get_enum (value);
1234       break;
1235     case PROP_USE_MMAP:
1236       v4l2camsrc->use_mmap = g_value_get_boolean (value);
1237       break;
1238     case PROP_USE_COPY:
1239       v4l2camsrc->use_copy = g_value_get_boolean (value);
1240       break;
1241     case PROP_AE:
1242       v4l2camsrc->ae_enabled = g_value_get_boolean (value);
1243       break;
1244     case PROP_AE_WINDOW:
1245     {
1246       GstStructure *ae_window_param = NULL;
1247       char * ctmp = NULL;
1248       gboolean parsed = TRUE;
1249
1250       ctmp = g_malloc0 (60);
1251       if (ctmp == NULL)
1252       {
1253              GST_DEBUG_OBJECT(v4l2camsrc, "alloc string mem failed.\n");
1254              break;
1255       }
1256       strncpy (ctmp,"ae,",3);
1257       strncat (ctmp,g_value_get_string (value),55);
1258       ae_window_param = gst_structure_from_string (ctmp, NULL);
1259       if(ae_window_param == NULL)
1260       {
1261               GST_DEBUG_OBJECT(v4l2camsrc,"wrong string format is entered. stop setting ae window.\n");
1262               g_free (ctmp);
1263               break;
1264       }
1265
1266       parsed = gst_structure_get_int(ae_window_param, "x_left",
1267                       &v4l2camsrc->ae_window.x_left);
1268       parsed |= gst_structure_get_int(ae_window_param, "x_right",
1269                       &v4l2camsrc->ae_window.x_right);
1270       parsed |= gst_structure_get_int(ae_window_param, "y_top",
1271                       &v4l2camsrc->ae_window.y_top);
1272       parsed |= gst_structure_get_int(ae_window_param, "y_bottom",
1273                       &v4l2camsrc->ae_window.y_bottom);
1274
1275       if (parsed == FALSE)
1276       {
1277                 GST_DEBUG_OBJECT(v4l2camsrc,"cannot parse ae window parameter. \n");
1278                 gst_structure_free (ae_window_param);
1279                 g_free (ctmp);
1280                 break;
1281       }
1282
1283       parsed = gst_structure_get_int(ae_window_param, "weight",
1284                       &v4l2camsrc->ae_window.weight);
1285
1286       if (parsed == FALSE)
1287       {
1288         GST_DEBUG_OBJECT(v4l2camsrc,
1289                              "set ae window weight to default value 0x8000.\n");
1290         v4l2camsrc->ae_window.weight = 0x8000;
1291       }
1292
1293       GST_DEBUG_OBJECT(v4l2camsrc,"ae-window-setting: x_left:%d, x_right:%d,"
1294                      "y_bottom:%d, y_top:%d, weight:%d.\n",
1295                       v4l2camsrc->ae_window.x_left,v4l2camsrc->ae_window.x_right,
1296                       v4l2camsrc->ae_window.y_bottom, v4l2camsrc->ae_window.y_top,
1297                      v4l2camsrc->ae_window.weight);
1298
1299
1300       if (v4l2camsrc->ae_metering_mode != GST_CAMERA_AE_METERING_SPOT)
1301       {
1302                 GST_DEBUG_OBJECT(v4l2camsrc,"wrong ae metering mode. set it to spot mode automaticly.\n");
1303                v4l2camsrc->ae_metering_mode = GST_CAMERA_AE_METERING_SPOT;
1304                 v4l2camsrc->mfldadvci->AeSetMeteringMode
1305                         ( (advci_ae_metering_mode) v4l2camsrc->ae_metering_mode);
1306
1307       }
1308       v4l2camsrc->mfldadvci->AeSetWindow ((advci_window *) (&(v4l2camsrc->ae_window)));
1309
1310       gst_structure_free (ae_window_param);
1311       g_free (ctmp);
1312       break;
1313     }
1314
1315     case PROP_AE_METERING_MODE:
1316     {
1317       v4l2camsrc->ae_metering_mode = g_value_get_enum (value);
1318       v4l2camsrc->mfldadvci->AeSetMeteringMode((advci_ae_metering_mode)v4l2camsrc->ae_metering_mode);
1319       break;
1320     }
1321     case PROP_AE_MODE:
1322     {
1323       v4l2camsrc->ae_mode = g_value_get_enum (value);
1324       v4l2camsrc->mfldadvci->AeSetMode((advci_ae_mode)v4l2camsrc->ae_mode);
1325       break;
1326     }
1327     case PROP_AF_METERING_MODE:
1328     {
1329       v4l2camsrc->af_metering_mode = g_value_get_enum (value);
1330       v4l2camsrc->mfldadvci->AfSetMeteringMode((advci_af_metering_mode)v4l2camsrc->af_metering_mode);
1331       break;
1332     }
1333     case PROP_AF_WINDOW:
1334     {
1335       GstStructure *af_window_param = NULL;
1336       char * ctmp = NULL;
1337       gboolean parsed = TRUE;
1338
1339       ctmp = g_malloc0 (60);
1340       if (ctmp == NULL)
1341       {
1342              GST_DEBUG_OBJECT(v4l2camsrc, "alloc string mem failed.\n");
1343              break;
1344       }
1345       strncpy (ctmp,"af,",3);
1346       strncat (ctmp,g_value_get_string (value),55);
1347       af_window_param = gst_structure_from_string (ctmp, NULL);
1348       if(af_window_param == NULL)
1349       {
1350               GST_DEBUG_OBJECT(v4l2camsrc,"wrong string format is entered. stop setting af window.\n");
1351               g_free (ctmp);
1352               break;
1353       }
1354
1355       parsed = gst_structure_get_int(af_window_param, "x_left",
1356                       &v4l2camsrc->af_window.x_left);
1357       parsed |= gst_structure_get_int(af_window_param, "x_right",
1358                       &v4l2camsrc->af_window.x_right);
1359       parsed |= gst_structure_get_int(af_window_param, "y_top",
1360                       &v4l2camsrc->af_window.y_top);
1361       parsed |= gst_structure_get_int(af_window_param, "y_bottom",
1362                       &v4l2camsrc->af_window.y_bottom);
1363
1364       if (parsed == FALSE)
1365       {
1366                 GST_DEBUG_OBJECT(v4l2camsrc,"cannot parse af window parameter. \n");
1367                 gst_structure_free (af_window_param);
1368                 g_free (ctmp);
1369                 break;
1370       }
1371
1372       parsed = gst_structure_get_int(af_window_param, "weight",
1373                       &v4l2camsrc->af_window.weight);
1374
1375       if (parsed == FALSE)
1376       {
1377              GST_DEBUG_OBJECT(v4l2camsrc,
1378                              "set af window weight to default value 0x8000.\n");
1379              v4l2camsrc->af_window.weight = 0x8000;
1380       }
1381
1382       GST_DEBUG_OBJECT(v4l2camsrc,"af-window-setting: x_left:%d, x_right:%d,"
1383                      "y_bottom:%d, y_top:%d, weight:%d.\n",
1384                       v4l2camsrc->af_window.x_left,v4l2camsrc->af_window.x_right,
1385                       v4l2camsrc->af_window.y_bottom, v4l2camsrc->af_window.y_top,
1386                      v4l2camsrc->af_window.y_top);
1387
1388
1389       v4l2camsrc->mfldadvci->AfSetWindows (1, (advci_window *) (&(v4l2camsrc->af_window)));
1390
1391       gst_structure_free (af_window_param);
1392       g_free (ctmp);
1393       break;
1394     }
1395
1396     case PROP_AF:
1397       v4l2camsrc->af_enabled = g_value_get_boolean (value);
1398       break;
1399
1400     case PROP_AWB:
1401       v4l2camsrc->awb_enabled = g_value_get_boolean (value);
1402       break;
1403     case PROP_STILL_AF:
1404       v4l2camsrc->still_af = g_value_get_boolean (value);
1405       cam_set_autofocus (v4l2camsrc->still_af);
1406       break;
1407     case PROP_FOCUS_POSITION:
1408       v4l2camsrc->focus_posi = g_value_get_int(value);
1409       if (opened)
1410         cam_driver_set_focus_posi (v4l2camsrc->video_fd, v4l2camsrc->focus_posi);
1411       else
1412         v4l2camsrc->focus_updated = TRUE;
1413       break;
1414     case PROP_VFLIP:
1415       v4l2camsrc->vflip = g_value_get_boolean(value);
1416       if (gst_v4l2camsrc_is_open (GST_CAMERA_SRC (v4l2camsrc)))
1417         gst_v4l2camsrc_set_attribute (GST_CAMERA_SRC (v4l2camsrc),V4L2_CID_VFLIP,v4l2camsrc->vflip);
1418       break;
1419     case  PROP_HFLIP:
1420       v4l2camsrc->hflip = g_value_get_boolean(value);
1421       if (gst_v4l2camsrc_is_open (GST_CAMERA_SRC (v4l2camsrc))) 
1422         gst_v4l2camsrc_set_attribute (GST_CAMERA_SRC (v4l2camsrc),V4L2_CID_HFLIP,v4l2camsrc->hflip);
1423       break;
1424     case PROP_BAYER_DOWNSCALING:
1425       v4l2camsrc->bayer_downscaling = g_value_get_boolean (value);
1426       break;
1427     case PROP_CAPTURE_CORRECTION_GDC:
1428       v4l2camsrc->gdc_enabled = g_value_get_boolean (value);
1429       if (opened)
1430         cam_set_capture_correction (v4l2camsrc->video_fd,
1431             CAM_CAPTURE_CORRECTION_GDC, v4l2camsrc->gdc_enabled);
1432       else
1433         v4l2camsrc->cc_updated = TRUE;
1434       break;
1435     case PROP_CAPTURE_CORRECTION_CAC:
1436       v4l2camsrc->cac_enabled = g_value_get_boolean (value);
1437       if (opened)
1438         cam_set_capture_correction (v4l2camsrc->video_fd,
1439             CAM_CAPTURE_CORRECTION_CAC, v4l2camsrc->cac_enabled);
1440       else
1441         v4l2camsrc->cc_updated = TRUE;
1442       break;
1443     case PROP_CAPTURE_CORRECTION_RER:
1444       v4l2camsrc->rer_enabled = g_value_get_boolean (value);
1445       cam_set_capture_correction (v4l2camsrc->video_fd,
1446           CAM_CAPTURE_CORRECTION_RER, v4l2camsrc->rer_enabled);
1447       break;
1448     case PROP_CAPTURE_CORRECTION_DIS:
1449       v4l2camsrc->dis_enabled = g_value_get_boolean (value);
1450       cam_set_capture_correction (v4l2camsrc->video_fd,
1451           CAM_CAPTURE_CORRECTION_DIS, v4l2camsrc->dis_enabled);
1452       break;
1453     case PROP_CAPTURE_CORRECTION_DVS:
1454       v4l2camsrc->dvs_enabled = g_value_get_boolean (value);
1455       if (opened)
1456         cam_set_capture_correction (v4l2camsrc->video_fd,
1457             CAM_CAPTURE_CORRECTION_DVS, v4l2camsrc->dvs_enabled);
1458       else
1459         v4l2camsrc->cc_updated = TRUE;
1460       break;
1461     case PROP_CAPTURE_CORRECTION_EDGE_ENHANCEMENT:
1462       v4l2camsrc->ee_enabled = g_value_get_boolean (value);
1463       if (opened)
1464         cam_set_capture_correction (v4l2camsrc->video_fd,
1465             CAM_CAPTURE_CORRECTION_EE, v4l2camsrc->ee_enabled);
1466       else
1467         v4l2camsrc->cc_updated = TRUE;
1468       break;
1469     case PROP_CAPTURE_CORRECTION_SHADING_CORRECTION:
1470       v4l2camsrc->sc_enabled = g_value_get_boolean (value);
1471       if (opened)
1472         cam_set_capture_correction (v4l2camsrc->video_fd,
1473             CAM_CAPTURE_CORRECTION_SC, v4l2camsrc->sc_enabled);
1474       else
1475         v4l2camsrc->cc_updated = TRUE;
1476       break;
1477     case PROP_CAPTURE_CORRECTION_BLACK_LEVEL_COMPENSATION:
1478       v4l2camsrc->blc_enabled = g_value_get_boolean (value);
1479       if (opened)
1480         cam_set_capture_correction (v4l2camsrc->video_fd,
1481             CAM_CAPTURE_CORRECTION_BLC, v4l2camsrc->blc_enabled);
1482       else
1483         v4l2camsrc->cc_updated = TRUE;
1484       break;
1485     case PROP_CAPTURE_CORRECTION_BAD_PIXEL_DETECTION:
1486       v4l2camsrc->bpd_enabled = g_value_get_boolean (value);
1487       if (opened)
1488         cam_set_capture_correction (v4l2camsrc->video_fd,
1489             CAM_CAPTURE_CORRECTION_BPD, v4l2camsrc->bpd_enabled);
1490       else
1491         v4l2camsrc->cc_updated = TRUE;
1492       break;
1493     case PROP_CAPTURE_CORRECTION_GAMMA:
1494       v4l2camsrc->tone.gamma = g_value_get_float (value);
1495       if (opened)
1496         cam_set_tone_control (v4l2camsrc->video_fd, CAM_GAMMA_VALUE,
1497             &v4l2camsrc->tone);
1498       else
1499         v4l2camsrc->gamma_updated = TRUE;
1500       break;
1501     case PROP_CAPTURE_CORRECTION_CONTRAST:
1502       v4l2camsrc->tone.contrast = g_value_get_int (value);
1503       if (opened)
1504         cam_set_tone_control (v4l2camsrc->video_fd, CAM_CONTRAST_VALUE,
1505             &v4l2camsrc->tone);
1506       else
1507         v4l2camsrc->gamma_updated = TRUE;
1508       break;
1509     case PROP_CAPTURE_CORRECTION_BRIGHTNESS:
1510       v4l2camsrc->tone.brightness = g_value_get_int (value);
1511       if (opened)
1512         cam_set_tone_control (v4l2camsrc->video_fd, CAM_BRIGHTNESS_VALUE,
1513             &v4l2camsrc->tone);
1514       else
1515         v4l2camsrc->gamma_updated = TRUE;
1516       break;
1517     case PROP_DUMP_RAW:
1518       v4l2camsrc->dump_raw = g_value_get_boolean (value);
1519       break;
1520     case PROP_DUMP_IMAGE:
1521       v4l2camsrc->dump_image = g_value_get_boolean (value);
1522       break;
1523     case PROP_DEBUG_FLAGS:
1524       v4l2camsrc->debug_flags = g_value_get_flags (value);
1525       break;
1526     case PROP_DISABLE_LOW_RES_CROP:
1527       v4l2camsrc->disable_low_res_crop = g_value_get_boolean (value);
1528       break;
1529     case PROP_DRAW_CORNER_MARKERS:
1530       v4l2camsrc->draw_corner_markers = g_value_get_boolean (value);
1531       break;
1532     default:
1533       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1534       break;
1535
1536
1537   }
1538 }
1539
1540 /*
1541  */
1542 static void
1543 gst_v4l2camsrc_get_property (GObject * object,
1544     guint prop_id, GValue * value, GParamSpec * pspec)
1545 {
1546   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (object);
1547
1548   switch (prop_id) {
1549     case PROP_DEVICE:
1550       g_value_set_string (value, v4l2camsrc->videodev);
1551       break;
1552     case PROP_DEVICE_NAME:
1553     {
1554       const guchar *new = NULL;
1555
1556       if (gst_v4l2camsrc_is_open (GST_CAMERA_SRC (v4l2camsrc))) {
1557         new = v4l2camsrc->vcap.card;
1558       } else if (gst_v4l2camsrc_open (GST_CAMERA_SRC (v4l2camsrc))) {
1559         new = v4l2camsrc->vcap.card;
1560         gst_v4l2camsrc_close (GST_CAMERA_SRC (v4l2camsrc));
1561         gst_camerasrc_clear_color_channels (GST_CAMERA_SRC (v4l2camsrc));
1562       }
1563       g_value_set_string (value, (gchar *) new);
1564       break;
1565     }
1566     case PROP_DEVICE_FD:
1567     {
1568       if (gst_v4l2camsrc_is_open (GST_CAMERA_SRC (v4l2camsrc)))
1569         g_value_set_int (value, v4l2camsrc->video_fd);
1570       else
1571         g_value_set_int (value, DEFAULT_PROP_DEVICE_FD);
1572       break;
1573     }
1574     case PROP_QUEUE_SIZE:
1575       g_value_set_uint (value, v4l2camsrc->num_buffers);
1576       break;
1577     case PROP_INPUT_SENSOR:
1578       g_value_set_enum (value, v4l2camsrc->input_sensor);
1579       break;
1580     case PROP_USE_MMAP:
1581       g_value_set_boolean (value, v4l2camsrc->use_mmap);
1582       break;
1583     case PROP_USE_COPY:
1584       g_value_set_boolean (value, v4l2camsrc->use_copy);
1585       break;
1586     case PROP_AE:
1587       g_value_set_boolean (value, v4l2camsrc->ae_enabled);
1588       break;
1589     case PROP_AE_METERING_MODE:
1590       g_value_set_enum (value, v4l2camsrc->ae_metering_mode);
1591       break;
1592     case PROP_AE_MODE:
1593       g_value_set_enum (value, v4l2camsrc->ae_mode);
1594       break;
1595     case PROP_AE_WINDOW:
1596     {
1597       GstStructure *tmp = NULL;
1598       tmp = gst_structure_empty_new("ae-window");
1599       if(tmp == NULL)
1600       {
1601               GST_DEBUG ("wrong default ae window setting.\n");
1602               break;
1603       }
1604       gst_structure_set (tmp,"x_left", G_TYPE_INT,
1605                       v4l2camsrc->ae_window.x_left,NULL);
1606       gst_structure_set (tmp,"x_right", G_TYPE_INT,
1607                       v4l2camsrc->ae_window.x_right,NULL);
1608       gst_structure_set (tmp,"y_bottom", G_TYPE_INT,
1609                       v4l2camsrc->ae_window.y_bottom,NULL);
1610       gst_structure_set (tmp,"y_top", G_TYPE_INT,
1611                       v4l2camsrc->ae_window.y_top,NULL);
1612       g_value_set_string(value, gst_structure_to_string(tmp));
1613       gst_structure_free(tmp);
1614       break;
1615     }
1616
1617     case PROP_AF:
1618       g_value_set_boolean (value, v4l2camsrc->af_enabled);
1619       break;
1620     case PROP_AF_METERING_MODE:
1621       g_value_set_enum (value, v4l2camsrc->af_metering_mode);
1622       break;
1623     case PROP_AF_WINDOW:
1624     {
1625       GstStructure *tmp = NULL;
1626       tmp = gst_structure_empty_new("af-window");
1627       if(tmp == NULL)
1628       {
1629               GST_DEBUG ("wrong default af window setting.\n");
1630               break;
1631       }
1632       gst_structure_set (tmp,"x_left", G_TYPE_INT,
1633                       v4l2camsrc->af_window.x_left,NULL);
1634       gst_structure_set (tmp,"x_right", G_TYPE_INT,
1635                       v4l2camsrc->af_window.x_right,NULL);
1636       gst_structure_set (tmp,"y_bottom", G_TYPE_INT,
1637                       v4l2camsrc->af_window.y_bottom,NULL);
1638       gst_structure_set (tmp,"y_top", G_TYPE_INT,
1639                       v4l2camsrc->af_window.y_top,NULL);
1640       g_value_set_string(value, gst_structure_to_string(tmp));
1641       gst_structure_free(tmp);
1642       break;
1643     }
1644
1645     case PROP_AWB:
1646       g_value_set_boolean (value, v4l2camsrc->awb_enabled);
1647       break;
1648     case PROP_STILL_AF:
1649       g_value_set_boolean (value, v4l2camsrc->still_af);
1650       break;
1651     case PROP_FOCUS_POSITION:
1652       g_value_set_int (value, v4l2camsrc->focus_posi);
1653       break;
1654     case PROP_VFLIP:
1655       g_value_set_boolean (value, v4l2camsrc->vflip);
1656       break;
1657     case PROP_HFLIP:
1658       g_value_set_boolean (value,  v4l2camsrc->hflip);
1659       break;
1660     case PROP_BAYER_DOWNSCALING:
1661       g_value_set_boolean (value, v4l2camsrc->bayer_downscaling);
1662       break;
1663     case PROP_CAPTURE_CORRECTION_GDC:
1664       g_value_set_boolean (value, v4l2camsrc->gdc_enabled);
1665       break;
1666     case PROP_CAPTURE_CORRECTION_CAC:
1667       g_value_set_boolean (value, v4l2camsrc->cac_enabled);
1668       break;
1669     case PROP_CAPTURE_CORRECTION_RER:
1670       g_value_set_boolean (value, v4l2camsrc->rer_enabled);
1671       break;
1672     case PROP_CAPTURE_CORRECTION_DIS:
1673       g_value_set_boolean (value, v4l2camsrc->dis_enabled);
1674       break;
1675     case PROP_CAPTURE_CORRECTION_DVS:
1676       g_value_set_boolean (value, v4l2camsrc->dvs_enabled);
1677       break;
1678     case PROP_CAPTURE_CORRECTION_EDGE_ENHANCEMENT:
1679       g_value_set_boolean (value, v4l2camsrc->ee_enabled);
1680       break;
1681     case PROP_CAPTURE_CORRECTION_SHADING_CORRECTION:
1682       g_value_set_boolean (value, v4l2camsrc->sc_enabled);
1683       break;
1684     case PROP_CAPTURE_CORRECTION_BLACK_LEVEL_COMPENSATION:
1685       g_value_set_boolean (value, v4l2camsrc->blc_enabled);
1686       break;
1687     case PROP_CAPTURE_CORRECTION_BAD_PIXEL_DETECTION:
1688       g_value_set_boolean (value, v4l2camsrc->bpd_enabled);
1689       break;
1690     case PROP_CAPTURE_CORRECTION_GAMMA:
1691       g_value_set_float (value, v4l2camsrc->tone.gamma);
1692       break;
1693     case PROP_CAPTURE_CORRECTION_CONTRAST:
1694       g_value_set_int (value, v4l2camsrc->tone.contrast);
1695       break;
1696     case PROP_CAPTURE_CORRECTION_BRIGHTNESS:
1697       g_value_set_int (value, v4l2camsrc->tone.brightness);
1698       break;
1699     case PROP_DUMP_RAW:
1700       g_value_set_boolean (value, v4l2camsrc->dump_raw);
1701       break;
1702     case PROP_DUMP_IMAGE:
1703       g_value_set_boolean (value, v4l2camsrc->dump_image);
1704       break;
1705     case PROP_DEBUG_FLAGS:
1706       g_value_set_flags (value, v4l2camsrc->debug_flags);
1707       break;
1708     case PROP_DISABLE_LOW_RES_CROP:
1709       g_value_set_boolean (value, v4l2camsrc->disable_low_res_crop);
1710       break;
1711     case PROP_DRAW_CORNER_MARKERS:
1712       g_value_set_boolean (value, v4l2camsrc->draw_corner_markers);
1713       break;
1714     default:
1715       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1716       break;
1717   }
1718 }
1719
1720
1721
1722 static gboolean
1723 gst_v4l2camsrc_unlock (GstCameraSrc * src)
1724 {
1725   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (src);
1726
1727   GST_LOG_OBJECT (v4l2camsrc, "Flushing");
1728   gst_poll_set_flushing (v4l2camsrc->poll, TRUE);
1729
1730   return TRUE;
1731 }
1732
1733 static gboolean
1734 gst_v4l2camsrc_unlock_stop (GstCameraSrc * src)
1735 {
1736   GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (src);
1737
1738   GST_LOG_OBJECT (v4l2camsrc, "No longer flushing");
1739   gst_poll_set_flushing (v4l2camsrc->poll, FALSE);
1740
1741   return TRUE;
1742 }
1743
1744 /*
1745  * gst_v4l2camsrc_set_zoom:
1746  * @camsrc: @GstCameraSrc object.
1747  * @zoom: zoom factor to be set.
1748  *
1749  * Set the zoom factor for outputted video.
1750  *
1751  * Returns: TRUE on success.
1752  */
1753 static gboolean
1754 gst_v4l2camsrc_set_zoom (GstCameraSrc * camsrc, gfloat zoom)
1755 {
1756   GstMFLDV4l2CamSrc *v4l2camsrc;
1757   gboolean ret = TRUE;
1758
1759   v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1760
1761   GST_DEBUG_OBJECT (v4l2camsrc, "ZOOM: %f", zoom);
1762
1763   v4l2camsrc->zoom_factor = zoom;
1764   if (v4l2camsrc->is_active) {
1765     g_mutex_lock (v4l2camsrc->device_mutex);
1766     ret = gst_v4l2camsrc_libmfldcam_set_zoom (v4l2camsrc, zoom);
1767     g_mutex_unlock (v4l2camsrc->device_mutex);
1768   } else
1769     v4l2camsrc->zoom_updated = TRUE;
1770
1771   return ret;
1772 }
1773 static gboolean
1774 gst_v4l2camsrc_set_ae_mode(GstCameraSrc * camsrc, int mode)
1775 {
1776   GstMFLDV4l2CamSrc *v4l2camsrc;
1777   gboolean ret = TRUE;
1778
1779   v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1780
1781   if (v4l2camsrc->is_active) {
1782     g_mutex_lock (v4l2camsrc->device_mutex);
1783     v4l2camsrc->ae_metering_mode = *(GstCameraAEMeteringMode *)&mode;
1784     v4l2camsrc->mfldadvci->AeSetMeteringMode((advci_ae_metering_mode)v4l2camsrc->ae_metering_mode);
1785     g_mutex_unlock (v4l2camsrc->device_mutex);
1786   }
1787
1788   return ret;
1789 }
1790 static gboolean
1791 gst_v4l2camsrc_get_ae_mode(GstCameraSrc * camsrc, int *mode)
1792 {
1793   GstMFLDV4l2CamSrc *v4l2camsrc;
1794   gboolean ret = TRUE;
1795
1796   v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1797
1798   if (v4l2camsrc->is_active) {
1799     g_mutex_lock (v4l2camsrc->device_mutex);
1800     *mode = v4l2camsrc->ae_metering_mode;
1801     g_mutex_unlock (v4l2camsrc->device_mutex);
1802   }
1803
1804   return ret;
1805 }
1806
1807 static gboolean
1808 gst_v4l2camsrc_get_makernote (GstCameraSrc * camsrc, unsigned char *buf, unsigned size)
1809 {
1810   GstMFLDV4l2CamSrc *v4l2camsrc;
1811   gboolean ret = TRUE;
1812
1813   v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1814   GST_DEBUG_OBJECT (v4l2camsrc, "%s, !!!!!!line:%d\n", __func__, __LINE__);
1815
1816   if (v4l2camsrc->is_active) {
1817     g_mutex_lock (v4l2camsrc->device_mutex);
1818     ret = gst_v4l2camsrc_libmfldcam_get_makernote(v4l2camsrc, buf, size);
1819     g_mutex_unlock (v4l2camsrc->device_mutex);
1820   }
1821
1822   return ret;
1823 }
1824
1825 static gboolean gst_v4l2camsrc_makernote_init(GstCameraSrc * camsrc,
1826                                                       unsigned * buf_size,
1827                                                       unsigned num_afwindows,
1828                                                       unsigned num_faces,
1829                                                       unsigned num_eyes,
1830                                                       unsigned num_grid,
1831                                                       int *handle)
1832 {
1833   GstMFLDV4l2CamSrc *v4l2camsrc;
1834
1835   v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1836   GST_DEBUG_OBJECT (v4l2camsrc, "%s, !!!!!!line:%d\n", __func__, __LINE__);
1837
1838   num_afwindows = num_grid = 1;
1839   num_faces = num_eyes = 0;
1840   return FALSE;
1841
1842 }
1843
1844 static gboolean gst_v4l2camsrc_makernote_deal(GstCameraSrc * camsrc,
1845                                                       GstBuffer *pmakerbuf,
1846                                                       unsigned num_afwindows,
1847                                                       unsigned num_grid,
1848                                                       int handle)
1849 {
1850   GstMFLDV4l2CamSrc *v4l2camsrc;
1851
1852   v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1853   GST_DEBUG_OBJECT (v4l2camsrc, "%s, !!!!!!line:%d\n", __func__, __LINE__);
1854
1855   return FALSE;
1856
1857 }
1858
1859 static gboolean gst_v4l2camsrc_makernote_uninit(GstCameraSrc * camsrc,
1860                                                         int handle)
1861 {
1862   GstMFLDV4l2CamSrc *v4l2camsrc;
1863
1864   v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1865   GST_DEBUG_OBJECT (v4l2camsrc, "%s, !!!!!!line:%d\n", __func__, __LINE__);
1866
1867   return FALSE;
1868 }
1869
1870
1871 /*
1872  * plugin_init:
1873  * @plugin: GstPlugin
1874  *
1875  * Returns: TRUE on success.
1876  */
1877 static gboolean
1878 plugin_init (GstPlugin * plugin)
1879 {
1880   GST_DEBUG_CATEGORY_INIT (gst_v4l2camsrc_debug, "camerasrc", 0,
1881       "Medfield V4L2 camera source");
1882
1883   return gst_element_register (plugin, "camerasrc",
1884       GST_RANK_NONE, GST_TYPE_V4L2CAMSRC);
1885 }
1886
1887 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1888     GST_VERSION_MINOR,
1889     "mfldv4l2cam",
1890     "V4L2 camera image capturing element",
1891     plugin_init, VERSION, "LGPL", "Intel", "www.intel.com")