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