1 /* GStreamer V4L2 camera source
2 * Copyright (C) 2010 Nokia Corporation <multimedia@maemo.org>
3 * 2010 Intel Corporation
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.
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.
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.
22 * SECTION:element-mfldcamsrc
23 * @short_description: Medfield V4L2 camera source
24 * @see_also: #GstCameraSrc
33 * <title>Example launch line</title>
36 * gst-launch mfldv4l2camsrc ! xvimagesink
48 #include <linux/videodev2.h>
49 #include "gstv4l2camsrc.h"
50 #include "v4l2camsrc_calls.h"
51 #include "gstv4l2camvidorient.h"
54 #include "exifmakernote_main.h"
55 #include "exifmakernote_util.h"
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
62 GST_DEBUG_CATEGORY (gst_v4l2camsrc_debug);
63 #define GST_CAT_DEFAULT gst_v4l2camsrc_debug
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,
77 static gboolean gst_v4l2camsrc_get_makernote (GstCameraSrc * camsrc, unsigned char *buf, unsigned size);
78 static gboolean gst_v4l2camsrc_makernote_init(GstCameraSrc * camsrc,
80 unsigned num_afwindows,
85 static gboolean gst_v4l2camsrc_makernote_deal(GstCameraSrc * camsrc,
87 unsigned num_afwindows,
90 static gboolean gst_v4l2camsrc_makernote_uninit(GstCameraSrc * camsrc,
104 PROP_AE_METERING_MODE,
107 PROP_AF_METERING_MODE,
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,
128 } GstV4L2CamSrcProperties;
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)
142 gst_camera_input_sensor_get_type (void)
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"},
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);
156 return gst_camera_input_sensor_type;
160 gst_camera_ae_metering_mode_get_type(void)
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"},
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);
176 return gst_camera_ae_metering_mode_type;
180 gst_camera_af_metering_mode_get_type(void)
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"},
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);
196 return gst_camera_af_metering_mode_type;
200 gst_camerasrc_debug_flags_get_type (void)
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",
206 {C_FLAGS (GST_CAMERASRC_DEBUG_FLAGS_MAKER_NOTE), "Debug flags for maker note",
208 {C_FLAGS (GST_CAMERASRC_DEBUG_FLAGS_AUTO_FOCUS), "Debug flags for auto focus",
213 if (G_UNLIKELY (!gst_camerasrc_debug_flags)) {
214 gst_camerasrc_debug_flags =
215 g_flags_register_static ("GstCameraSrcDebugFlags", values);
217 return gst_camerasrc_debug_flags;
222 GST_IMPLEMENT_V4L2CAMSRC_VIDORIENT_METHODS (GstMFLDV4l2CamSrc, gst_v4l2camsrc);
226 gst_v4l2camsrc_interface_init (GstImplementsInterfaceClass * klass)
229 * default virtual functions
231 klass->supported = gst_v4l2camsrc_iface_supported;
235 gst_v4l2camsrc_init_interfaces (GType type)
237 static const GInterfaceInfo v4l2camsrc_iface_info = {
238 (GInterfaceInitFunc) gst_v4l2camsrc_interface_init,
242 static const GInterfaceInfo v4l2camsrc_videoorientation_info = {
243 (GInterfaceInitFunc) gst_v4l2camsrc_video_orientation_interface_init,
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);
255 GST_BOILERPLATE_FULL (GstMFLDV4l2CamSrc, gst_v4l2camsrc, GstCameraSrc,
256 GST_TYPE_CAMERA_SRC, gst_v4l2camsrc_init_interfaces);
261 gst_v4l2camsrc_iface_supported (GstImplementsInterface * iface,
264 GstCameraSrc *camsrc = GST_CAMERA_SRC (iface);
266 if (gst_v4l2camsrc_is_open (camsrc) &&
267 iface_type == GST_TYPE_VIDEO_ORIENTATION) {
271 else if (GST_IS_IMPLEMENTS_INTERFACE (camsrc)) {
272 GstImplementsInterfaceClass *parent_klass;
275 g_type_interface_peek (parent_class, GST_TYPE_IMPLEMENTS_INTERFACE);
276 return parent_klass->supported (iface, iface_type);
284 * gst_v4l2camsrc_is_open:
288 gst_v4l2camsrc_is_open (GstCameraSrc * camsrc)
290 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc);
292 return GST_V4L2CAMSRC_IS_OPEN (v4l2camsrc);
296 * gst_v4l2camsrc_is_active:
300 gst_v4l2camsrc_is_active (GstCameraSrc * camsrc)
302 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc);
304 return GST_V4L2CAMSRC_IS_ACTIVE (v4l2camsrc);
308 * gst_v4l2camsrc_v4l2fourcc_to_structure:
311 static GstStructure *
312 gst_v4l2camsrc_v4l2fourcc_to_structure (guint32 fourcc)
314 GstStructure *structure = NULL;
317 case V4L2_PIX_FMT_MJPEG: /* Motion-JPEG */
318 case V4L2_PIX_FMT_JPEG: /* JFIF JPEG */
319 structure = gst_structure_new ("image/jpeg", NULL);
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;
334 guint32 r_mask = 0, b_mask = 0, g_mask = 0;
337 case V4L2_PIX_FMT_RGB332:
339 endianness = G_BYTE_ORDER; /* 'like, whatever' */
344 case V4L2_PIX_FMT_RGB555:
345 case V4L2_PIX_FMT_RGB555X:
349 fourcc == V4L2_PIX_FMT_RGB555X ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
354 case V4L2_PIX_FMT_RGB565:
355 case V4L2_PIX_FMT_RGB565X:
358 fourcc == V4L2_PIX_FMT_RGB565X ? G_BIG_ENDIAN : G_LITTLE_ENDIAN;
363 case V4L2_PIX_FMT_RGB24:
365 endianness = G_BIG_ENDIAN;
370 case V4L2_PIX_FMT_BGR24:
372 endianness = G_BIG_ENDIAN;
377 case V4L2_PIX_FMT_RGB32:
379 endianness = G_BIG_ENDIAN;
384 case V4L2_PIX_FMT_BGR32:
386 endianness = G_BIG_ENDIAN;
392 g_assert_not_reached ();
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);
404 case V4L2_PIX_FMT_GREY: /* 8 Greyscale */
405 structure = gst_structure_new ("video/x-raw-gray",
406 "bpp", G_TYPE_INT, 8, NULL);
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 */
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:
428 case V4L2_PIX_FMT_YUV411P:{
432 case V4L2_PIX_FMT_NV12:
433 fcc = GST_MAKE_FOURCC ('N', 'V', '1', '2');
435 case V4L2_PIX_FMT_NV21:
436 fcc = GST_MAKE_FOURCC ('N', 'V', '2', '1');
438 case V4L2_PIX_FMT_NV16:
439 fcc = GST_MAKE_FOURCC ('N', 'V', '1', '6');
441 case V4L2_PIX_FMT_NV61:
442 fcc = GST_MAKE_FOURCC ('N', 'V', '6', '1');
444 case V4L2_PIX_FMT_YVU410:
445 fcc = GST_MAKE_FOURCC ('Y', 'V', 'U', '9');
447 case V4L2_PIX_FMT_YUV410:
448 fcc = GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
450 case V4L2_PIX_FMT_YUV420:
451 fcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
453 case V4L2_PIX_FMT_YUYV:
454 fcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
456 case V4L2_PIX_FMT_YVU420:
457 fcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
459 case V4L2_PIX_FMT_UYVY:
460 fcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
462 case V4L2_PIX_FMT_Y41P:
463 fcc = GST_MAKE_FOURCC ('Y', '4', '1', 'P');
465 case V4L2_PIX_FMT_YUV411P:
466 fcc = GST_MAKE_FOURCC ('Y', '4', '1', 'B');
468 case V4L2_PIX_FMT_YUV422P:
469 fcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
471 case V4L2_PIX_FMT_YUV444:
472 fcc = GST_MAKE_FOURCC ('Y', '4', '4', '4');
474 #ifdef V4L2_PIX_FMT_YVYU
475 case V4L2_PIX_FMT_YVYU:
476 fcc = GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U');
480 g_assert_not_reached ();
483 structure = gst_structure_new ("video/x-raw-yuv",
484 "format", GST_TYPE_FOURCC, fcc, NULL);
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:{
500 case V4L2_PIX_FMT_SBGGR8:
501 fcc = GST_MAKE_FOURCC ('B', 'A', '8', '1');
503 case V4L2_PIX_FMT_SGBRG8:
504 fcc = GST_MAKE_FOURCC ('G', 'B', 'R', 'G');
506 case V4L2_PIX_FMT_SGRBG8:
507 fcc = GST_MAKE_FOURCC ('G', 'R', 'B', 'G');
509 case V4L2_PIX_FMT_SRGGB8:
510 fcc = GST_MAKE_FOURCC ('R', 'G', 'G', 'B');
512 case V4L2_PIX_FMT_SBGGR10:
513 fcc = GST_MAKE_FOURCC ('B', 'G', '1', '0');
515 case V4L2_PIX_FMT_SGBRG10:
516 fcc = GST_MAKE_FOURCC ('G', 'B', '1', '0');
518 case V4L2_PIX_FMT_SGRBG10:
519 fcc = GST_MAKE_FOURCC ('B', 'A', '1', '0');
521 case V4L2_PIX_FMT_SRGGB10:
522 fcc = GST_MAKE_FOURCC ('R', 'G', '1', '0');
524 case V4L2_PIX_FMT_SBGGR16:
525 fcc = GST_MAKE_FOURCC ('B', 'Y', 'R', '2');
528 g_assert_not_reached ();
531 structure = gst_structure_new ("video/x-raw-bayer",
532 "format", GST_TYPE_FOURCC, fcc, NULL);
536 GST_DEBUG ("Unknown fourcc 0x%08x %" GST_FOURCC_FORMAT,
537 fourcc, GST_FOURCC_ARGS (fourcc));
545 * gst_v4l2camsrc_get_caps:
549 gst_v4l2camsrc_get_caps (GstCameraSrc * camsrc)
551 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc);
552 GstStructure *template;
556 if (!gst_v4l2camsrc_is_open (camsrc)) {
557 /* FIXME: should it probe the device? */
561 if (!v4l2camsrc->formats)
562 gst_v4l2camsrc_fill_format_list (v4l2camsrc);
564 ret = gst_caps_new_empty ();
566 for (walk = v4l2camsrc->formats; walk; walk = walk->next) {
567 struct v4l2_fmtdesc *format;
569 /* FIXME: Introduce own format structure */
570 format = (struct v4l2_fmtdesc *) walk->data;
572 template = gst_v4l2camsrc_v4l2fourcc_to_structure (format->pixelformat);
577 tmp = gst_v4l2camsrc_probe_caps_for_format (v4l2camsrc,
578 format->pixelformat, template);
580 gst_caps_append (ret, tmp);
582 gst_structure_free (template);
584 GST_DEBUG_OBJECT (v4l2camsrc, "unknown format %u", format->pixelformat);
588 v4l2camsrc->probed_caps = gst_caps_ref (ret);
590 GST_INFO_OBJECT (v4l2camsrc, "probed caps: %" GST_PTR_FORMAT, ret);
596 * gst_v4l2camsrc_get_num_buffers:
600 gst_v4l2camsrc_get_num_buffers (GstCameraSrc * camsrc)
602 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc);
604 return v4l2camsrc->num_buffers;
608 * common format / caps utilities:
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},
623 {V4L2_PIX_FMT_NV12, TRUE},
624 {V4L2_PIX_FMT_NV21, TRUE},
626 {V4L2_PIX_FMT_NV16, TRUE},
627 {V4L2_PIX_FMT_NV61, TRUE},
629 {V4L2_PIX_FMT_YUYV, TRUE},
630 {V4L2_PIX_FMT_UYVY, TRUE},
632 {V4L2_PIX_FMT_SBGGR16, TRUE},
634 {V4L2_PIX_FMT_SBGGR8, TRUE},
635 {V4L2_PIX_FMT_SGBRG8, TRUE},
636 {V4L2_PIX_FMT_SGRBG8, TRUE},
637 {V4L2_PIX_FMT_SRGGB8, TRUE},
639 {V4L2_PIX_FMT_SBGGR10, TRUE},
640 {V4L2_PIX_FMT_SGBRG10, TRUE},
641 {V4L2_PIX_FMT_SGRBG10, TRUE},
642 {V4L2_PIX_FMT_SRGGB10, TRUE},
644 {V4L2_PIX_FMT_RGB24, TRUE},
645 {V4L2_PIX_FMT_RGB32, TRUE},
646 {V4L2_PIX_FMT_RGB565, TRUE},
649 #define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats))
650 #define GST_V4L2_MAX_SIZE (1<<15) /* 2^15 == 32768 */
653 gst_v4l2camsrc_get_all_caps (void)
655 static GstCaps *caps = NULL;
658 GstStructure *structure;
662 caps = gst_caps_new_empty ();
663 for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {
665 gst_v4l2camsrc_v4l2fourcc_to_structure (gst_v4l2_formats[i].format);
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);
673 gst_caps_append_structure (caps, structure);
678 return gst_caps_ref (caps);
683 * gst_v4l2camsrc_base_init:
684 * @klass: #GstElementClass.
688 gst_v4l2camsrc_base_init (gpointer klass)
690 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
692 gst_element_class_set_details_simple (element_class,
693 "V4L2 camera source",
695 "Video4Linux2 camera source element",
696 "Maemo Multimedia <multimedia@maemo.org>");
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 ()));
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);
709 gst_v4l2camsrc_read_settings (GstCameraSrc * camsrc,
710 GstPhotoSettings * photoconf);
711 gboolean gst_v4l2camsrc_write_settings (GstCameraSrc * camsrc,
712 GstPhotoSettings * photoconf, gboolean scene_override);
715 * gst_v4l2camsrc_class_init:
716 * @klass: #GstMFLDV4l2CamSrcClass.
720 gst_v4l2camsrc_class_init (GstMFLDV4l2CamSrcClass * klass)
722 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
723 GstCameraSrcClass *camera_class = GST_CAMERA_SRC_CLASS (klass);
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);
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));
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));
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));
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));
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));
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));
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));
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));
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));
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 ));
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));
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));
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 ));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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);
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);
946 * gst_v4l2camsrc_driver_wrapper_load:
947 * Create the mfldadvci object. The function in libmfldadvci can
948 * be called from this source element now
951 gst_v4l2camsrc_mfldadvci_wrapper_load (GstMFLDV4l2CamSrc * v4l2camsrc)
953 GstV4l2MFLDAdvCI *mfldadvci;
955 mfldadvci = g_new0 (GstV4l2MFLDAdvCI, 1);
958 int (*init_function) (GstV4l2MFLDAdvCI * mfldadvci);
960 wrapper_default_functions_init (mfldadvci);
962 if (g_module_supported ()) {
965 module_file = g_module_build_path (MFLD_ADVCI_PATH, "libmfldadvci.so.0");
967 GST_DEBUG_OBJECT (v4l2camsrc, "Loading %s", module_file);
969 v4l2camsrc->module = g_module_open (module_file, G_MODULE_BIND_LOCAL);
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);
978 printf("Camera Source Interface version is %d\n", LIBMFLDADVCI_VERSION);
980 if (v4l2camsrc->module) {
983 ret = g_module_symbol (v4l2camsrc->module, "libmfldadvci_init",
984 (gpointer) & init_function);
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;
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);
1004 GST_WARNING_OBJECT (v4l2camsrc, "libmfldadvci: Init symbol not found");
1005 g_module_close (v4l2camsrc->module);
1006 v4l2camsrc->module = NULL;
1009 GST_DEBUG_OBJECT (v4l2camsrc,
1010 "libmfldadvci: Opening the module failed: %s", g_module_error ());
1012 g_free (module_file);
1013 GST_DEBUG_OBJECT (v4l2camsrc, "libmfldadvci: initialized");
1020 * gst_v4l2camsrc_mfldadvci_wrapper_unload:
1021 * Unload the libmfldadvci and free its resource
1024 gst_v4l2camsrc_mfldadvci_wrapper_unload (GstMFLDV4l2CamSrc * v4l2camsrc)
1026 GstV4l2MFLDAdvCI *mfldadvci = v4l2camsrc->mfldadvci;
1028 if (v4l2camsrc->module) {
1029 void (*deinit_function) (GstV4l2MFLDAdvCI * mfldadvci);
1032 GST_DEBUG_OBJECT (v4l2camsrc, "Unloading libmfldadvci");
1034 ret = g_module_symbol (v4l2camsrc->module, "libmfdladvci_deinit",
1035 (gpointer) & deinit_function);
1037 deinit_function (mfldadvci);
1039 g_module_close (v4l2camsrc->module);
1040 v4l2camsrc->module = NULL;
1048 * gst_v4l2camsrc_init:
1049 * @v4l2camsrc: #GstMFLDV4l2CamSrc.
1050 * @klass: #GstMFLDV4l2CamSrcClass.
1054 gst_v4l2camsrc_init (GstMFLDV4l2CamSrc * v4l2camsrc,
1055 GstMFLDV4l2CamSrcClass * klass)
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;
1088 v4l2camsrc->preflash_enabled = FALSE;
1089 v4l2camsrc->capflash_enabled = FALSE;
1090 v4l2camsrc->preflash_analoggain = 0;
1092 v4l2camsrc->dump_raw = FALSE;
1093 v4l2camsrc->dump_image = FALSE;
1094 v4l2camsrc->raw_output_size = 0;
1095 v4l2camsrc->debug_flags = DEFAULT_DEBUG_FLAGS;
1097 v4l2camsrc->device_mutex = g_mutex_new ();
1099 v4l2camsrc->mfldadvci = gst_v4l2camsrc_mfldadvci_wrapper_load (v4l2camsrc);
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;
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;
1116 libmfld_cam_init (v4l2camsrc->mfldadvci);
1118 GST_DEBUG ("initialized to commit %s", MFLD_V4L2CAMSRC_VERSION);
1123 gst_v4l2camsrc_dispose (GObject * object)
1125 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (object);
1127 if (v4l2camsrc->formats) {
1128 gst_v4l2camsrc_clear_format_list (v4l2camsrc);
1131 if (v4l2camsrc->probed_caps) {
1132 gst_caps_unref (v4l2camsrc->probed_caps);
1133 v4l2camsrc->probed_caps = NULL;
1136 /* FIXME: driver cleanup function */
1137 if (v4l2camsrc->videodev) {
1138 g_free (v4l2camsrc->videodev);
1139 v4l2camsrc->videodev = NULL;
1142 if (v4l2camsrc->poll) {
1143 gst_poll_free (v4l2camsrc->poll);
1146 g_mutex_free (v4l2camsrc->device_mutex);
1148 G_OBJECT_CLASS (parent_class)->dispose (object);
1149 libmfld_cam_dispose ();
1154 * gst_v4l2camsrc_finalize:
1159 gst_v4l2camsrc_finalize (GObject * object)
1161 G_OBJECT_CLASS (parent_class)->finalize (object);
1169 gst_v4l2camsrc_set_property (GObject * object,
1170 guint prop_id, const GValue * value, GParamSpec * pspec)
1172 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (object);
1173 gboolean opened = GST_V4L2CAMSRC_IS_OPEN (v4l2camsrc);
1177 g_free (v4l2camsrc->videodev);
1178 v4l2camsrc->videodev = g_value_dup_string (value);
1180 case PROP_QUEUE_SIZE:
1181 v4l2camsrc->num_buffers = g_value_get_uint (value);
1182 v4l2camsrc->tmp_num_buffers = v4l2camsrc->num_buffers;
1184 case PROP_INPUT_SENSOR:
1185 v4l2camsrc->input_sensor = g_value_get_enum (value);
1188 v4l2camsrc->use_mmap = g_value_get_boolean (value);
1191 v4l2camsrc->use_copy = g_value_get_boolean (value);
1194 v4l2camsrc->ae_enabled = g_value_get_boolean (value);
1196 case PROP_AE_WINDOW:
1198 GstStructure *ae_window_param = NULL;
1200 gboolean parsed = TRUE;
1203 ctmp = g_malloc0 (60);
1206 GST_DEBUG_OBJECT(v4l2camsrc, "alloc string mem failed.\n");
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)
1214 GST_DEBUG_OBJECT(v4l2camsrc,"wrong string format is entered. stop setting ae window.\n");
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);
1228 if (parsed == FALSE)
1230 GST_DEBUG_OBJECT(v4l2camsrc,"cannot parse ae window parameter. \n");
1231 gst_structure_free (ae_window_param);
1236 parsed = gst_structure_get_int(ae_window_param, "weight",
1237 &v4l2camsrc->ae_window.weight);
1239 if (parsed == FALSE)
1241 GST_DEBUG_OBJECT(v4l2camsrc,
1242 "set ae window weight to default value 0x8000.\n");
1243 v4l2camsrc->ae_window.weight = 0x8000;
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);
1253 if (v4l2camsrc->ae_metering_mode != GST_CAMERA_AE_METERING_SPOT)
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)
1261 GST_DEBUG_OBJECT(v4l2camsrc,"set metering mode failed.\n");
1265 r = v4l2camsrc->mfldadvci->AeSetWindow ((ci_adv_Window *) (&(v4l2camsrc->ae_window)));
1266 if(r != ci_adv_Success)
1268 GST_DEBUG_OBJECT(v4l2camsrc,"ae set window failed due to 3a lib error.\n");
1271 gst_structure_free (ae_window_param);
1276 case PROP_AE_METERING_MODE:
1278 v4l2camsrc->ae_metering_mode = g_value_get_enum (value);
1279 v4l2camsrc->mfldadvci->AeSetMeteringMode((ci_adv_AeMeteringMode)v4l2camsrc->ae_metering_mode);
1282 case PROP_AF_METERING_MODE:
1284 v4l2camsrc->af_metering_mode = g_value_get_enum (value);
1285 v4l2camsrc->mfldadvci->AfSetMeteringMode((ci_adv_AfMeteringMode)v4l2camsrc->af_metering_mode);
1288 case PROP_AF_WINDOW:
1290 GstStructure *af_window_param = NULL;
1292 gboolean parsed = TRUE;
1295 ctmp = g_malloc0 (60);
1298 GST_DEBUG_OBJECT(v4l2camsrc, "alloc string mem failed.\n");
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)
1306 GST_DEBUG_OBJECT(v4l2camsrc,"wrong string format is entered. stop setting af window.\n");
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);
1320 if (parsed == FALSE)
1322 GST_DEBUG_OBJECT(v4l2camsrc,"cannot parse af window parameter. \n");
1323 gst_structure_free (af_window_param);
1328 parsed = gst_structure_get_int(af_window_param, "weight",
1329 &v4l2camsrc->af_window.weight);
1331 if (parsed == FALSE)
1333 GST_DEBUG_OBJECT(v4l2camsrc,
1334 "set af window weight to default value 0x8000.\n");
1335 v4l2camsrc->af_window.weight = 0x8000;
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);
1345 if (v4l2camsrc->af_metering_mode != GST_CAMERA_AF_METERING_SPOT)
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)
1353 GST_DEBUG_OBJECT(v4l2camsrc,"set metering mode failed.\n");
1357 r = v4l2camsrc->mfldadvci->AfSetWindow ((ci_adv_Window *) (&(v4l2camsrc->af_window)));
1358 if(r != ci_adv_Success)
1360 GST_DEBUG_OBJECT(v4l2camsrc,"af set window failed due to 3a lib error.\n");
1363 gst_structure_free (af_window_param);
1369 v4l2camsrc->af_enabled = g_value_get_boolean (value);
1373 v4l2camsrc->awb_enabled = g_value_get_boolean (value);
1376 v4l2camsrc->still_af = g_value_get_boolean (value);
1377 cam_set_autofocus (v4l2camsrc->still_af);
1379 case PROP_FOCUS_POSITION:
1380 v4l2camsrc->focus_posi = g_value_get_int(value);
1382 cam_driver_set_focus_posi (v4l2camsrc->video_fd, v4l2camsrc->focus_posi);
1384 v4l2camsrc->focus_updated = TRUE;
1386 case PROP_BAYER_DOWNSCALING:
1387 v4l2camsrc->bayer_downscaling = g_value_get_boolean (value);
1389 case PROP_CAPTURE_CORRECTION_GDC:
1390 v4l2camsrc->gdc_enabled = g_value_get_boolean (value);
1392 cam_set_capture_correction (v4l2camsrc->video_fd,
1393 CAM_CAPTURE_CORRECTION_GDC, v4l2camsrc->gdc_enabled);
1395 v4l2camsrc->cc_updated = TRUE;
1397 case PROP_CAPTURE_CORRECTION_CAC:
1398 v4l2camsrc->cac_enabled = g_value_get_boolean (value);
1400 cam_set_capture_correction (v4l2camsrc->video_fd,
1401 CAM_CAPTURE_CORRECTION_CAC, v4l2camsrc->cac_enabled);
1403 v4l2camsrc->cc_updated = TRUE;
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);
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);
1415 case PROP_CAPTURE_CORRECTION_DVS:
1416 v4l2camsrc->dvs_enabled = g_value_get_boolean (value);
1418 cam_set_capture_correction (v4l2camsrc->video_fd,
1419 CAM_CAPTURE_CORRECTION_DVS, v4l2camsrc->dvs_enabled);
1421 v4l2camsrc->cc_updated = TRUE;
1423 case PROP_CAPTURE_CORRECTION_EDGE_ENHANCEMENT:
1424 v4l2camsrc->ee_enabled = g_value_get_boolean (value);
1426 cam_set_capture_correction (v4l2camsrc->video_fd,
1427 CAM_CAPTURE_CORRECTION_EE, v4l2camsrc->ee_enabled);
1429 v4l2camsrc->cc_updated = TRUE;
1431 case PROP_CAPTURE_CORRECTION_SHADING_CORRECTION:
1432 v4l2camsrc->sc_enabled = g_value_get_boolean (value);
1434 cam_set_capture_correction (v4l2camsrc->video_fd,
1435 CAM_CAPTURE_CORRECTION_SC, v4l2camsrc->sc_enabled);
1437 v4l2camsrc->cc_updated = TRUE;
1439 case PROP_CAPTURE_CORRECTION_BLACK_LEVEL_COMPENSATION:
1440 v4l2camsrc->blc_enabled = g_value_get_boolean (value);
1442 cam_set_capture_correction (v4l2camsrc->video_fd,
1443 CAM_CAPTURE_CORRECTION_BLC, v4l2camsrc->blc_enabled);
1445 v4l2camsrc->cc_updated = TRUE;
1447 case PROP_CAPTURE_CORRECTION_BAD_PIXEL_DETECTION:
1448 v4l2camsrc->bpd_enabled = g_value_get_boolean (value);
1450 cam_set_capture_correction (v4l2camsrc->video_fd,
1451 CAM_CAPTURE_CORRECTION_BPD, v4l2camsrc->bpd_enabled);
1453 v4l2camsrc->cc_updated = TRUE;
1455 case PROP_CAPTURE_CORRECTION_GAMMA:
1456 v4l2camsrc->tone.gamma = g_value_get_float (value);
1458 cam_set_tone_control (v4l2camsrc->video_fd, CAM_GAMMA_VALUE,
1461 v4l2camsrc->gamma_updated = TRUE;
1463 case PROP_CAPTURE_CORRECTION_CONTRAST:
1464 v4l2camsrc->tone.contrast = g_value_get_int (value);
1466 cam_set_tone_control (v4l2camsrc->video_fd, CAM_CONTRAST_VALUE,
1469 v4l2camsrc->gamma_updated = TRUE;
1471 case PROP_CAPTURE_CORRECTION_BRIGHTNESS:
1472 v4l2camsrc->tone.brightness = g_value_get_int (value);
1474 cam_set_tone_control (v4l2camsrc->video_fd, CAM_BRIGHTNESS_VALUE,
1477 v4l2camsrc->gamma_updated = TRUE;
1480 v4l2camsrc->dump_raw = g_value_get_boolean (value);
1482 case PROP_DUMP_IMAGE:
1483 v4l2camsrc->dump_image = g_value_get_boolean (value);
1485 case PROP_DEBUG_FLAGS:
1486 v4l2camsrc->debug_flags = g_value_get_flags (value);
1489 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1499 gst_v4l2camsrc_get_property (GObject * object,
1500 guint prop_id, GValue * value, GParamSpec * pspec)
1502 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (object);
1506 g_value_set_string (value, v4l2camsrc->videodev);
1508 case PROP_DEVICE_NAME:
1510 const guchar *new = NULL;
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));
1519 g_value_set_string (value, (gchar *) new);
1522 case PROP_DEVICE_FD:
1524 if (gst_v4l2camsrc_is_open (GST_CAMERA_SRC (v4l2camsrc)))
1525 g_value_set_int (value, v4l2camsrc->video_fd);
1527 g_value_set_int (value, DEFAULT_PROP_DEVICE_FD);
1530 case PROP_QUEUE_SIZE:
1531 g_value_set_uint (value, v4l2camsrc->num_buffers);
1533 case PROP_INPUT_SENSOR:
1534 g_value_set_enum (value, v4l2camsrc->input_sensor);
1537 g_value_set_boolean (value, v4l2camsrc->use_mmap);
1540 g_value_set_boolean (value, v4l2camsrc->use_copy);
1543 g_value_set_boolean (value, v4l2camsrc->ae_enabled);
1545 case PROP_AE_METERING_MODE:
1546 g_value_set_enum (value, v4l2camsrc->ae_metering_mode);
1548 case PROP_AE_WINDOW:
1550 GstStructure *tmp = NULL;
1551 tmp = gst_structure_empty_new("ae-window");
1554 GST_DEBUG ("wrong default ae window setting.\n");
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);
1571 g_value_set_boolean (value, v4l2camsrc->af_enabled);
1573 case PROP_AF_METERING_MODE:
1574 g_value_set_enum (value, v4l2camsrc->af_metering_mode);
1576 case PROP_AF_WINDOW:
1578 GstStructure *tmp = NULL;
1579 tmp = gst_structure_empty_new("af-window");
1582 GST_DEBUG ("wrong default af window setting.\n");
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);
1599 g_value_set_boolean (value, v4l2camsrc->awb_enabled);
1602 g_value_set_boolean (value, v4l2camsrc->still_af);
1604 case PROP_FOCUS_POSITION:
1605 g_value_set_int (value, v4l2camsrc->focus_posi);
1607 case PROP_BAYER_DOWNSCALING:
1608 g_value_set_boolean (value, v4l2camsrc->bayer_downscaling);
1610 case PROP_CAPTURE_CORRECTION_GDC:
1611 g_value_set_boolean (value, v4l2camsrc->gdc_enabled);
1613 case PROP_CAPTURE_CORRECTION_CAC:
1614 g_value_set_boolean (value, v4l2camsrc->cac_enabled);
1616 case PROP_CAPTURE_CORRECTION_RER:
1617 g_value_set_boolean (value, v4l2camsrc->rer_enabled);
1619 case PROP_CAPTURE_CORRECTION_DIS:
1620 g_value_set_boolean (value, v4l2camsrc->dis_enabled);
1622 case PROP_CAPTURE_CORRECTION_DVS:
1623 g_value_set_boolean (value, v4l2camsrc->dvs_enabled);
1625 case PROP_CAPTURE_CORRECTION_EDGE_ENHANCEMENT:
1626 g_value_set_boolean (value, v4l2camsrc->ee_enabled);
1628 case PROP_CAPTURE_CORRECTION_SHADING_CORRECTION:
1629 g_value_set_boolean (value, v4l2camsrc->sc_enabled);
1631 case PROP_CAPTURE_CORRECTION_BLACK_LEVEL_COMPENSATION:
1632 g_value_set_boolean (value, v4l2camsrc->blc_enabled);
1634 case PROP_CAPTURE_CORRECTION_BAD_PIXEL_DETECTION:
1635 g_value_set_boolean (value, v4l2camsrc->bpd_enabled);
1637 case PROP_CAPTURE_CORRECTION_GAMMA:
1638 g_value_set_float (value, v4l2camsrc->tone.gamma);
1640 case PROP_CAPTURE_CORRECTION_CONTRAST:
1641 g_value_set_int (value, v4l2camsrc->tone.contrast);
1643 case PROP_CAPTURE_CORRECTION_BRIGHTNESS:
1644 g_value_set_int (value, v4l2camsrc->tone.brightness);
1647 g_value_set_boolean (value, v4l2camsrc->dump_raw);
1649 case PROP_DUMP_IMAGE:
1650 g_value_set_boolean (value, v4l2camsrc->dump_image);
1652 case PROP_DEBUG_FLAGS:
1653 g_value_set_flags (value, v4l2camsrc->debug_flags);
1656 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1664 gst_v4l2camsrc_unlock (GstCameraSrc * src)
1666 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (src);
1668 GST_LOG_OBJECT (v4l2camsrc, "Flushing");
1669 gst_poll_set_flushing (v4l2camsrc->poll, TRUE);
1675 gst_v4l2camsrc_unlock_stop (GstCameraSrc * src)
1677 GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (src);
1679 GST_LOG_OBJECT (v4l2camsrc, "No longer flushing");
1680 gst_poll_set_flushing (v4l2camsrc->poll, FALSE);
1686 * gst_v4l2camsrc_set_zoom:
1687 * @camsrc: @GstCameraSrc object.
1688 * @zoom: zoom factor to be set.
1690 * Set the zoom factor for outputted video.
1692 * Returns: TRUE on success.
1695 gst_v4l2camsrc_set_zoom (GstCameraSrc * camsrc, gfloat zoom)
1697 GstMFLDV4l2CamSrc *v4l2camsrc;
1698 gboolean ret = TRUE;
1700 v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1702 GST_DEBUG_OBJECT (v4l2camsrc, "ZOOM: %f", zoom);
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);
1710 v4l2camsrc->zoom_updated = TRUE;
1716 gst_v4l2camsrc_get_makernote (GstCameraSrc * camsrc, unsigned char *buf, unsigned size)
1718 GstMFLDV4l2CamSrc *v4l2camsrc;
1719 gboolean ret = TRUE;
1721 v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1722 GST_DEBUG_OBJECT (v4l2camsrc, "%s, !!!!!!line:%d\n", __func__, __LINE__);
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);
1733 static gboolean gst_v4l2camsrc_makernote_init(GstCameraSrc * camsrc,
1734 unsigned * buf_size,
1735 unsigned num_afwindows,
1741 GstMFLDV4l2CamSrc *v4l2camsrc;
1742 ENUM_MAKERNOTE_RET_VAL ret;
1744 v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1745 GST_DEBUG_OBJECT (v4l2camsrc, "%s, !!!!!!line:%d\n", __func__, __LINE__);
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)
1757 static gboolean gst_v4l2camsrc_makernote_deal(GstCameraSrc * camsrc,
1758 GstBuffer *pmakerbuf,
1759 unsigned num_afwindows,
1763 GstMFLDV4l2CamSrc *v4l2camsrc;
1764 ENUM_MAKERNOTE_RET_VAL ret;
1766 v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1767 GST_DEBUG_OBJECT (v4l2camsrc, "%s, !!!!!!line:%d\n", __func__, __LINE__);
1769 makernote_util_create(handle, num_afwindows, num_grid, camsrc); // af windows is one, grid for awb is one
1771 ret = makernote_nokia_copy_buffer(handle, GST_BUFFER_DATA(pmakerbuf),
1772 GST_BUFFER_SIZE(pmakerbuf));
1773 if(ENUM_MAKERNOTE_RET_TRUE != ret)
1779 static gboolean gst_v4l2camsrc_makernote_uninit(GstCameraSrc * camsrc,
1782 GstMFLDV4l2CamSrc *v4l2camsrc;
1784 v4l2camsrc = GST_V4L2CAMSRC (camsrc);
1785 GST_DEBUG_OBJECT (v4l2camsrc, "%s, !!!!!!line:%d\n", __func__, __LINE__);
1787 if(makernote_nokia_uninit(handle) != ENUM_MAKERNOTE_RET_TRUE)
1796 * @plugin: GstPlugin
1798 * Returns: TRUE on success.
1801 plugin_init (GstPlugin * plugin)
1803 GST_DEBUG_CATEGORY_INIT (gst_v4l2camsrc_debug, "mfldv4l2camsrc", 0,
1804 "Medfield V4L2 camera source");
1806 return gst_element_register (plugin, "mfldv4l2camsrc",
1807 GST_RANK_NONE, GST_TYPE_V4L2CAMSRC);
1810 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1813 "V4L2 camera image capturing element",
1814 plugin_init, VERSION, "LGPL", "Intel", "www.intel.com")