camera: Add support to generate src_query for vidsrcpad.
[gstreamer-omap:gst-openmax.git] / omx / gstomx_camera.c
1 /* GStreamer
2  *
3  * Copyright (C) 2009 Texas Instruments, Inc - http://www.ti.com/
4  *
5  * Description: OMX Camera element
6  *  Created on: Aug 31, 2009
7  *      Author: Rob Clark <rob@ti.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation
12  * version 2.1 of the License.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23
24 #include "gstomx_camera.h"
25 #include "gstomx.h"
26
27 #include <gst/video/video.h>
28
29 #ifdef USE_OMXTICORE
30 #  include <OMX_TI_IVCommon.h>
31 #  include <OMX_TI_Index.h>
32 #endif
33
34 /**
35  * SECTION:element-omx_camerasrc
36  *
37  * omx_camerasrc can be used to capture video and/or still frames from OMX
38  * camera.  It can also be used as a filter to provide access to the camera's
39  * memory-to-memory mode.
40  * <p>
41  * In total, the omx_camerasrc element exposes one optional input port, "sink",
42  * one mandatory src pad, "src", and two optional src pads, "imgsrc" and
43  * "vidsrc".  If "imgsrc" and/or "vidsrc" are linked, then viewfinder buffers
44  * are pushed on the "src" pad.
45  * <p>
46  * In all modes, preview buffers are pushed on the "src" pad.  In video capture
47  * mode, the same buffer is pushed on the "vidsrc" pad.  In image capture mode,
48  * a separate full resolution image (either raw or jpg encoded) is pushed on
49  * the "imgsrc" pad.
50  * <p>
51  * The camera pad_alloc()s buffers from the "src" pad, in order to allocate
52  * memory from the video driver.  The "vidsrc" caps are slaved to the "src"
53  * caps.  Although this should be considered an implementation detail.
54  * <p>
55  * TODO: for legacy mode support, as a replacement for v4l2src, can we push
56  * buffers of the requested resolution on the "src" pad?  Can we configure the
57  * OMX component for arbitrary resolution on the preview port, or do we need
58  * to dynamically map the "src" pad to different ports depending on the config?
59  * The OMX camera supports only video resolutions on the preview and video
60  * ports, but supports higher resolution stills on the image port.
61  *
62  * <refsect2>
63  * <title>Example launch lines</title>
64  * |[
65  * gst-launch omx_camera vstab=1 mode=2 vnf=1 name=cam cam.src ! queue ! v4l2sink \
66  * cam.vidsrc ! "video/x-raw-yuv, format=(fourcc)UYVY, width=720, height=480, framerate=30/1" ! \
67  * queue ! omx_h264enc matroskamux name=mux ! filesink location=capture.mkv ! \
68  * alsasrc ! "audio/x-raw-int,rate=48000,channels=1, width=16, depth=16, endianness=1234" ! \
69  * queue ! omx_aacenc bitrate=64000 profile=2 ! "audio/mpeg,mpegversion=4,rate=48000,channels=1" ! \
70  * mux. cam.imgsrc ! "image/jpeg, width=720, height=480" ! filesink name=capture.jpg
71  * ]|
72  * </refsect2>
73  */
74
75 static const GstElementDetails element_details =
76 GST_ELEMENT_DETAILS ("Video OMX Camera Source",
77     "Source/Video",
78     "Reads frames from a OMX Camera Component",
79     "Rob Clark <rob@ti.com>");
80
81
82 enum
83 {
84     ARG_0,
85     ARG_NUM_IMAGE_OUTPUT_BUFFERS,
86     ARG_NUM_VIDEO_OUTPUT_BUFFERS,
87     ARG_MODE,
88     ARG_SHUTTER,
89     ARG_ZOOM,
90     ARG_FOCUS,
91     ARG_AWB,
92     ARG_CONTRAST,
93     ARG_BRIGHTNESS,
94     ARG_EXPOSURE,
95     ARG_ISO,
96     ARG_ROTATION,
97     ARG_MIRROR,
98     ARG_SATURATION,
99     ARG_EXPOSUREVALUE,
100     ARG_MANUALFOCUS,
101 #ifdef USE_OMXTICORE
102     ARG_THUMBNAIL_WIDTH,
103     ARG_THUMBNAIL_HEIGHT,
104     ARG_FLICKER,
105     ARG_SCENE,
106     ARG_VNF,
107     ARG_YUV_RANGE,
108     ARG_VSTAB,
109     ARG_DEVICE,
110     ARG_LDC,
111     ARG_NSF,
112     ARG_MTIS,
113 #endif
114 };
115
116 #define DEFAULT_ZOOM_LEVEL          100
117 #define MIN_ZOOM_LEVEL              100
118 #define MAX_ZOOM_LEVEL              600
119 #define CAM_ZOOM_IN_STEP            65536
120 #define DEFAULT_FOCUS               OMX_IMAGE_FocusControlOff
121 #define DEFAULT_AWB                 OMX_WhiteBalControlOff
122 #define DEFAULT_EXPOSURE            OMX_ExposureControlOff
123 #define DEFAULT_CONTRAST_LEVEL      0
124 #define MIN_CONTRAST_LEVEL          -100
125 #define MAX_CONTRAST_LEVEL          100
126 #define DEFAULT_BRIGHTNESS_LEVEL    50
127 #define MIN_BRIGHTNESS_LEVEL        0
128 #define MAX_BRIGHTNESS_LEVEL        100
129 #define DEFAULT_ISO_LEVEL           0
130 #define MIN_ISO_LEVEL               0
131 #define MAX_ISO_LEVEL               1600
132 #define DEFAULT_ROTATION            180
133 #define DEFAULT_MIRROR              OMX_MirrorNone
134 #define MIN_SATURATION_VALUE        -100
135 #define MAX_SATURATION_VALUE        100
136 #define DEFAULT_SATURATION_VALUE    0
137 #define MIN_EXPOSURE_VALUE          -3.0
138 #define MAX_EXPOSURE_VALUE          3.0
139 #define DEFAULT_EXPOSURE_VALUE      0.0
140 #define MIN_MANUALFOCUS             0
141 #define MAX_MANUALFOCUS             100
142 #define DEFAULT_MANUALFOCUS         50
143 #ifdef USE_OMXTICORE
144 #  define DEFAULT_THUMBNAIL_WIDTH   352
145 #  define DEFAULT_THUMBNAIL_HEIGHT  288
146 #  define MIN_THUMBNAIL_LEVEL       16
147 #  define MAX_THUMBNAIL_LEVEL       1920
148 #  define DEFAULT_FLICKER           OMX_FlickerCancelOff
149 #  define DEFAULT_SCENE             OMX_Manual
150 #  define DEFAULT_VNF               OMX_VideoNoiseFilterModeOn
151 #  define DEFAULT_YUV_RANGE         OMX_ITURBT601
152 #  define DEFAULT_DEVICE            OMX_PrimarySensor
153 #  define DEFAULT_NSF               OMX_ISONoiseFilterModeOff
154 #endif
155
156
157 GSTOMX_BOILERPLATE (GstOmxCamera, gst_omx_camera, GstOmxBaseSrc, GST_OMX_BASE_SRC_TYPE);
158
159 #define USE_GSTOMXCAM_IMGSRCPAD
160 #define USE_GSTOMXCAM_VIDSRCPAD
161 //#define USE_VIDEO_PORT
162 //#define USE_GSTOMXCAM_IN_PORT
163
164 /*
165  * Mode table
166  */
167 enum
168 {
169     MODE_PREVIEW        = 0,
170     MODE_VIDEO          = 1,
171     MODE_VIDEO_IMAGE    = 2,
172     MODE_IMAGE          = 3,
173     MODE_IMAGE_HS       = 4,
174 };
175
176 /*
177  * Shutter state
178  */
179 enum
180 {
181     SHUTTER_OFF         = 0,
182     SHUTTER_HALF_PRESS  = 1,
183     SHUTTER_FULL_PRESS  = 2,
184 };
185
186 /**
187  * Table mapping mode to features and ports.  The mode is used as an index
188  * into this table to determine which ports and features are used in that
189  * particular mode.  Since there is some degree of overlap between various
190  * modes, this is to simplify the code to not care about modes, but instead
191  * just which bits are set in the config.
192  */
193 static const enum
194 {
195     /* ports that can be used: */
196     PORT_PREVIEW  = 0x01,
197     PORT_VIDEO    = 0x02,
198     PORT_IMAGE    = 0x04,
199 } config[] = {
200     /* MODE_PREVIEW */            PORT_PREVIEW,
201     /* MODE_VIDEO */              PORT_PREVIEW,
202     /* MODE_VIDEO_IMAGE */        PORT_VIDEO | PORT_IMAGE,
203     /* MODE_IMAGE */              PORT_PREVIEW | PORT_IMAGE,
204     /* MODE_IMAGE_HS */           PORT_PREVIEW | PORT_IMAGE,
205 };
206
207
208
209 /*
210  * Enums:
211  */
212
213 #define GST_TYPE_OMX_CAMERA_MODE (gst_omx_camera_mode_get_type ())
214 static GType
215 gst_omx_camera_mode_get_type (void)
216 {
217     static GType type = 0;
218
219     if (!type)
220     {
221         static GEnumValue vals[] =
222         {
223             {MODE_PREVIEW,        "Preview",                    "preview"},
224             {MODE_VIDEO,          "Video Capture",              "video"},
225             {MODE_VIDEO_IMAGE,    "Video+Image Capture",        "video-image"},
226             {MODE_IMAGE,          "Image Capture",              "image"},
227             {MODE_IMAGE_HS,       "Image Capture High Speed",   "image-hs"},
228             {0, NULL, NULL},
229         };
230
231         type = g_enum_register_static ("GstOmxCameraMode", vals);
232     }
233
234     return type;
235 }
236
237 #define GST_TYPE_OMX_CAMERA_SHUTTER (gst_omx_camera_shutter_get_type ())
238 static GType
239 gst_omx_camera_shutter_get_type (void)
240 {
241     static GType type = 0;
242
243     if (!type)
244     {
245         static GEnumValue vals[] =
246         {
247             {SHUTTER_OFF,         "Off",                        "off"},
248             {SHUTTER_HALF_PRESS,  "Half Press",                 "half-press"},
249             {SHUTTER_FULL_PRESS,  "Full Press",                 "full-press"},
250             {0, NULL, NULL},
251         };
252
253         type = g_enum_register_static ("GstOmxCameraShutter", vals);
254     }
255
256     return type;
257 }
258
259 #define GST_TYPE_OMX_CAMERA_FOCUS (gst_omx_camera_focus_get_type ())
260 static GType
261 gst_omx_camera_focus_get_type (void)
262 {
263     static GType type = 0;
264
265     if (!type)
266     {
267         static GEnumValue vals[] =
268         {
269             {OMX_IMAGE_FocusControlOff,      "off",              "off"},
270             {OMX_IMAGE_FocusControlOn,       "on",               "on"},
271             {OMX_IMAGE_FocusControlAuto,     "auto",             "auto"},
272             {OMX_IMAGE_FocusControlAutoLock, "autolock",         "autolock"},
273             {0, NULL, NULL},
274         };
275
276         type = g_enum_register_static ("GstOmxCameraFocus", vals);
277     }
278
279     return type;
280 }
281
282 #define GST_TYPE_OMX_CAMERA_AWB (gst_omx_camera_awb_get_type ())
283 static GType
284 gst_omx_camera_awb_get_type ()
285 {
286     static GType type = 0;
287
288     if (!type)
289     {
290         static const GEnumValue vals[] =
291         {
292             {OMX_WhiteBalControlOff,           "Balance off",    "off"},
293             {OMX_WhiteBalControlAuto,          "Auto balance",   "auto"},
294             {OMX_WhiteBalControlSunLight,      "Sun light",      "sunlight"},
295             {OMX_WhiteBalControlCloudy,        "Cloudy",         "cloudy"},
296             {OMX_WhiteBalControlShade,         "Shade",          "shade"},
297             {OMX_WhiteBalControlTungsten,      "Tungsten",       "tungsten"},
298             {OMX_WhiteBalControlFluorescent,   "Fluorescent",    "fluorescent"},
299             {OMX_WhiteBalControlIncandescent,  "Incandescent",   "incandescent"},
300             {OMX_WhiteBalControlFlash,         "Flash",          "flash" },
301             {OMX_WhiteBalControlHorizon,       "Horizon",        "horizon" },
302             {0, NULL, NULL },
303         };
304
305         type = g_enum_register_static ("GstOmxCameraWhiteBalance",vals);
306     }
307
308     return type;
309 }
310
311 #define GST_TYPE_OMX_CAMERA_EXPOSURE (gst_omx_camera_exposure_get_type ())
312 static GType
313 gst_omx_camera_exposure_get_type ()
314 {
315     static GType type = 0;
316
317     if (!type)
318     {
319         static const GEnumValue vals[] =
320         {
321             {OMX_ExposureControlOff,             "Exposure control off",     "off"},
322             {OMX_ExposureControlAuto,            "Auto exposure",            "auto"},
323             {OMX_ExposureControlNight,           "Night exposure",           "night"},
324             {OMX_ExposureControlBackLight,       "Backlight exposure",       "backlight"},
325             {OMX_ExposureControlSpotLight,       "SportLight exposure",      "sportlight"},
326             {OMX_ExposureControlSports,          "Sports exposure",          "sports"},
327             {OMX_ExposureControlSnow,            "Snow exposure",            "snow"},
328             {OMX_ExposureControlBeach,           "Beach exposure",           "beach"},
329             {OMX_ExposureControlLargeAperture,   "Large aperture exposure",  "large-aperture"},
330             {OMX_ExposureControlSmallApperture,  "Small aperture exposure",  "small-aperture"},
331             {0, NULL, NULL },
332         };
333
334         type = g_enum_register_static ("GstOmxCameraExposureControl", vals);
335     }
336
337     return type;
338 }
339
340 #define GST_TYPE_OMX_CAMERA_MIRROR (gst_omx_camera_mirror_get_type ())
341 static GType
342 gst_omx_camera_mirror_get_type (void)
343 {
344     static GType type = 0;
345
346     if (!type)
347     {
348         static GEnumValue vals[] =
349         {
350             {OMX_MirrorNone,        "Off",              "off"},
351             {OMX_MirrorVertical,    "Vertical",         "vertical"},
352             {OMX_MirrorHorizontal,  "Horizontal",       "horizontal"},
353             {OMX_MirrorBoth,        "Both",             "both"},
354             {0, NULL, NULL},
355         };
356
357         type = g_enum_register_static ("GstOmxCameraMirror", vals);
358     }
359
360     return type;
361 }
362
363 #ifdef USE_OMXTICORE
364 #define GST_TYPE_OMX_CAMERA_FLICKER (gst_omx_camera_flicker_get_type ())
365 static GType
366 gst_omx_camera_flicker_get_type ()
367 {
368     static GType type = 0;
369
370     if (!type)
371     {
372         static const GEnumValue vals[] =
373         {
374             {OMX_FlickerCancelOff,  "Flicker control off",       "off"},
375             {OMX_FlickerCancelAuto, "Auto flicker control",      "auto"},
376             {OMX_FlickerCancel50,   "Flicker control for 50Hz",  "flick-50hz"},
377             {OMX_FlickerCancel60,   "Flicker control for 60Hz",  "flick-60hz"},
378             {0, NULL, NULL },
379         };
380
381         type = g_enum_register_static ("GstOmxCameraFlickerCancel", vals);
382     }
383
384     return type;
385 }
386
387 #define GST_TYPE_OMX_CAMERA_SCENE (gst_omx_camera_scene_get_type ())
388 static GType
389 gst_omx_camera_scene_get_type ()
390 {
391     static GType type = 0;
392
393     if (!type)
394     {
395         static const GEnumValue vals[] =
396         {
397             {OMX_Manual,         "Manual settings",         "manual"},
398             {OMX_Closeup,        "Closeup settings",        "closeup"},
399             {OMX_Portrait,       "Portrait settings",       "portrait"},
400             {OMX_Landscape,      "Landscape settings",      "landscape"},
401             {OMX_Underwater,     "Underwater settings",     "underwater"},
402             {OMX_Sport,          "Sport settings",          "sport"},
403             {OMX_SnowBeach,      "SnowBeach settings",      "snowbeach"},
404             {OMX_Mood,           "Mood settings",           "mood"},
405 #if 0       /* The following options are not yet enabled at OMX level */
406             {OMX_NightPortrait,  "NightPortrait settings",  "night-portrait"},
407             {OMX_NightIndoor,    "NightIndoor settings",    "night-indoor"},
408             {OMX_Fireworks,      "Fireworks settings",      "fireworks"},
409             /* for still image: */
410             {OMX_Document,       "Document settings",       "document"},
411             {OMX_Barcode,        "Barcode settings",        "barcode"},
412             /* for video: */
413             {OMX_SuperNight,     "SuperNight settings",     "supernight"},
414             {OMX_Cine,           "Cine settings",           "cine"},
415             {OMX_OldFilm,        "OldFilm settings",        "oldfilm"},
416 #endif
417             {0, NULL, NULL},
418         };
419
420         type = g_enum_register_static ("GstOmxCameraScene", vals);
421     }
422
423     return type;
424 }
425
426 #define GST_TYPE_OMX_CAMERA_VNF (gst_omx_camera_vnf_get_type ())
427 static GType
428 gst_omx_camera_vnf_get_type (void)
429 {
430     static GType type = 0;
431
432     if (!type)
433     {
434         static GEnumValue vals[] =
435         {
436             {OMX_VideoNoiseFilterModeOff,   "off",              "off"},
437             {OMX_VideoNoiseFilterModeOn,    "on",               "on"},
438             {OMX_VideoNoiseFilterModeAuto,  "auto",             "auto"},
439             {0, NULL, NULL},
440         };
441
442         type = g_enum_register_static ("GstOmxCameraVnf", vals);
443     }
444
445     return type;
446 }
447
448 #define GST_TYPE_OMX_CAMERA_YUV_RANGE (gst_omx_camera_yuv_range_get_type ())
449 static GType
450 gst_omx_camera_yuv_range_get_type (void)
451 {
452     static GType type = 0;
453
454     if (!type)
455     {
456         static GEnumValue vals[] =
457         {
458             {OMX_ITURBT601,       "OMX_ITURBT601",              "OMX_ITURBT601"},
459             {OMX_Full8Bit,        "OMX_Full8Bit",               "OMX_Full8Bit"},
460             {0, NULL, NULL},
461         };
462
463         type = g_enum_register_static ("GstOmxCameraYuvRange", vals);
464     }
465
466     return type;
467 }
468
469 #define GST_TYPE_OMX_CAMERA_DEVICE (gst_omx_camera_device_get_type ())
470 static GType
471 gst_omx_camera_device_get_type (void)
472 {
473     static GType type = 0;
474
475     if (!type)
476     {
477         static GEnumValue vals[] =
478         {
479             {OMX_PrimarySensor,     "Primary",          "primary"},
480             {OMX_SecondarySensor,   "Secondary",        "secondary"},
481             {OMX_TI_StereoSensor,   "Stereo",           "stereo"},
482             {0, NULL, NULL},
483         };
484
485         type = g_enum_register_static ("GstOmxCameraDevice", vals);
486     }
487
488     return type;
489 }
490
491 #define GST_TYPE_OMX_CAMERA_NSF (gst_omx_camera_nsf_get_type ())
492 static GType
493 gst_omx_camera_nsf_get_type ()
494 {
495     static GType type = 0;
496
497     if (!type)
498     {
499         static const GEnumValue vals[] =
500         {
501             {OMX_ISONoiseFilterModeOff,     "nsf control off",    "off"},
502             {OMX_ISONoiseFilterModeOn,      "nsf control on",     "on"},
503             {OMX_ISONoiseFilterModeAuto,    "nsf control auto",   "auto"},
504             {0, NULL, NULL },
505         };
506
507         type = g_enum_register_static ("GstOmxCameraISONoiseFilter", vals);
508     }
509
510     return type;
511 }
512 #endif
513
514
515 /*
516  * Caps:
517  */
518
519
520 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
521         GST_PAD_SRC,
522         GST_PAD_ALWAYS,
523         GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV_STRIDED (GSTOMX_ALL_FORMATS, "[ 0, max ]"))
524     );
525
526 static GstStaticPadTemplate imgsrc_template = GST_STATIC_PAD_TEMPLATE ("imgsrc",
527         GST_PAD_SRC,
528         GST_PAD_SOMETIMES,
529         /* Note: imgsrc pad supports JPEG format, Bayer, as well as
530            non-strided YUV. */
531         GST_STATIC_CAPS (
532                 "image/jpeg, width=(int)[1,max], height=(int)[1,max]; "
533                 "video/x-raw-bayer, width=(int)[1,max], height=(int)[1,max]; "
534                 GST_VIDEO_CAPS_YUV (GSTOMX_ALL_FORMATS))
535     );
536
537 static GstStaticPadTemplate vidsrc_template = GST_STATIC_PAD_TEMPLATE ("vidsrc",
538         GST_PAD_SRC,
539         GST_PAD_SOMETIMES,
540         GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV_STRIDED (GSTOMX_ALL_FORMATS, "[ 0, max ]"))
541     );
542
543 #ifdef USE_GSTOMXCAM_IN_PORT
544 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
545         GST_PAD_SINK,
546         GST_PAD_ALWAYS,
547         GST_STATIC_CAPS ("???")
548     );
549 #endif
550
551 static gboolean
552 src_setcaps (GstPad *pad, GstCaps *caps)
553 {
554     GstOmxCamera *self = GST_OMX_CAMERA (GST_PAD_PARENT (pad));
555     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
556
557     GstVideoFormat format;
558     gint width, height, rowstride;
559     gint framerate_num, framerate_denom;
560     const GValue *framerate = NULL;
561
562     if (!self)
563     {
564         GST_DEBUG_OBJECT (pad, "pad has no parent (yet?)");
565         return TRUE;  // ???
566     }
567
568     GST_INFO_OBJECT (omx_base, "setcaps (src/vidsrc): %" GST_PTR_FORMAT, caps);
569
570     g_return_val_if_fail (caps, FALSE);
571     g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
572
573     if (gst_video_format_parse_caps_strided (caps,
574             &format, &width, &height, &rowstride))
575     {
576         /* Output port configuration: */
577         OMX_PARAM_PORTDEFINITIONTYPE param;
578
579         G_OMX_PORT_GET_DEFINITION (omx_base->out_port, &param);
580
581         param.format.video.eColorFormat = g_omx_gstvformat_to_colorformat (format);
582         param.format.video.nFrameWidth  = width;
583         param.format.video.nFrameHeight = height;
584         param.format.video.nStride      = self->rowstride = rowstride;
585         param.nBufferSize = gst_video_format_get_size_strided (format, width, height, rowstride);
586
587         /* special hack to work around OMX camera bug:
588          */
589         if (param.format.video.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar)
590             param.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
591
592         framerate = gst_structure_get_value (
593                 gst_caps_get_structure (caps, 0), "framerate");
594
595         if (framerate)
596         {
597             framerate_num = gst_value_get_fraction_numerator (framerate);
598             framerate_denom = gst_value_get_fraction_denominator (framerate);
599
600             param.format.video.xFramerate = (framerate_num << 16) / framerate_denom;
601         }
602
603         /* At the moment we are only using preview port and not vid_port
604          * From omx camera desing document we are missing
605          * SetParam CommonSensormode -> bOneShot = FALSE ?
606          */
607         G_OMX_PORT_SET_DEFINITION (omx_base->out_port, &param);
608
609 #ifdef USE_VIDEO_PORT
610         G_OMX_PORT_SET_DEFINITION (self->vid_port, &param);
611 #endif
612
613         GST_INFO_OBJECT (omx_base, " Rowstride=%d, Width=%d, Height=%d, Color=%d, Buffersize=%d, framerate=%d",
614             param.format.video.nStride, param.format.video.nFrameWidth, param.format.video.nFrameHeight, param.format.video.eColorFormat, param.nBufferSize,param.format.video.xFramerate );
615
616         gst_pad_set_caps (GST_BASE_SRC (self)->srcpad, caps);
617 #if 0
618         /* force the src pad and vidsrc pad to use the same caps: */
619         if (pad == self->vidsrcpad)
620         {
621             gst_pad_set_caps (GST_BASE_SRC (self)->srcpad, caps);
622         }
623         else
624         {
625             gst_pad_set_caps (self->vidsrcpad, caps);
626         }
627
628         GST_INFO_OBJECT (omx_base, " exit setcaps src: %");
629 #endif
630     }
631
632     return TRUE;
633 }
634
635 static gboolean
636 imgsrc_setcaps (GstPad *pad, GstCaps *caps)
637 {
638     GstOmxCamera *self = GST_OMX_CAMERA (GST_PAD_PARENT (pad));
639     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
640
641     GstVideoFormat format;
642     gint width, height, rowstride;
643     GstStructure *s;
644
645     GST_INFO_OBJECT (omx_base, "setcaps (imgsrc): %" GST_PTR_FORMAT, caps);
646
647     g_return_val_if_fail (caps, FALSE);
648     g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
649
650     if (gst_video_format_parse_caps_strided (caps,
651             &format, &width, &height, &rowstride))
652     {
653         /* Output port configuration for YUV: */
654         OMX_PARAM_PORTDEFINITIONTYPE param;
655
656         GST_DEBUG_OBJECT (self, "set raw format");
657
658         G_OMX_PORT_GET_DEFINITION (self->img_port, &param);
659
660         param.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
661         param.format.image.eColorFormat = g_omx_gstvformat_to_colorformat (format);
662         param.format.image.nFrameWidth  = width;
663         param.format.image.nFrameHeight = height;
664         param.format.image.nStride      = rowstride;
665
666         /* special hack to work around OMX camera bug:
667          */
668         if (param.format.video.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar)
669             param.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
670
671         G_OMX_PORT_SET_DEFINITION (self->img_port, &param);
672     }
673     else if (gst_structure_has_name (s=gst_caps_get_structure (caps, 0), "image/jpeg"))
674     {
675         /* Output port configuration for JPEG: */
676         OMX_PARAM_PORTDEFINITIONTYPE param;
677
678         GST_DEBUG_OBJECT (self, "set JPEG format");
679
680         G_OMX_PORT_GET_DEFINITION (self->img_port, &param);
681
682         gst_structure_get_int (s, "width", &width);
683         gst_structure_get_int (s, "height", &height);
684
685         param.format.image.eColorFormat = OMX_COLOR_FormatCbYCrY;
686         param.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
687         param.format.image.nFrameWidth  = width;
688         param.format.image.nFrameHeight = height;
689         param.format.image.nStride      = 0;
690
691         GST_INFO_OBJECT (self, "Rowstride=%d, Width=%d, Height=%d, Buffersize=%d, num-buffer=%d",
692             param.format.image.nStride, param.format.image.nFrameWidth, param.format.image.nFrameHeight, param.nBufferSize, param.nBufferCountActual);
693
694         G_OMX_PORT_SET_DEFINITION (self->img_port, &param);
695     }
696     else if (gst_structure_has_name (s=gst_caps_get_structure (caps, 0),
697                      "video/x-raw-bayer"))
698     {
699         /* Output port configuration for Bayer: */
700         OMX_PARAM_PORTDEFINITIONTYPE param;
701
702         GST_DEBUG_OBJECT (self, "set Raw-Bayer format");
703
704         G_OMX_PORT_GET_DEFINITION (self->img_port, &param);
705
706         gst_structure_get_int (s, "width", &width);
707         gst_structure_get_int (s, "height", &height);
708
709         param.format.image.eColorFormat = OMX_COLOR_FormatRawBayer10bit;
710         param.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
711         param.format.image.nFrameWidth  = width;
712         param.format.image.nFrameHeight = height;
713         param.format.image.nStride      = width * 2;
714
715         GST_INFO_OBJECT (self, "Rowstride=%d, Width=%d, Height=%d, "
716             "Buffersize=%d, num-buffer=%d", param.format.image.nStride,
717             param.format.image.nFrameWidth, param.format.image.nFrameHeight,
718             param.nBufferSize, param.nBufferCountActual);
719
720         G_OMX_PORT_SET_DEFINITION (self->img_port, &param);
721     }
722
723     return TRUE;
724 }
725
726 static gboolean
727 src_query (GstPad *pad, GstQuery *query)
728 {
729     GstOmxCamera *self = GST_OMX_CAMERA (GST_PAD_PARENT (pad));
730     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
731     gboolean ret = FALSE;
732
733     GST_DEBUG_OBJECT (self, "Begin");
734
735     if (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERS)
736     {
737         const GstCaps *caps;
738         OMX_ERRORTYPE err;
739         OMX_PARAM_PORTDEFINITIONTYPE param;
740
741         _G_OMX_INIT_PARAM (&param);
742
743         gst_query_parse_buffers_caps (query, &caps);
744
745         /* ensure the caps we are querying are the current ones, otherwise
746          * results are meaningless..
747          *
748          * @todo should we save and restore current caps??
749          */
750         src_setcaps (pad, (GstCaps *)caps);
751
752         param.nPortIndex = omx_base->out_port->port_index;
753         err = OMX_GetParameter (omx_base->gomx->omx_handle,
754                 OMX_IndexParamPortDefinition, &param);
755         g_assert (err == OMX_ErrorNone);
756
757         GST_DEBUG_OBJECT (self, "Actual buffers: %d", param.nBufferCountActual);
758
759         gst_query_set_buffers_count (query, param.nBufferCountActual);
760
761 #ifdef USE_OMXTICORE
762         {
763             OMX_CONFIG_RECTTYPE rect;
764             _G_OMX_INIT_PARAM (&rect);
765
766             rect.nPortIndex = omx_base->out_port->port_index;
767             err = OMX_GetParameter (omx_base->gomx->omx_handle,
768                     OMX_TI_IndexParam2DBufferAllocDimension, &rect);
769             if (err == OMX_ErrorNone)
770             {
771                 GST_DEBUG_OBJECT (self, "Min dimensions: %dx%d",
772                         rect.nWidth, rect.nHeight);
773
774                 gst_query_set_buffers_dimensions (query,
775                         rect.nWidth, rect.nHeight);
776             }
777         }
778 #endif
779
780         ret = TRUE;
781     }
782
783     GST_DEBUG_OBJECT (self, "End -> %d", ret);
784
785     return ret;
786 }
787
788 /* note.. maybe this should be moved somewhere common... GstOmxBaseVideoDec has
789  * almost same logic..
790  */
791 static void
792 settings_changed (GstElement *self, GstPad *pad)
793 {
794     GstCaps *new_caps;
795
796     if (!gst_pad_is_linked (pad))
797     {
798         GST_DEBUG_OBJECT (self, "%"GST_PTR_FORMAT": pad is not linked", pad);
799         return;
800     }
801
802     new_caps = gst_caps_intersect (gst_pad_get_caps (pad),
803            gst_pad_peer_get_caps (pad));
804
805     if (!gst_caps_is_fixed (new_caps))
806     {
807         gst_caps_do_simplify (new_caps);
808         GST_INFO_OBJECT (self, "%"GST_PTR_FORMAT": pre-fixated caps: %" GST_PTR_FORMAT, pad, new_caps);
809         gst_pad_fixate_caps (pad, new_caps);
810     }
811
812     GST_INFO_OBJECT (self, "%"GST_PTR_FORMAT": caps are: %" GST_PTR_FORMAT, pad, new_caps);
813     GST_INFO_OBJECT (self, "%"GST_PTR_FORMAT": old caps are: %" GST_PTR_FORMAT, pad, GST_PAD_CAPS (pad));
814
815     gst_pad_set_caps (pad, new_caps);
816 }
817
818 static void
819 settings_changed_cb (GOmxCore *core)
820 {
821     GstOmxCamera *self = core->object;
822
823     GST_DEBUG_OBJECT (self, "settings changed");
824
825     settings_changed (GST_ELEMENT (self), GST_BASE_SRC (self)->srcpad);
826
827 #ifdef USE_GSTOMXCAM_VIDSRCPAD
828     settings_changed (GST_ELEMENT (self), self->vidsrcpad);
829 #endif
830 #ifdef USE_GSTOMXCAM_IMGSRCPAD
831     settings_changed (GST_ELEMENT (self), self->imgsrcpad);
832 #endif
833 }
834
835 static void
836 setup_ports (GstOmxBaseSrc *base_src)
837 {
838     GstOmxCamera *self = GST_OMX_CAMERA (base_src);
839     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
840     OMX_PARAM_PORTDEFINITIONTYPE param;
841
842 #ifdef USE_VIDEO_PORT
843     G_OMX_PORT_GET_DEFINITION (self->vid_port, &param);
844     g_omx_port_setup (self->vid_port, &param);
845 #endif
846
847 #ifdef USE_GSTOMXCAM_IMGSRCPAD
848     G_OMX_PORT_GET_DEFINITION (self->img_port, &param);
849     g_omx_port_setup (self->img_port, &param);
850 #endif
851
852 #ifdef USE_GSTOMXCAM_IN_PORT
853     G_OMX_PORT_GET_DEFINITION (self->in_port, &param);
854     g_omx_port_setup (self->in_port, &param);
855 #endif
856
857 /*   Not supported yet
858     self->vid_port->share_buffer = TRUE;
859     self->img_port->share_buffer = TRUE;
860 */
861     omx_base->out_port->omx_allocate = FALSE;
862     omx_base->out_port->share_buffer = TRUE;
863
864 #ifdef USE_GSTOMXCAM_IMGSRCPAD
865     self->img_port->omx_allocate = TRUE;
866     self->img_port->share_buffer = FALSE;
867 #endif
868
869 }
870
871
872 static GstClockTime
873 get_timestamp (GstOmxCamera *self)
874 {
875     GstClock *clock;
876     GstClockTime timestamp;
877
878     /* timestamps, LOCK to get clock and base time. */
879     GST_OBJECT_LOCK (self);
880     if ((clock = GST_ELEMENT_CLOCK (self))) {
881       /* we have a clock, get base time and ref clock */
882       timestamp = GST_ELEMENT (self)->base_time;
883       gst_object_ref (clock);
884     } else {
885       /* no clock, can't set timestamps */
886       timestamp = GST_CLOCK_TIME_NONE;
887     }
888     GST_OBJECT_UNLOCK (self);
889
890     if (clock) {
891       /* the time now is the time of the clock minus the base time */
892       /* Hack: Need to subtract the extra lag that is causing problems to AV sync */
893       timestamp = gst_clock_get_time (clock) - timestamp - (140 * GST_MSECOND);
894       gst_object_unref (clock);
895
896       /* if we have a framerate adjust timestamp for frame latency */
897 #if 0
898       if (self->fps_n > 0 && self->fps_d > 0)
899       {
900         GstClockTime latency;
901
902         latency = gst_util_uint64_scale_int (GST_SECOND, self->fps_d, self->fps_n);
903
904         if (timestamp > latency)
905           timestamp -= latency;
906         else
907           timestamp = 0;
908       }
909 #endif
910     }
911
912     return timestamp;
913 }
914
915 #ifdef USE_GSTOMXCAM_IMGSRCPAD
916 /** This function configure the camera component on capturing/no capturing mode **/
917 static void
918 set_capture (GstOmxCamera *self, gboolean capture_mode)
919 {
920     OMX_CONFIG_BOOLEANTYPE param;
921     GOmxCore *gomx;
922     OMX_ERRORTYPE err;
923     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
924
925     gomx = (GOmxCore *) omx_base->gomx;
926
927     _G_OMX_INIT_PARAM (&param);
928
929     param.bEnabled = (capture_mode == TRUE) ? OMX_TRUE : OMX_FALSE;
930
931     err = G_OMX_CORE_SET_CONFIG (gomx, OMX_IndexConfigCapturing, &param);
932     g_warn_if_fail (err == OMX_ErrorNone);
933
934     GST_DEBUG_OBJECT (self, "Capture = %d", param.bEnabled);
935 }
936 #endif
937
938 static void
939 set_camera_operating_mode (GstOmxCamera *self)
940 {
941     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
942     OMX_CONFIG_CAMOPERATINGMODETYPE mode;
943     GOmxCore *gomx;
944     OMX_ERRORTYPE error_val = OMX_ErrorNone;
945
946     gomx = (GOmxCore *) omx_base->gomx;
947     _G_OMX_INIT_PARAM (&mode);
948
949     switch (self->next_mode)
950     {
951         case MODE_VIDEO:
952             mode.eCamOperatingMode = OMX_CaptureVideo;
953             break;
954         case MODE_PREVIEW:
955         case MODE_IMAGE:
956             mode.eCamOperatingMode = OMX_CaptureImageProfileBase;
957             break;
958         case MODE_VIDEO_IMAGE:     /* @todo check this */
959         case MODE_IMAGE_HS:
960             mode.eCamOperatingMode =
961                 OMX_CaptureImageHighSpeedTemporalBracketing;
962             break;
963         default:
964             g_assert_not_reached ();
965     }
966     GST_DEBUG_OBJECT (self, "OMX_CaptureImageMode: set = %d",
967             mode.eCamOperatingMode);
968     error_val = OMX_SetParameter (gomx->omx_handle,
969             OMX_IndexCameraOperatingMode, &mode);
970     g_assert (error_val == OMX_ErrorNone);
971 }
972
973 static void
974 start_ports (GstOmxCamera *self)
975 {
976
977 #if 0
978     /* Not utilized  because we are setting the preview port enable since the beginning*/
979
980     if (config[self->mode] & PORT_PREVIEW)
981     {
982         GST_DEBUG_OBJECT (self, "enable preview port");
983         g_omx_port_enable (omx_base->out_port);
984     }
985 #endif
986
987 #ifdef USE_GSTOMXCAM_VIDSRCPAD
988     if (config[self->mode] & PORT_VIDEO)
989     {
990         GST_DEBUG_OBJECT (self, "enable video port");
991         gst_pad_set_active (self->vidsrcpad, TRUE);
992         gst_element_add_pad (GST_ELEMENT_CAST (self), self->vidsrcpad);
993         g_omx_port_enable (self->vid_port);
994     }
995     else if (self->mode == MODE_VIDEO)
996     {
997         GST_DEBUG_OBJECT (self, "enable video srcpad");
998         gst_pad_set_active (self->vidsrcpad, TRUE);
999         gst_element_add_pad (GST_ELEMENT_CAST (self), self->vidsrcpad);
1000     }
1001 #endif
1002
1003 #ifdef USE_GSTOMXCAM_IMGSRCPAD
1004     if (config[self->mode] & PORT_IMAGE)
1005     {
1006         GST_DEBUG_OBJECT (self, "enable image port");
1007         gst_pad_set_active (self->imgsrcpad, TRUE);
1008         gst_element_add_pad (GST_ELEMENT_CAST (self), self->imgsrcpad);
1009
1010         /* WORKAROUND: Image capture set only in LOADED state */
1011         /* set_camera_operating_mode (self); */
1012         g_omx_port_enable (self->img_port);
1013
1014         GST_DEBUG_OBJECT (self, "image port set_capture set to  %d", TRUE);
1015         set_capture (self, TRUE);
1016     }
1017 #endif
1018 }
1019
1020
1021 static void
1022 stop_ports (GstOmxCamera *self)
1023 {
1024
1025 #if 0
1026     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
1027     if (config[self->mode] & PORT_PREVIEW)
1028     {
1029         GST_DEBUG_OBJECT (self, "disable preview port");
1030         g_omx_port_disable (omx_base->out_port);
1031     }
1032 #endif
1033
1034 #ifdef USE_GSTOMXCAM_VIDSRCPAD
1035     if (config[self->mode] & PORT_VIDEO)
1036     {
1037         GST_DEBUG_OBJECT (self, "disable video port");
1038         gst_pad_set_active (self->vidsrcpad, FALSE);
1039         //gst_element_remove_pad (GST_ELEMENT_CAST (self), self->vidsrcpad);
1040         g_omx_port_disable (self->vid_port);
1041     }
1042     else if (self->mode == MODE_VIDEO)
1043     {
1044         GST_DEBUG_OBJECT (self, "disable video src pad");
1045         gst_pad_set_active (self->vidsrcpad, FALSE);
1046     }
1047 #endif
1048
1049 #ifdef USE_GSTOMXCAM_IMGSRCPAD
1050     if (config[self->mode] & PORT_IMAGE)
1051     {
1052         GST_DEBUG_OBJECT (self, "disable image port");
1053         gst_pad_set_active (self->imgsrcpad, FALSE);
1054         //gst_element_remove_pad (GST_ELEMENT_CAST (self), self->imgsrcpad);
1055         g_omx_port_disable (self->img_port);
1056     }
1057 #endif
1058 }
1059
1060
1061 /*
1062  * GstBaseSrc Methods:
1063  */
1064
1065 static GstFlowReturn
1066 create (GstBaseSrc *gst_base,
1067         guint64 offset,
1068         guint length,
1069         GstBuffer **ret_buf)
1070 {
1071     GstOmxCamera *self = GST_OMX_CAMERA (gst_base);
1072     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
1073     GstBuffer *preview_buf = NULL;
1074     GstBuffer *vid_buf = NULL;
1075     GstBuffer *img_buf = NULL;
1076     GstFlowReturn ret = GST_FLOW_NOT_NEGOTIATED;
1077     GstClockTime timestamp;
1078     GstEvent *vstab_evt = NULL;
1079     gboolean pending_eos;
1080     guint n_offset = 0;
1081     static guint cont;
1082
1083     pending_eos = g_atomic_int_compare_and_exchange (&self->pending_eos, TRUE, FALSE);
1084
1085     GST_DEBUG_OBJECT (self, "begin, mode=%d, pending_eos=%d", self->mode, pending_eos);
1086
1087     GST_LOG_OBJECT (self, "state: %d", omx_base->gomx->omx_state);
1088
1089     if (omx_base->gomx->omx_state == OMX_StateLoaded)
1090     {
1091         GST_INFO_OBJECT (self, "omx: prepare");
1092         gst_omx_base_src_setup_ports (omx_base);
1093         g_omx_core_prepare (omx_base->gomx);
1094     }
1095
1096     if (self->mode != self->next_mode)
1097     {
1098         if (self->mode != -1)
1099             stop_ports (self);
1100         self->mode = self->next_mode;
1101         start_ports (self);
1102
1103         /* @todo for now just capture one image... later let the user config
1104          * this to the number of desired burst mode images
1105          */
1106         if (self->mode == MODE_IMAGE)
1107             self->img_count = 1;
1108         if (self->mode == MODE_IMAGE_HS)
1109             self->img_count = self->img_port->num_buffers;
1110     }
1111
1112     if (config[self->mode] & PORT_PREVIEW)
1113     {
1114         ret = gst_omx_base_src_create_from_port (omx_base,
1115                 omx_base->out_port, &preview_buf);
1116         n_offset = omx_base->out_port->n_offset;
1117         if (ret != GST_FLOW_OK)
1118             goto fail;
1119     }
1120
1121     if (config[self->mode] & PORT_VIDEO)
1122     {
1123         ret = gst_omx_base_src_create_from_port (omx_base,
1124                 self->vid_port, &vid_buf);
1125         n_offset = self->vid_port->n_offset;
1126         if (ret != GST_FLOW_OK)
1127             goto fail;
1128     }
1129     else if (self->mode == MODE_VIDEO)
1130     {
1131         vid_buf = gst_buffer_ref (preview_buf);
1132     }
1133
1134     if (config[self->mode] & PORT_IMAGE)
1135     {
1136         ret = gst_omx_base_src_create_from_port (omx_base,
1137                 self->img_port, &img_buf);
1138         if (ret != GST_FLOW_OK)
1139             goto fail;
1140
1141         if (--self->img_count == 0)
1142         {
1143             self->next_mode = MODE_PREVIEW;
1144             GST_DEBUG_OBJECT (self, "image port set_capture set to %d", FALSE);
1145             set_capture (self, FALSE);
1146         }
1147         GST_DEBUG_OBJECT (self, "### img_count = %d ###", self->img_count);
1148     }
1149
1150     if (vid_buf && !preview_buf)
1151     {
1152         preview_buf = gst_buffer_ref (vid_buf);
1153     }
1154
1155     timestamp = get_timestamp (self);
1156     cont ++;
1157     GST_DEBUG_OBJECT (self, "******** preview buffers cont = %d", cont);
1158     GST_BUFFER_TIMESTAMP (preview_buf) = timestamp;
1159
1160     *ret_buf = preview_buf;
1161
1162     if (n_offset)
1163     {
1164         vstab_evt = gst_event_new_vstab (n_offset / self->rowstride, /* top */
1165                 n_offset % self->rowstride); /* left */
1166         gst_pad_push_event (GST_BASE_SRC (self)->srcpad,
1167                 gst_event_ref (vstab_evt));
1168     }
1169
1170     if (vid_buf)
1171     {
1172         GST_DEBUG_OBJECT (self, "pushing vid_buf");
1173         GST_BUFFER_TIMESTAMP (vid_buf) = timestamp;
1174         if (vstab_evt)
1175             gst_pad_push_event (self->vidsrcpad, gst_event_ref (vstab_evt));
1176         gst_pad_push (self->vidsrcpad, vid_buf);
1177         if (G_UNLIKELY (pending_eos))
1178             gst_pad_push_event (self->vidsrcpad, gst_event_new_eos ());
1179     }
1180
1181     if (img_buf)
1182     {
1183         GST_DEBUG_OBJECT (self, "pushing img_buf");
1184         GST_BUFFER_TIMESTAMP (img_buf) = timestamp;
1185         gst_pad_push (self->imgsrcpad, img_buf);
1186         if (G_UNLIKELY (pending_eos))
1187             gst_pad_push_event (self->imgsrcpad, gst_event_new_eos ());
1188     }
1189
1190     if (vstab_evt)
1191     {
1192         gst_event_unref (vstab_evt);
1193     }
1194
1195     if (G_UNLIKELY (pending_eos))
1196     {
1197          /* now send eos event, which was previously deferred, to parent
1198           * class this will trigger basesrc's eos logic.  Unfortunately we
1199           * can't call parent->send_event() directly from here to pass along
1200           * the eos, which would be a more obvious approach, because that
1201           * would deadlock when it tries to acquire live-lock.. but live-
1202           * lock is already held when calling create().
1203           */
1204           return GST_FLOW_UNEXPECTED;
1205     }
1206
1207     GST_DEBUG_OBJECT (self, "end, ret=%d", ret);
1208
1209     return GST_FLOW_OK;
1210
1211 fail:
1212     if (preview_buf) gst_buffer_unref (preview_buf);
1213     if (vid_buf)     gst_buffer_unref (vid_buf);
1214     if (img_buf)     gst_buffer_unref (img_buf);
1215
1216     return ret;
1217 }
1218
1219 static gboolean
1220 send_event (GstElement * element, GstEvent * event)
1221 {
1222     GstOmxCamera *self = GST_OMX_CAMERA (element);
1223
1224     GST_DEBUG_OBJECT (self, "received %s event", GST_EVENT_TYPE_NAME (event));
1225
1226     switch (GST_EVENT_TYPE (event))
1227     {
1228         case GST_EVENT_EOS:
1229             /* note: we don't pass the eos event on to basesrc until
1230              * we have a chance to handle it ourselves..
1231              */
1232             g_atomic_int_set (&self->pending_eos, TRUE);
1233             gst_event_unref (event);
1234             return TRUE;
1235         default:
1236             return GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
1237     }
1238 }
1239
1240 /*
1241  * GObject Methods:
1242  */
1243
1244 static void
1245 set_property (GObject *obj,
1246               guint prop_id,
1247               const GValue *value,
1248               GParamSpec *pspec)
1249 {
1250     GstOmxCamera *self = GST_OMX_CAMERA (obj);
1251     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
1252
1253     switch (prop_id)
1254     {
1255         case ARG_NUM_IMAGE_OUTPUT_BUFFERS:
1256         case ARG_NUM_VIDEO_OUTPUT_BUFFERS:
1257         {
1258             OMX_PARAM_PORTDEFINITIONTYPE param;
1259             OMX_U32 nBufferCountActual = g_value_get_uint (value);
1260             GOmxPort *port = (prop_id == ARG_NUM_IMAGE_OUTPUT_BUFFERS) ?
1261                     self->img_port : self->vid_port;
1262
1263             G_OMX_PORT_GET_DEFINITION (port, &param);
1264
1265             g_return_if_fail (nBufferCountActual >= param.nBufferCountMin);
1266             param.nBufferCountActual = nBufferCountActual;
1267
1268             G_OMX_PORT_SET_DEFINITION (port, &param);
1269
1270             break;
1271         }
1272         case ARG_MODE:
1273         {
1274             /* WORKAROUND: Image capture set only once (in LOADED state) */
1275             static gboolean first_time = TRUE;
1276             self->next_mode = g_value_get_enum (value);
1277             GST_DEBUG_OBJECT (self, "mode: %d", self->next_mode);
1278             /* WORKAROUND : Image capture set only once (in LOADED state) */
1279             if (first_time)
1280                 set_camera_operating_mode (self);
1281             first_time = FALSE;
1282             break;
1283         }
1284         case ARG_SHUTTER:
1285         {
1286             self->shutter = g_value_get_enum (value);
1287             GST_DEBUG_OBJECT (self, "shutter: %d", self->shutter);
1288             break;
1289         }
1290         case ARG_ZOOM:
1291         {
1292             OMX_CONFIG_SCALEFACTORTYPE zoom_scalefactor;
1293             GOmxCore *gomx;
1294             OMX_U32 zoom_factor;
1295             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1296             gint32 zoom_value;
1297             zoom_value = g_value_get_int (value);
1298             gomx = (GOmxCore *) omx_base->gomx;
1299             zoom_factor = (OMX_U32)((CAM_ZOOM_IN_STEP * zoom_value) / 100);
1300             GST_DEBUG_OBJECT (self, "Set Property for zoom factor = %d", zoom_value);
1301
1302             _G_OMX_INIT_PARAM (&zoom_scalefactor);
1303             error_val = OMX_GetConfig (gomx->omx_handle, OMX_IndexConfigCommonDigitalZoom,
1304                                        &zoom_scalefactor);
1305             g_assert (error_val == OMX_ErrorNone);
1306             GST_DEBUG_OBJECT (self, "OMX_GetConfig Successful for zoom");
1307             zoom_scalefactor.xWidth = (zoom_factor);
1308             zoom_scalefactor.xHeight = (zoom_factor);
1309             GST_DEBUG_OBJECT (self, "zoom_scalefactor = %d", zoom_scalefactor.xHeight);
1310             error_val = OMX_SetConfig (gomx->omx_handle, OMX_IndexConfigCommonDigitalZoom,
1311                                        &zoom_scalefactor);
1312             g_assert (error_val == OMX_ErrorNone);
1313             GST_DEBUG_OBJECT (self, "OMX_SetConfig Successful for zoom");
1314             break;
1315         }
1316         case ARG_FOCUS:
1317         {
1318             OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE config;
1319             GOmxCore *gomx;
1320             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1321
1322             gomx = (GOmxCore *) omx_base->gomx;
1323             _G_OMX_INIT_PARAM (&config);
1324             error_val = OMX_GetConfig(gomx->omx_handle,
1325                                        OMX_IndexConfigFocusControl, &config);
1326             g_assert (error_val == OMX_ErrorNone);
1327             config.nPortIndex = omx_base->out_port->port_index;
1328             config.eFocusControl = g_value_get_enum (value);
1329             GST_DEBUG_OBJECT (self, "AF: param=%d port=%d", config.eFocusControl,
1330                                                             config.nPortIndex);
1331
1332             error_val = OMX_SetConfig (gomx->omx_handle,
1333                                        OMX_IndexConfigFocusControl, &config);
1334             g_assert (error_val == OMX_ErrorNone);
1335             break;
1336         }
1337         case ARG_AWB:
1338         {
1339             OMX_CONFIG_WHITEBALCONTROLTYPE config;
1340             GOmxCore *gomx;
1341             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1342
1343             gomx = (GOmxCore *) omx_base->gomx;
1344             _G_OMX_INIT_PARAM (&config);
1345             error_val = OMX_GetConfig (gomx->omx_handle,
1346                                        OMX_IndexConfigCommonWhiteBalance,
1347                                        &config);
1348             g_assert (error_val == OMX_ErrorNone);
1349             config.nPortIndex = omx_base->out_port->port_index;
1350             config.eWhiteBalControl = g_value_get_enum (value);
1351             GST_DEBUG_OBJECT (self, "AWB: param=%d",
1352                                      config.eWhiteBalControl,
1353                                      config.nPortIndex);
1354
1355             error_val = OMX_SetConfig (gomx->omx_handle,
1356                                        OMX_IndexConfigCommonWhiteBalance,
1357                                        &config);
1358             g_assert (error_val == OMX_ErrorNone);
1359             break;
1360         }
1361         case ARG_CONTRAST:
1362         {
1363             OMX_CONFIG_CONTRASTTYPE config;
1364             GOmxCore *gomx;
1365             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1366
1367             gomx = (GOmxCore *) omx_base->gomx;
1368             _G_OMX_INIT_PARAM (&config);
1369             error_val = OMX_GetConfig (gomx->omx_handle,
1370                                        OMX_IndexConfigCommonContrast, &config);
1371             g_assert (error_val == OMX_ErrorNone);
1372             config.nContrast = g_value_get_int (value);
1373             GST_DEBUG_OBJECT (self, "Contrast: param=%d", config.nContrast);
1374
1375             error_val = OMX_SetConfig (gomx->omx_handle,
1376                                        OMX_IndexConfigCommonContrast, &config);
1377             g_assert (error_val == OMX_ErrorNone);
1378             break;
1379         }
1380         case ARG_BRIGHTNESS:
1381         {
1382             OMX_CONFIG_BRIGHTNESSTYPE config;
1383             GOmxCore *gomx;
1384             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1385
1386             gomx = (GOmxCore *) omx_base->gomx;
1387             _G_OMX_INIT_PARAM (&config);
1388             error_val = OMX_GetConfig (gomx->omx_handle,
1389                                        OMX_IndexConfigCommonBrightness, &config);
1390             g_assert (error_val == OMX_ErrorNone);
1391             config.nBrightness = g_value_get_int (value);
1392             GST_DEBUG_OBJECT (self, "Brightness: param=%d", config.nBrightness);
1393
1394             error_val = OMX_SetConfig (gomx->omx_handle,
1395                                        OMX_IndexConfigCommonBrightness, &config);
1396             g_assert (error_val == OMX_ErrorNone);
1397             break;
1398         }
1399         case ARG_EXPOSURE:
1400         {
1401             OMX_CONFIG_EXPOSURECONTROLTYPE config;
1402             GOmxCore *gomx;
1403             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1404
1405             gomx = (GOmxCore *) omx_base->gomx;
1406             _G_OMX_INIT_PARAM (&config);
1407             error_val = OMX_GetConfig (gomx->omx_handle,
1408                                        OMX_IndexConfigCommonExposure,
1409                                        &config);
1410             g_assert (error_val == OMX_ErrorNone);
1411             config.eExposureControl = g_value_get_enum (value);
1412             GST_DEBUG_OBJECT (self, "Exposure control = %d",
1413                               config.eExposureControl);
1414
1415             error_val = OMX_SetConfig (gomx->omx_handle,
1416                                        OMX_IndexConfigCommonExposure,
1417                                        &config);
1418             g_assert (error_val == OMX_ErrorNone);
1419             break;
1420         }
1421         case ARG_ISO:
1422         {
1423             OMX_CONFIG_EXPOSUREVALUETYPE config;
1424             GOmxCore *gomx;
1425             OMX_U32 iso_requested;
1426             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1427
1428             gomx = (GOmxCore *) omx_base->gomx;
1429             _G_OMX_INIT_PARAM (&config);
1430             error_val = OMX_GetConfig (gomx->omx_handle,
1431                                        OMX_IndexConfigCommonExposureValue, &config);
1432             g_assert (error_val == OMX_ErrorNone);
1433             iso_requested = g_value_get_uint (value);
1434             config.bAutoSensitivity = (iso_requested < 100) ? OMX_TRUE : OMX_FALSE;
1435             if (config.bAutoSensitivity == OMX_FALSE)
1436             {
1437                 config.nSensitivity = iso_requested;
1438             }
1439             GST_DEBUG_OBJECT (self, "ISO Speed: Auto=%d Sensitivity=%d",
1440                               config.bAutoSensitivity, config.nSensitivity);
1441
1442             error_val = OMX_SetConfig (gomx->omx_handle,
1443                                        OMX_IndexConfigCommonExposureValue, &config);
1444             g_assert (error_val == OMX_ErrorNone);
1445             break;
1446         }
1447         case ARG_ROTATION:
1448         {
1449             OMX_CONFIG_ROTATIONTYPE  config;
1450
1451             G_OMX_PORT_GET_CONFIG (self->img_port, OMX_IndexConfigCommonRotate, &config);
1452
1453             config.nRotation = g_value_get_uint (value);
1454             GST_DEBUG_OBJECT (self, "Rotation: param=%d", config.nRotation);
1455
1456             G_OMX_PORT_SET_CONFIG (self->img_port, OMX_IndexConfigCommonRotate, &config);
1457             break;
1458         }
1459         case ARG_MIRROR:
1460         {
1461             OMX_CONFIG_MIRRORTYPE  config;
1462             G_OMX_PORT_GET_CONFIG (self->img_port, OMX_IndexConfigCommonMirror, &config);
1463
1464             config.eMirror = g_value_get_enum (value);
1465             GST_DEBUG_OBJECT (self, "Mirror: param=%d", config.eMirror);
1466
1467             G_OMX_PORT_SET_CONFIG (self->img_port, OMX_IndexConfigCommonMirror, &config);
1468             break;
1469         }
1470         case ARG_SATURATION:
1471         {
1472             OMX_CONFIG_SATURATIONTYPE config;
1473             GOmxCore *gomx;
1474             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1475
1476             gomx = (GOmxCore *) omx_base->gomx;
1477             _G_OMX_INIT_PARAM (&config);
1478             error_val = OMX_GetConfig (gomx->omx_handle,
1479                                        OMX_IndexConfigCommonSaturation, &config);
1480             g_assert (error_val == OMX_ErrorNone);
1481             config.nSaturation = g_value_get_int (value);
1482             GST_DEBUG_OBJECT (self, "Saturation: param=%d", config.nSaturation);
1483
1484             error_val = OMX_SetConfig (gomx->omx_handle,
1485                                        OMX_IndexConfigCommonSaturation, &config);
1486             g_assert (error_val == OMX_ErrorNone);
1487             break;
1488         }
1489         case ARG_EXPOSUREVALUE:
1490         {
1491             OMX_CONFIG_EXPOSUREVALUETYPE config;
1492             GOmxCore *gomx;
1493             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1494             gfloat exposure_float_value;
1495
1496             gomx = (GOmxCore *) omx_base->gomx;
1497             _G_OMX_INIT_PARAM (&config);
1498             error_val = OMX_GetConfig (gomx->omx_handle,
1499                                        OMX_IndexConfigCommonExposureValue, &config);
1500             g_assert (error_val == OMX_ErrorNone);
1501             exposure_float_value = g_value_get_float (value);
1502             /* Converting into Q16 ( X << 16  = X*65536 ) */
1503             config.xEVCompensation = (OMX_S32) (exposure_float_value * 65536);
1504             GST_DEBUG_OBJECT (self, "xEVCompensation: value=%f EVCompensation=%d",
1505                               exposure_float_value, config.xEVCompensation);
1506
1507             error_val = OMX_SetConfig (gomx->omx_handle,
1508                                        OMX_IndexConfigCommonExposureValue, &config);
1509             g_assert (error_val == OMX_ErrorNone);
1510             break;
1511         }
1512         case ARG_MANUALFOCUS:
1513         {
1514             OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE config;
1515             GOmxCore *gomx;
1516             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1517
1518             gomx = (GOmxCore *) omx_base->gomx;
1519             _G_OMX_INIT_PARAM (&config);
1520             error_val = OMX_GetConfig (gomx->omx_handle,
1521                                        OMX_IndexConfigFocusControl, &config);
1522             g_assert (error_val == OMX_ErrorNone);
1523             config.nPortIndex = omx_base->out_port->port_index;
1524             config.eFocusControl = OMX_IMAGE_FocusControlOn;
1525             config.nFocusSteps = g_value_get_uint (value);
1526             GST_DEBUG_OBJECT (self, "Manual AF: param=%d port=%d value=%d",
1527                               config.eFocusControl,
1528                               config.nPortIndex,
1529                               config.nFocusSteps);
1530
1531             error_val = OMX_SetConfig (gomx->omx_handle,
1532                                        OMX_IndexConfigFocusControl, &config);
1533             g_assert (error_val == OMX_ErrorNone);
1534             break;
1535         }
1536 #ifdef USE_OMXTICORE
1537         case ARG_THUMBNAIL_WIDTH:
1538         {
1539             OMX_PARAM_THUMBNAILTYPE param;
1540             GOmxCore *gomx;
1541             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1542
1543             gomx = (GOmxCore *) omx_base->gomx;
1544             _G_OMX_INIT_PARAM (&param);
1545             error_val = OMX_GetParameter (gomx->omx_handle,
1546                                           OMX_IndexParamThumbnail,
1547                                           &param);
1548             g_assert (error_val == OMX_ErrorNone);
1549             self->img_thumbnail_width = g_value_get_int (value);
1550             param.nWidth = self->img_thumbnail_width;
1551             GST_DEBUG_OBJECT (self, "Thumbnail width=%d", param.nWidth);
1552             error_val = OMX_SetParameter (gomx->omx_handle,
1553                     OMX_IndexParamThumbnail,&param);
1554             g_assert (error_val == OMX_ErrorNone);
1555             break;
1556         }
1557         case ARG_THUMBNAIL_HEIGHT:
1558         {
1559             OMX_PARAM_THUMBNAILTYPE param;
1560             GOmxCore *gomx;
1561             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1562
1563             gomx = (GOmxCore *) omx_base->gomx;
1564             _G_OMX_INIT_PARAM (&param);
1565             error_val = OMX_GetParameter (gomx->omx_handle,
1566                                           OMX_IndexParamThumbnail,
1567                                           &param);
1568             g_assert (error_val == OMX_ErrorNone);
1569             self->img_thumbnail_height = g_value_get_int (value);
1570             param.nHeight = self->img_thumbnail_height;
1571             GST_DEBUG_OBJECT (self, "Thumbnail height=%d", param.nHeight);
1572             error_val = OMX_SetParameter (gomx->omx_handle,
1573                     OMX_IndexParamThumbnail,&param);
1574             g_assert (error_val == OMX_ErrorNone);
1575             break;
1576         }
1577         case ARG_FLICKER:
1578         {
1579             OMX_CONFIG_FLICKERCANCELTYPE config;
1580             GOmxCore *gomx;
1581             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1582
1583             gomx = (GOmxCore *) omx_base->gomx;
1584             _G_OMX_INIT_PARAM (&config);
1585             error_val = OMX_GetConfig (gomx->omx_handle,
1586                                        OMX_IndexConfigFlickerCancel,
1587                                        &config);
1588             g_assert (error_val == OMX_ErrorNone);
1589             config.eFlickerCancel = g_value_get_enum (value);
1590             GST_DEBUG_OBJECT (self, "Flicker control = %d", config.eFlickerCancel);
1591
1592             error_val = OMX_SetConfig (gomx->omx_handle,
1593                                        OMX_IndexConfigFlickerCancel,
1594                                        &config);
1595             g_assert (error_val == OMX_ErrorNone);
1596             break;
1597         }
1598         case ARG_SCENE:
1599         {
1600             OMX_CONFIG_SCENEMODETYPE config;
1601             GOmxCore *gomx;
1602             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1603
1604             gomx = (GOmxCore *) omx_base->gomx;
1605             _G_OMX_INIT_PARAM (&config);
1606             error_val = OMX_GetParameter (gomx->omx_handle,
1607                                           OMX_IndexParamSceneMode,
1608                                           &config);
1609             g_assert (error_val == OMX_ErrorNone);
1610             config.eSceneMode = g_value_get_enum (value);
1611             GST_DEBUG_OBJECT (self, "Scene mode = %d",
1612                               config.eSceneMode);
1613
1614             error_val = OMX_SetParameter (gomx->omx_handle,
1615                                           OMX_IndexParamSceneMode,
1616                                           &config);
1617             g_assert (error_val == OMX_ErrorNone);
1618             break;
1619         }
1620         case ARG_VNF:
1621         {
1622             OMX_PARAM_VIDEONOISEFILTERTYPE param;
1623
1624             G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamVideoNoiseFilter, &param);
1625
1626             param.eMode = g_value_get_enum (value);
1627             GST_DEBUG_OBJECT (self, "vnf: param=%d", param.eMode);
1628
1629             G_OMX_PORT_SET_PARAM (omx_base->out_port, OMX_IndexParamVideoNoiseFilter, &param);
1630
1631             break;
1632         }
1633         case ARG_YUV_RANGE:
1634         {
1635             OMX_PARAM_VIDEOYUVRANGETYPE param;
1636
1637             G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamVideoCaptureYUVRange, &param);
1638
1639             param.eYUVRange = g_value_get_enum (value);
1640             GST_DEBUG_OBJECT (self, "yuv-range: param=%d", param.eYUVRange);
1641
1642             G_OMX_PORT_SET_PARAM (omx_base->out_port, OMX_IndexParamVideoCaptureYUVRange, &param);
1643
1644             break;
1645         }
1646         case ARG_VSTAB:
1647         {
1648             OMX_CONFIG_BOOLEANTYPE param;
1649             OMX_CONFIG_FRAMESTABTYPE config;
1650
1651             G_OMX_CORE_GET_PARAM (omx_base->gomx, OMX_IndexParamFrameStabilisation, &param);
1652             G_OMX_CORE_GET_CONFIG (omx_base->gomx, OMX_IndexConfigCommonFrameStabilisation, &config);
1653
1654             param.bEnabled = config.bStab = g_value_get_boolean (value);
1655             GST_DEBUG_OBJECT (self, "vstab: param=%d, config=%d", param.bEnabled, config.bStab);
1656
1657             G_OMX_CORE_SET_PARAM (omx_base->gomx, OMX_IndexParamFrameStabilisation, &param);
1658             G_OMX_CORE_SET_CONFIG (omx_base->gomx, OMX_IndexConfigCommonFrameStabilisation, &config);
1659
1660             break;
1661         }
1662         case ARG_DEVICE:
1663         {
1664             OMX_CONFIG_SENSORSELECTTYPE config;
1665             GOmxCore *gomx;
1666             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1667
1668             gomx = (GOmxCore *) omx_base->gomx;
1669             _G_OMX_INIT_PARAM (&config);
1670             error_val = OMX_GetConfig (gomx->omx_handle,
1671                                        OMX_TI_IndexConfigSensorSelect, &config);
1672             g_assert (error_val == OMX_ErrorNone);
1673             config.nPortIndex = omx_base->out_port->port_index;
1674             config.eSensor = g_value_get_enum (value);
1675             GST_DEBUG_OBJECT (self, "Device src=%d, port=%d", config.eSensor,
1676                               config.nPortIndex);
1677             error_val = OMX_SetConfig (gomx->omx_handle,
1678                                        OMX_TI_IndexConfigSensorSelect, &config);
1679             g_assert (error_val == OMX_ErrorNone);
1680             break;
1681         }
1682         case ARG_LDC:
1683         {
1684             OMX_CONFIG_BOOLEANTYPE param;
1685
1686             G_OMX_CORE_GET_PARAM (omx_base->gomx,
1687                                   OMX_IndexParamLensDistortionCorrection, &param);
1688
1689             param.bEnabled = g_value_get_boolean (value);
1690             GST_DEBUG_OBJECT (self, "Lens Distortion Correction: param=%d",
1691                               param.bEnabled);
1692             G_OMX_CORE_SET_PARAM (omx_base->gomx,
1693                                   OMX_IndexParamLensDistortionCorrection, &param);
1694             break;
1695         }
1696         case ARG_NSF:
1697         {
1698             OMX_PARAM_ISONOISEFILTERTYPE param;
1699             GOmxCore *gomx;
1700             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1701
1702             gomx = (GOmxCore *) omx_base->gomx;
1703             _G_OMX_INIT_PARAM (&param);
1704             error_val = OMX_GetParameter (gomx->omx_handle,
1705                                           OMX_IndexParamHighISONoiseFiler,
1706                                           &param);
1707             g_assert (error_val == OMX_ErrorNone);
1708             param.eMode = g_value_get_enum (value);
1709             GST_DEBUG_OBJECT (self, "ISO Noise Filter (NSF)=%d", param.eMode);
1710             error_val = OMX_SetParameter (gomx->omx_handle,
1711                                           OMX_IndexParamHighISONoiseFiler,
1712                                           &param);
1713             g_assert (error_val == OMX_ErrorNone);
1714             break;
1715         }
1716         case ARG_MTIS:
1717         {
1718             OMX_CONFIG_BOOLEANTYPE config;
1719             GOmxCore *gomx;
1720             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1721
1722             gomx = (GOmxCore *) omx_base->gomx;
1723             _G_OMX_INIT_PARAM (&config);
1724             error_val = OMX_GetConfig (gomx->omx_handle,
1725                                        OMX_IndexConfigMotionTriggeredImageStabilisation,
1726                                        &config);
1727             g_assert (error_val == OMX_ErrorNone);
1728
1729             config.bEnabled = g_value_get_boolean (value);
1730             GST_DEBUG_OBJECT (self, "Motion Triggered Image Stabilisation = %d",
1731                               config.bEnabled);
1732             error_val = OMX_SetConfig (gomx->omx_handle,
1733                                        OMX_IndexConfigMotionTriggeredImageStabilisation,
1734                                        &config);
1735             g_assert (error_val == OMX_ErrorNone);
1736             break;
1737         }
1738 #endif
1739         default:
1740         {
1741             G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
1742             break;
1743         }
1744     }
1745 }
1746
1747 static void
1748 get_property (GObject *obj,
1749               guint prop_id,
1750               GValue *value,
1751               GParamSpec *pspec)
1752 {
1753     GstOmxCamera *self = GST_OMX_CAMERA (obj);
1754     GstOmxBaseSrc *omx_base = GST_OMX_BASE_SRC (self);
1755
1756     switch (prop_id)
1757     {
1758         case ARG_NUM_IMAGE_OUTPUT_BUFFERS:
1759         case ARG_NUM_VIDEO_OUTPUT_BUFFERS:
1760         {
1761             OMX_PARAM_PORTDEFINITIONTYPE param;
1762             GOmxPort *port = (prop_id == ARG_NUM_IMAGE_OUTPUT_BUFFERS) ?
1763                     self->img_port : self->vid_port;
1764
1765             G_OMX_PORT_GET_DEFINITION (port, &param);
1766
1767             g_value_set_uint (value, param.nBufferCountActual);
1768
1769             break;
1770         }
1771         case ARG_MODE:
1772         {
1773             GST_DEBUG_OBJECT (self, "mode: %d", self->mode);
1774             g_value_set_enum (value, self->mode);
1775             break;
1776         }
1777         case ARG_SHUTTER:
1778         {
1779             GST_DEBUG_OBJECT (self, "shutter: %d", self->shutter);
1780             g_value_set_enum (value, self->shutter);
1781             break;
1782         }
1783         case ARG_ZOOM:
1784         {
1785             OMX_CONFIG_SCALEFACTORTYPE zoom_scalefactor;
1786             GOmxCore *gomx;
1787             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1788             gomx = (GOmxCore *) omx_base->gomx;
1789             GST_DEBUG_OBJECT (self, "Get Property for zoom");
1790
1791             _G_OMX_INIT_PARAM (&zoom_scalefactor);
1792             error_val = OMX_GetConfig (gomx->omx_handle, OMX_IndexConfigCommonDigitalZoom,
1793                                        &zoom_scalefactor);
1794             g_assert (error_val == OMX_ErrorNone);
1795             break;
1796         }
1797         case ARG_FOCUS:
1798         {
1799             OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE config;
1800             GOmxCore *gomx;
1801             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1802             gomx = (GOmxCore *) omx_base->gomx;
1803
1804             _G_OMX_INIT_PARAM (&config);
1805             error_val = OMX_GetConfig (gomx->omx_handle,
1806                                         OMX_IndexConfigFocusControl, &config);
1807             g_assert (error_val == OMX_ErrorNone);
1808             config.nPortIndex = omx_base->out_port->port_index;
1809             GST_DEBUG_OBJECT (self, "AF: param=%d port=%d", config.eFocusControl,
1810                                                             config.nPortIndex);
1811             g_value_set_enum (value, config.eFocusControl);
1812
1813             break;
1814         }
1815         case ARG_AWB:
1816         {
1817             OMX_CONFIG_WHITEBALCONTROLTYPE config;
1818             GOmxCore *gomx;
1819             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1820             gomx = (GOmxCore *) omx_base->gomx;
1821
1822             _G_OMX_INIT_PARAM (&config);
1823             error_val = OMX_GetConfig (gomx->omx_handle,
1824                                        OMX_IndexConfigCommonWhiteBalance,
1825                                        &config);
1826             g_assert (error_val == OMX_ErrorNone);
1827             config.nPortIndex = omx_base->out_port->port_index;
1828             GST_DEBUG_OBJECT (self, "AWB: param=%d", config.eWhiteBalControl);
1829             g_value_set_enum (value, config.eWhiteBalControl);
1830
1831             break;
1832         }
1833         case ARG_CONTRAST:
1834         {
1835             OMX_CONFIG_CONTRASTTYPE config;
1836             GOmxCore *gomx;
1837             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1838
1839             gomx = (GOmxCore *) omx_base->gomx;
1840             _G_OMX_INIT_PARAM (&config);
1841             error_val = OMX_GetConfig (gomx->omx_handle,
1842                                        OMX_IndexConfigCommonContrast, &config);
1843             g_assert (error_val == OMX_ErrorNone);
1844             GST_DEBUG_OBJECT (self, "Contrast=%d", config.nContrast);
1845             break;
1846         }
1847         case ARG_BRIGHTNESS:
1848         {
1849             OMX_CONFIG_BRIGHTNESSTYPE config;
1850             GOmxCore *gomx;
1851             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1852
1853             gomx = (GOmxCore *) omx_base->gomx;
1854             _G_OMX_INIT_PARAM (&config);
1855             error_val = OMX_GetConfig (gomx->omx_handle,
1856                                        OMX_IndexConfigCommonBrightness, &config);
1857             g_assert (error_val == OMX_ErrorNone);
1858             GST_DEBUG_OBJECT (self, "Brightness=%d", config.nBrightness);
1859             break;
1860         }
1861         case ARG_EXPOSURE:
1862         {
1863             OMX_CONFIG_EXPOSURECONTROLTYPE config;
1864             GOmxCore *gomx;
1865             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1866             gomx = (GOmxCore *) omx_base->gomx;
1867
1868             _G_OMX_INIT_PARAM (&config);
1869             error_val = OMX_GetConfig (gomx->omx_handle,
1870                                        OMX_IndexConfigCommonExposure,
1871                                        &config);
1872             g_assert (error_val == OMX_ErrorNone);
1873             GST_DEBUG_OBJECT (self, "Exposure control = %d",
1874                               config.eExposureControl);
1875             g_value_set_enum (value, config.eExposureControl);
1876
1877             break;
1878         }
1879         case ARG_ISO:
1880         {
1881             OMX_CONFIG_EXPOSUREVALUETYPE config;
1882             GOmxCore *gomx;
1883             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1884             gomx = (GOmxCore *) omx_base->gomx;
1885
1886             _G_OMX_INIT_PARAM (&config);
1887             error_val = OMX_GetConfig (gomx->omx_handle,
1888                                        OMX_IndexConfigCommonExposureValue, &config);
1889             g_assert (error_val == OMX_ErrorNone);
1890             GST_DEBUG_OBJECT (self, "ISO Speed: param=%d", config.nSensitivity);
1891             g_value_set_uint (value, config.nSensitivity);
1892
1893             break;
1894         }
1895         case ARG_ROTATION:
1896         {
1897             OMX_CONFIG_ROTATIONTYPE  config;
1898
1899             G_OMX_PORT_GET_CONFIG (self->img_port, OMX_IndexConfigCommonRotate, &config);
1900
1901             GST_DEBUG_OBJECT (self, "Rotation: param=%d", config.nRotation);
1902             g_value_set_uint (value, config.nRotation);
1903             break;
1904         }
1905         case ARG_MIRROR:
1906         {
1907             OMX_CONFIG_MIRRORTYPE  config;
1908             G_OMX_PORT_GET_CONFIG (self->img_port, OMX_IndexConfigCommonMirror, &config);
1909
1910             GST_DEBUG_OBJECT (self, "Mirror: param=%d", config.eMirror);
1911             g_value_set_enum (value, config.eMirror);
1912             break;
1913         }
1914         case ARG_SATURATION:
1915         {
1916             OMX_CONFIG_SATURATIONTYPE config;
1917             GOmxCore *gomx;
1918             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1919
1920             gomx = (GOmxCore *) omx_base->gomx;
1921             _G_OMX_INIT_PARAM (&config);
1922             error_val = OMX_GetConfig (gomx->omx_handle,
1923                                        OMX_IndexConfigCommonSaturation, &config);
1924             g_assert (error_val == OMX_ErrorNone);
1925             GST_DEBUG_OBJECT (self, "Saturation=%d", config.nSaturation);
1926             break;
1927         }
1928         case ARG_EXPOSUREVALUE:
1929         {
1930             OMX_CONFIG_EXPOSUREVALUETYPE config;
1931             GOmxCore *gomx;
1932             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1933
1934             gomx = (GOmxCore *) omx_base->gomx;
1935             _G_OMX_INIT_PARAM (&config);
1936             error_val = OMX_GetConfig (gomx->omx_handle,
1937                                        OMX_IndexConfigCommonExposureValue, &config);
1938             g_assert (error_val == OMX_ErrorNone);
1939             GST_DEBUG_OBJECT (self, "xEVCompensation: EVCompensation=%d",
1940                               config.xEVCompensation);
1941             break;
1942         }
1943         case ARG_MANUALFOCUS:
1944         {
1945             OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE config;
1946             GOmxCore *gomx;
1947             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1948
1949             gomx = (GOmxCore *) omx_base->gomx;
1950             _G_OMX_INIT_PARAM (&config);
1951             error_val = OMX_GetConfig (gomx->omx_handle,
1952                                        OMX_IndexConfigFocusControl, &config);
1953             g_assert (error_val == OMX_ErrorNone);
1954             GST_DEBUG_OBJECT (self, "Manual AF: param=%d port=%d value=%d",
1955                               config.eFocusControl,
1956                               config.nPortIndex,
1957                               config.nFocusSteps);
1958             g_value_set_uint (value, config.nFocusSteps);
1959             break;
1960         }
1961 #ifdef USE_OMXTICORE
1962         case ARG_THUMBNAIL_WIDTH:
1963         {
1964             OMX_PARAM_THUMBNAILTYPE param;
1965             GOmxCore *gomx;
1966             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1967
1968             gomx = (GOmxCore *) omx_base->gomx;
1969             _G_OMX_INIT_PARAM (&param);
1970             error_val = OMX_GetParameter(gomx->omx_handle,
1971                                        OMX_IndexParamThumbnail,
1972                                        &param);
1973             g_assert (error_val == OMX_ErrorNone);
1974             self->img_thumbnail_width = param.nWidth;
1975             GST_DEBUG_OBJECT (self, "Thumbnail width=%d",
1976                                     self->img_thumbnail_width);
1977             break;
1978         }
1979         case ARG_THUMBNAIL_HEIGHT:
1980         {
1981             OMX_PARAM_THUMBNAILTYPE param;
1982             GOmxCore *gomx;
1983             OMX_ERRORTYPE error_val = OMX_ErrorNone;
1984
1985             gomx = (GOmxCore *) omx_base->gomx;
1986             _G_OMX_INIT_PARAM (&param);
1987             error_val = OMX_GetParameter(gomx->omx_handle,
1988                                        OMX_IndexParamThumbnail,
1989                                        &param);
1990             g_assert (error_val == OMX_ErrorNone);
1991             self->img_thumbnail_height = param.nHeight;
1992             GST_DEBUG_OBJECT (self, "Thumbnail height=%d",
1993                                     self->img_thumbnail_height);
1994             break;
1995         }
1996         case ARG_FLICKER:
1997         {
1998             OMX_CONFIG_FLICKERCANCELTYPE config;
1999             GOmxCore *gomx;
2000             OMX_ERRORTYPE error_val = OMX_ErrorNone;
2001             gomx = (GOmxCore *) omx_base->gomx;
2002
2003             _G_OMX_INIT_PARAM (&config);
2004             error_val = OMX_GetConfig (gomx->omx_handle,
2005                                        OMX_IndexConfigFlickerCancel,
2006                                        &config);
2007             g_assert (error_val == OMX_ErrorNone);
2008             GST_DEBUG_OBJECT (self, "Flicker control = %d", config.eFlickerCancel);
2009             g_value_set_enum (value, config.eFlickerCancel);
2010
2011             break;
2012         }
2013         case ARG_SCENE:
2014         {
2015             OMX_CONFIG_SCENEMODETYPE config;
2016             GOmxCore *gomx;
2017             OMX_ERRORTYPE error_val = OMX_ErrorNone;
2018
2019             gomx = (GOmxCore *) omx_base->gomx;
2020             _G_OMX_INIT_PARAM (&config);
2021             error_val = OMX_GetParameter (gomx->omx_handle,
2022                                           OMX_IndexParamSceneMode, &config);
2023             g_assert (error_val == OMX_ErrorNone);
2024             GST_DEBUG_OBJECT (self, "Scene mode = %d", config.eSceneMode);
2025             g_value_set_enum (value, config.eSceneMode);
2026
2027             break;
2028         }
2029         case ARG_VNF:
2030         {
2031             OMX_PARAM_VIDEONOISEFILTERTYPE param;
2032
2033             G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamVideoNoiseFilter, &param);
2034
2035             GST_DEBUG_OBJECT (self, "vnf: param=%d", param.eMode);
2036             g_value_set_enum (value, param.eMode);
2037
2038             break;
2039         }
2040         case ARG_YUV_RANGE:
2041         {
2042             OMX_PARAM_VIDEOYUVRANGETYPE param;
2043
2044             G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamVideoCaptureYUVRange, &param);
2045
2046             GST_DEBUG_OBJECT (self, "yuv-range: param=%d", param.eYUVRange);
2047             g_value_set_enum (value, param.eYUVRange);
2048
2049             break;
2050         }
2051         case ARG_VSTAB:
2052         {
2053             OMX_CONFIG_BOOLEANTYPE param;
2054             OMX_CONFIG_FRAMESTABTYPE config;
2055
2056             G_OMX_CORE_GET_PARAM (omx_base->gomx, OMX_IndexParamFrameStabilisation, &param);
2057             G_OMX_CORE_GET_CONFIG (omx_base->gomx, OMX_IndexConfigCommonFrameStabilisation, &config);
2058
2059             GST_DEBUG_OBJECT (self, "vstab: param=%d, config=%d", param.bEnabled, config.bStab);
2060             g_value_set_boolean (value, param.bEnabled && config.bStab);
2061
2062             break;
2063         }
2064         case ARG_DEVICE:
2065         {
2066             OMX_CONFIG_SENSORSELECTTYPE config;
2067             GOmxCore *gomx;
2068             OMX_ERRORTYPE error_val = OMX_ErrorNone;
2069
2070             gomx = (GOmxCore *) omx_base->gomx;
2071             _G_OMX_INIT_PARAM (&config);
2072             error_val = OMX_GetConfig (gomx->omx_handle,
2073                                        OMX_TI_IndexConfigSensorSelect, &config);
2074             g_assert (error_val == OMX_ErrorNone);
2075             GST_DEBUG_OBJECT (self, "Device src=%d", config.eSensor);
2076             g_value_set_enum (value, config.eSensor);
2077
2078             break;
2079         }
2080         case ARG_LDC:
2081         {
2082             OMX_CONFIG_BOOLEANTYPE param;
2083
2084             G_OMX_CORE_GET_PARAM (omx_base->gomx,
2085                                   OMX_IndexParamLensDistortionCorrection, &param);
2086             GST_DEBUG_OBJECT (self, "Lens Distortion Correction: param=%d",
2087                               param.bEnabled);
2088             g_value_set_boolean (value, param.bEnabled);
2089             break;
2090         }
2091         case ARG_NSF:
2092         {
2093             OMX_PARAM_ISONOISEFILTERTYPE param;
2094             GOmxCore *gomx;
2095             OMX_ERRORTYPE error_val = OMX_ErrorNone;
2096
2097             gomx = (GOmxCore *) omx_base->gomx;
2098             _G_OMX_INIT_PARAM (&param);
2099             error_val = OMX_GetParameter (gomx->omx_handle,
2100                                           OMX_IndexParamHighISONoiseFiler,
2101                                           &param);
2102             g_assert (error_val == OMX_ErrorNone);
2103             GST_DEBUG_OBJECT (self, "ISO Noise Filter (NSF)=%d", param.eMode);
2104             g_value_set_enum (value, param.eMode);
2105
2106             break;
2107         }
2108         case ARG_MTIS:
2109         {
2110             OMX_CONFIG_BOOLEANTYPE config;
2111             GOmxCore *gomx;
2112             OMX_ERRORTYPE error_val = OMX_ErrorNone;
2113
2114             gomx = (GOmxCore *) omx_base->gomx;
2115             _G_OMX_INIT_PARAM (&config);
2116             error_val = OMX_GetConfig (gomx->omx_handle,
2117                                        OMX_IndexConfigMotionTriggeredImageStabilisation,
2118                                        &config);
2119             g_assert (error_val == OMX_ErrorNone);
2120             GST_DEBUG_OBJECT (self, "Motion Triggered Image Stabilisation = %d",
2121                               config.bEnabled);
2122             g_value_set_boolean (value, config.bEnabled);
2123             break;
2124         }
2125 #endif
2126         default:
2127         {
2128             G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
2129             break;
2130         }
2131     }
2132 }
2133
2134 /*
2135  * Initialization:
2136  */
2137
2138 static void
2139 type_base_init (gpointer g_class)
2140 {
2141     GstElementClass *element_class;
2142
2143     element_class = GST_ELEMENT_CLASS (g_class);
2144
2145     gst_element_class_set_details (element_class, &element_details);
2146
2147     gst_element_class_add_pad_template (element_class,
2148         gst_static_pad_template_get (&src_template));
2149
2150     gst_element_class_add_pad_template (element_class,
2151         gst_static_pad_template_get (&vidsrc_template));
2152
2153     gst_element_class_add_pad_template (element_class,
2154         gst_static_pad_template_get (&imgsrc_template));
2155
2156 #if 0
2157     gst_element_class_add_pad_template (element_class,
2158         gst_static_pad_template_get (&sink_template));
2159 #endif
2160 }
2161
2162 static void
2163 type_class_init (gpointer g_class,
2164                  gpointer class_data)
2165 {
2166     GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
2167     GstElementClass *gst_element_class = GST_ELEMENT_CLASS (g_class);
2168     GstBaseSrcClass *gst_base_src_class = GST_BASE_SRC_CLASS (g_class);
2169     GstOmxBaseSrcClass *omx_base_class = GST_OMX_BASE_SRC_CLASS (g_class);
2170
2171     omx_base_class->out_port_index = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
2172
2173     /* GstBaseSrc methods: */
2174     gst_base_src_class->create = GST_DEBUG_FUNCPTR (create);
2175
2176     /* GstElement methods: */
2177     gst_element_class->send_event = GST_DEBUG_FUNCPTR (send_event);
2178
2179     /* GObject methods: */
2180     gobject_class->set_property = GST_DEBUG_FUNCPTR (set_property);
2181     gobject_class->get_property = GST_DEBUG_FUNCPTR (get_property);
2182
2183     /* install properties: */
2184     g_object_class_install_property (gobject_class, ARG_NUM_IMAGE_OUTPUT_BUFFERS,
2185             g_param_spec_uint ("image-output-buffers", "Image port output buffers",
2186                     "The number of OMX image port output buffers",
2187                     1, 10, 4, G_PARAM_READWRITE));
2188     g_object_class_install_property (gobject_class, ARG_NUM_VIDEO_OUTPUT_BUFFERS,
2189             g_param_spec_uint ("video-output-buffers", "Video port output buffers",
2190                     "The number of OMX video port output buffers",
2191                     1, 10, 4, G_PARAM_READWRITE));
2192
2193     g_object_class_install_property (gobject_class, ARG_MODE,
2194             g_param_spec_enum ("mode", "Camera Mode",
2195                     "image capture, video capture, or both",
2196                     GST_TYPE_OMX_CAMERA_MODE,
2197                     MODE_PREVIEW,
2198                     G_PARAM_READWRITE));
2199
2200     g_object_class_install_property (gobject_class, ARG_SHUTTER,
2201             g_param_spec_enum ("shutter", "Shutter State",
2202                     "shutter button state",
2203                     GST_TYPE_OMX_CAMERA_SHUTTER,
2204                     SHUTTER_OFF,
2205                     G_PARAM_READWRITE));
2206
2207     g_object_class_install_property (gobject_class, ARG_ZOOM,
2208             g_param_spec_int ("zoom", "Digital Zoom",
2209                     "digital zoom factor/level",
2210                     MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL, DEFAULT_ZOOM_LEVEL,
2211                     G_PARAM_READWRITE));
2212
2213     g_object_class_install_property (gobject_class, ARG_FOCUS,
2214             g_param_spec_enum ("focus", "Auto Focus",
2215                     "auto focus state",
2216                     GST_TYPE_OMX_CAMERA_FOCUS,
2217                     DEFAULT_FOCUS,
2218                     G_PARAM_READWRITE));
2219
2220     g_object_class_install_property (gobject_class, ARG_AWB,
2221             g_param_spec_enum ("awb", "Auto White Balance",
2222                     "auto white balance state",
2223                     GST_TYPE_OMX_CAMERA_AWB,
2224                     DEFAULT_AWB,
2225                     G_PARAM_READWRITE));
2226     g_object_class_install_property (gobject_class, ARG_CONTRAST,
2227             g_param_spec_int ("contrast", "Contrast",
2228                     "contrast level", MIN_CONTRAST_LEVEL,
2229                     MAX_CONTRAST_LEVEL, DEFAULT_CONTRAST_LEVEL,
2230                     G_PARAM_READWRITE));
2231     g_object_class_install_property (gobject_class, ARG_BRIGHTNESS,
2232             g_param_spec_int ("brightness", "Brightness",
2233                     "brightness level", MIN_BRIGHTNESS_LEVEL,
2234                     MAX_BRIGHTNESS_LEVEL, DEFAULT_BRIGHTNESS_LEVEL,
2235                     G_PARAM_READWRITE));
2236     g_object_class_install_property (gobject_class, ARG_EXPOSURE,
2237             g_param_spec_enum ("exposure", "Exposure Control",
2238                     "exposure control mode",
2239                     GST_TYPE_OMX_CAMERA_EXPOSURE,
2240                     DEFAULT_EXPOSURE,
2241                     G_PARAM_READWRITE));
2242     g_object_class_install_property (gobject_class, ARG_ISO,
2243             g_param_spec_uint ("iso-speed", "ISO Speed",
2244                     "ISO speed level", MIN_ISO_LEVEL,
2245                     MAX_ISO_LEVEL, DEFAULT_ISO_LEVEL,
2246                     G_PARAM_READWRITE));
2247     g_object_class_install_property (gobject_class, ARG_ROTATION,
2248             g_param_spec_uint ("rotation", "Rotation",
2249                     "Image rotation",
2250                     0, 270, DEFAULT_ROTATION , G_PARAM_READWRITE));
2251     g_object_class_install_property (gobject_class, ARG_MIRROR,
2252             g_param_spec_enum ("mirror", "Mirror",
2253                     "Mirror image",
2254                     GST_TYPE_OMX_CAMERA_MIRROR,
2255                     DEFAULT_MIRROR,
2256                     G_PARAM_READWRITE));
2257     g_object_class_install_property (gobject_class, ARG_SATURATION,
2258             g_param_spec_int ("saturation", "Saturation",
2259                     "Saturation level", MIN_SATURATION_VALUE,
2260                     MAX_SATURATION_VALUE, DEFAULT_SATURATION_VALUE,
2261                     G_PARAM_READWRITE));
2262     g_object_class_install_property (gobject_class, ARG_EXPOSUREVALUE,
2263             g_param_spec_float ("exposure-value", "Exposure value",
2264                     "EVCompensation level", MIN_EXPOSURE_VALUE,
2265                     MAX_EXPOSURE_VALUE, DEFAULT_EXPOSURE_VALUE,
2266                     G_PARAM_READWRITE));
2267     g_object_class_install_property (gobject_class, ARG_MANUALFOCUS,
2268             g_param_spec_uint ("manual-focus", "Manual Focus",
2269                     "Manual focus level, 0:Infinity  100:Macro",
2270                     MIN_MANUALFOCUS, MAX_MANUALFOCUS, DEFAULT_MANUALFOCUS,
2271                     G_PARAM_READWRITE));
2272 #ifdef USE_OMXTICORE
2273     g_object_class_install_property (gobject_class, ARG_THUMBNAIL_WIDTH,
2274             g_param_spec_int ("thumb-width", "Thumbnail width",
2275                     "Thumbnail width in pixels", MIN_THUMBNAIL_LEVEL,
2276                     MAX_THUMBNAIL_LEVEL, DEFAULT_THUMBNAIL_WIDTH,
2277                     G_PARAM_READWRITE));
2278     g_object_class_install_property (gobject_class, ARG_THUMBNAIL_HEIGHT,
2279             g_param_spec_int ("thumb-height", "Thumbnail height",
2280                     "Thumbnail height in pixels", MIN_THUMBNAIL_LEVEL,
2281                     MAX_THUMBNAIL_LEVEL, DEFAULT_THUMBNAIL_HEIGHT,
2282                     G_PARAM_READWRITE));
2283     g_object_class_install_property (gobject_class, ARG_FLICKER,
2284             g_param_spec_enum ("flicker", "Flicker Control",
2285                     "flicker control state",
2286                     GST_TYPE_OMX_CAMERA_FLICKER,
2287                     DEFAULT_FLICKER,
2288                     G_PARAM_READWRITE));
2289     g_object_class_install_property (gobject_class, ARG_SCENE,
2290             g_param_spec_enum ("scene", "Scene Mode",
2291                     "Scene mode",
2292                     GST_TYPE_OMX_CAMERA_SCENE,
2293                     DEFAULT_SCENE,
2294                     G_PARAM_READWRITE));
2295     g_object_class_install_property (gobject_class, ARG_VNF,
2296             g_param_spec_enum ("vnf", "Video Noise Filter",
2297                     "is video noise filter algorithm enabled?",
2298                     GST_TYPE_OMX_CAMERA_VNF,
2299                     DEFAULT_VNF,
2300                     G_PARAM_READWRITE));
2301     g_object_class_install_property (gobject_class, ARG_YUV_RANGE,
2302             g_param_spec_enum ("yuv-range", "YUV Range",
2303                     "YUV Range",
2304                     GST_TYPE_OMX_CAMERA_YUV_RANGE,
2305                     DEFAULT_YUV_RANGE,
2306                     G_PARAM_READWRITE));
2307     g_object_class_install_property (gobject_class, ARG_VSTAB,
2308             g_param_spec_boolean ("vstab", "Video Frame Stabilization",
2309                     "is video stabilization algorithm enabled?",
2310                     TRUE,
2311                     G_PARAM_READWRITE));
2312     g_object_class_install_property (gobject_class, ARG_DEVICE,
2313             g_param_spec_enum ("device", "Camera sensor",
2314                     "Image and video stream source",
2315                     GST_TYPE_OMX_CAMERA_DEVICE,
2316                     DEFAULT_DEVICE,
2317                     G_PARAM_READWRITE));
2318     g_object_class_install_property (gobject_class, ARG_LDC,
2319             g_param_spec_boolean ("ldc", "Lens Distortion Correction",
2320                     "Lens Distortion Correction state",
2321                     FALSE,
2322                     G_PARAM_READWRITE));
2323     g_object_class_install_property (gobject_class, ARG_NSF,
2324             g_param_spec_enum ("nsf", "ISO noise suppression filter",
2325                     "low light environment noise filter",
2326                     GST_TYPE_OMX_CAMERA_NSF,
2327                     DEFAULT_NSF,
2328                     G_PARAM_READWRITE));
2329     g_object_class_install_property (gobject_class, ARG_MTIS,
2330             g_param_spec_boolean ("mtis", "Motion triggered image stabilisation mode",
2331                     "Motion triggered image stabilisation mode",
2332                     FALSE,
2333                     G_PARAM_READWRITE));
2334 #endif
2335 }
2336
2337
2338 void check_settings (GOmxPort *port, GstPad *pad);
2339
2340
2341 /**
2342  * overrides the default buffer allocation for img_port to allow
2343  * pad_alloc'ing from the imgsrcpad
2344  */
2345 static GstBuffer *
2346 img_buffer_alloc (GOmxPort *port, gint len)
2347 {
2348     GstOmxCamera *self = port->core->object;
2349     GstBuffer *buf;
2350     GstFlowReturn ret;
2351
2352     GST_DEBUG_OBJECT (self, "img_buffer_alloc begin");
2353     check_settings (self->img_port, self->imgsrcpad);
2354
2355     ret = gst_pad_alloc_buffer_and_set_caps (
2356             self->imgsrcpad, GST_BUFFER_OFFSET_NONE,
2357             len, GST_PAD_CAPS (self->imgsrcpad), &buf);
2358
2359     if (ret == GST_FLOW_OK) return buf;
2360
2361     return NULL;
2362 }
2363
2364
2365 static void
2366 type_instance_init (GTypeInstance *instance,
2367                     gpointer g_class)
2368 {
2369     GstOmxCamera   *self     = GST_OMX_CAMERA (instance);
2370     GstOmxBaseSrc  *omx_base = GST_OMX_BASE_SRC (self);
2371     GstBaseSrc     *basesrc  = GST_BASE_SRC (self);
2372     GstPadTemplate *pad_template;
2373
2374     GST_DEBUG_OBJECT (omx_base, "begin");
2375
2376     self->mode = -1;
2377     self->next_mode = MODE_PREVIEW;
2378
2379     omx_base->setup_ports = setup_ports;
2380
2381     omx_base->gomx->settings_changed_cb = settings_changed_cb;
2382
2383     omx_base->gomx->use_timestamps = TRUE;
2384
2385     self->vid_port = g_omx_core_get_port (omx_base->gomx, "vid",
2386             OMX_CAMERA_PORT_VIDEO_OUT_VIDEO);
2387     self->img_port = g_omx_core_get_port (omx_base->gomx, "img",
2388             OMX_CAMERA_PORT_IMAGE_OUT_IMAGE);
2389     self->in_port = g_omx_core_get_port (omx_base->gomx, "in",
2390             OMX_CAMERA_PORT_OTHER_IN);
2391     self->in_vid_port = g_omx_core_get_port (omx_base->gomx, "in_vid",
2392             OMX_CAMERA_PORT_VIDEO_IN_VIDEO);
2393     self->msr_port = g_omx_core_get_port (omx_base->gomx, "msr",
2394             OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT);
2395
2396     self->img_port->buffer_alloc = img_buffer_alloc;
2397 #if 0
2398     self->in_port = g_omx_core_get_port (omx_base->gomx, "in"
2399             OMX_CAMERA_PORT_VIDEO_IN_VIDEO);
2400 #endif
2401
2402     gst_base_src_set_live (basesrc, TRUE);
2403
2404     /* setup src pad (already created by basesrc): */
2405
2406     gst_pad_set_setcaps_function (basesrc->srcpad,
2407             GST_DEBUG_FUNCPTR (src_setcaps));
2408
2409     /* create/setup vidsrc pad: */
2410     pad_template = gst_element_class_get_pad_template (
2411             GST_ELEMENT_CLASS (g_class), "vidsrc");
2412     g_return_if_fail (pad_template != NULL);
2413
2414     GST_DEBUG_OBJECT (basesrc, "creating vidsrc pad");
2415     self->vidsrcpad = gst_pad_new_from_template (pad_template, "vidsrc");
2416
2417     /* src and vidsrc pads have same caps: */
2418     gst_pad_set_setcaps_function (self->vidsrcpad,
2419             GST_DEBUG_FUNCPTR (src_setcaps));
2420
2421     /* create/setup imgsrc pad: */
2422     pad_template = gst_element_class_get_pad_template (
2423             GST_ELEMENT_CLASS (g_class), "imgsrc");
2424     g_return_if_fail (pad_template != NULL);
2425
2426     GST_DEBUG_OBJECT (basesrc, "creating imgsrc pad");
2427     self->imgsrcpad = gst_pad_new_from_template (pad_template, "imgsrc");
2428     gst_pad_set_setcaps_function (self->imgsrcpad,
2429             GST_DEBUG_FUNCPTR (imgsrc_setcaps));
2430     gst_pad_set_query_function (basesrc->srcpad,
2431             GST_DEBUG_FUNCPTR (src_query));
2432     gst_pad_set_query_function (self->vidsrcpad,
2433             GST_DEBUG_FUNCPTR (src_query));
2434 #if 0
2435     /* disable all ports to begin with: */
2436     g_omx_port_disable (self->in_port);
2437     g_omx_port_disable (omx_base->out_port);
2438 #endif
2439     g_omx_port_disable (self->vid_port);
2440     g_omx_port_disable (self->img_port);
2441     g_omx_port_disable (self->in_port);
2442     g_omx_port_disable (self->in_vid_port);
2443     g_omx_port_disable (self->msr_port);
2444
2445     GST_DEBUG_OBJECT (omx_base, "end");
2446 }