Initial release
[adaptation/ap_samsung/gst-plugins-s5pc2xx.git] / camerasrc / src / gstcamerasrc.c
1 /*
2  * camerasrc
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jeongmo Yang <jm80.yang@samsung.com>
7  *
8  * This library is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU Lesser General Public License as published by the
10  * Free Software Foundation; either version 2.1 of the License, or (at your option)
11  * any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  * License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; if not, write to the Free Software Foundation, Inc., 51
20  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <gst/gst.h>
29 #include <gst/gstutils.h>
30 #include <glib-object.h>
31 #include <unistd.h>
32 #include <sys/time.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <sched.h> /* sched_yield() */
37
38 #include "gstcamerasrc.h"
39 #include "gstcamerasrccontrol.h"
40 #include "gstcamerasrccolorbalance.h"
41
42
43 /******************************************************************************
44  * Definitions
45  *******************************************************************************/
46 GST_DEBUG_CATEGORY (camerasrc_debug);
47 #define GST_CAT_DEFAULT camerasrc_debug
48
49 #define USE_FRAME_SAFETY_MARGIN
50
51 #if defined (USE_FRAME_SAFETY_MARGIN)
52 #define FRAME_SAFETY_MARGIN 4096
53 #else
54 #define FRAME_SAFETY_MARGIN 0
55 #endif
56
57 #ifndef YUV422_SIZE
58 #define YUV422_SIZE(width,height) ( ((width)*(height)) << 1 )
59 #endif
60
61 #ifndef YUV420_SIZE
62 #define YUV420_SIZE(width,height) ( ((width)*(height)*3) >> 1 )
63 #endif
64
65 #define SCMN_CS_YUV420              1 /* Y:U:V 4:2:0 */
66 #define SCMN_CS_I420                SCMN_CS_YUV420 /* Y:U:V */
67 #define SCMN_CS_NV12                6
68 #define SCMN_CS_NV12_T64X32         11 /* 64x32 Tiled NV12 type */
69 #define SCMN_CS_UYVY                100
70 #define SCMN_CS_YUYV                101
71 #define SCMN_CS_YUY2                SCMN_CS_YUYV
72
73 /* max channel count *********************************************************/
74 #define SCMN_IMGB_MAX_PLANE         (4)
75
76 /* image buffer definition ***************************************************
77
78     +------------------------------------------+ ---
79     |                                          |  ^
80     |     a[], p[]                             |  |
81     |     +---------------------------+ ---    |  |
82     |     |                           |  ^     |  |
83     |     |<---------- w[] ---------->|  |     |  |
84     |     |                           |  |     |  |
85     |     |                           |        |
86     |     |                           |  h[]   |  e[]
87     |     |                           |        |
88     |     |                           |  |     |  |
89     |     |                           |  |     |  |
90     |     |                           |  v     |  |
91     |     +---------------------------+ ---    |  |
92     |                                          |  v
93     +------------------------------------------+ ---
94
95     |<----------------- s[] ------------------>|
96 */
97
98 typedef struct
99 {
100         /* width of each image plane */
101         int w[SCMN_IMGB_MAX_PLANE];
102         /* height of each image plane */
103         int h[SCMN_IMGB_MAX_PLANE];
104         /* stride of each image plane */
105         int s[SCMN_IMGB_MAX_PLANE];
106         /* elevation of each image plane */
107         int e[SCMN_IMGB_MAX_PLANE];
108         /* user space address of each image plane */
109         void *a[SCMN_IMGB_MAX_PLANE];
110         /* physical address of each image plane, if needs */
111         void *p[SCMN_IMGB_MAX_PLANE];
112         /* color space type of image */
113         int cs;
114         /* left postion, if needs */
115         int x;
116         /* top position, if needs */
117         int y;
118         /* to align memory */
119         int __dummy2;
120         /* arbitrary data */
121         int data[16];
122 } SCMN_IMGB;
123
124 #if !defined (PAGE_SHIFT)
125     #define PAGE_SHIFT sysconf(_SC_PAGESIZE)
126 #endif
127 #if !defined (PAGE_SIZE)
128     #define PAGE_SIZE (1UL << PAGE_SHIFT)
129 #endif
130 #if !defined (PAGE_MASK)
131     #define PAGE_MASK (~(PAGE_SIZE-1))
132 #endif
133 #if !defined (PAGE_ALIGN)
134     #define PAGE_ALIGN(addr)    (((addr)+PAGE_SIZE-1)&PAGE_MASK)
135 #endif
136
137 #define ALIGN_SIZE_I420                 (1024<<2)
138 #define ALIGN_SIZE_NV12                 (1024<<6)
139 #define CAMERASRC_ALIGN(addr,size)      (((addr)+((size)-1))&(~((size)-1)))
140
141 #if !defined (CLEAR)
142     #define CLEAR(x)                    memset(&(x), 0, sizeof(x))
143 #endif
144
145
146 /* Enables */
147 #define _ENABLE_CAMERASRC_DEBUG                 0
148
149 /* Local definitions */
150 #define _DEFAULT_WIDTH                          320
151 #define _DEFAULT_HEIGHT                         240
152 #define _DEFAULT_FPS                            30
153 #define _DEFAULT_HIGH_SPEED_FPS                 0
154 #define _DEFAULT_FPS_AUTO                       FALSE
155 #define _DEFAULT_PIX_FORMAT                     CAMERASRC_PIX_UYVY
156 #define _DEFAULT_FOURCC                         GST_MAKE_FOURCC ('J', 'P', 'E', 'G')
157 #define _DEFAULT_COLORSPACE                     CAMERASRC_COL_RAW
158 #define _DEFAULT_CAMERA_ID                      CAMERASRC_DEV_ID_PRIMARY
159
160 /* mmap/pad-alloc related definition */
161 #define _DEFAULT_NUM_LIVE_BUFFER                0
162 #define _DEFAULT_BUFFER_COUNT                   0
163 #define _ALLOWED_GAP_BTWN_BUF                   5       /* Allowed gap between circulation count of each buffer and that of average buffer */
164 #define _DEFAULT_BUFFER_RUNNING                 FALSE
165 #define _DEFAULT_DEQUE_WAITINGTIME              200     /* msec */
166 #define _MINIMUM_REMAINING_V4L2_QBUF            1       /* minimum number of buffer that should remain in the v4l2 driver */
167
168 #define _FD_DEFAULT     (-1)
169 #define _FD_MIN         (-1)
170 #define _FD_MAX         (1<<15) /* 2^15 == 32768 */
171
172 #define _DEFAULT_CAP_QUALITY                    GST_CAMERASRC_QUALITY_HIGH
173 #define _DEFAULT_CAP_JPG_QUALITY                95
174 #define _DEFAULT_CAP_WIDTH                      1600
175 #define _DEFAULT_CAP_HEIGHT                     1200
176 #define _DEFAULT_CAP_COUNT                      1
177 #define _DEFAULT_CAP_INTERVAL                   0
178 #define _DEFAULT_CAP_PROVIDE_EXIF               FALSE
179 #define _DEFAULT_ENABLE_ZSL_MODE                FALSE
180 #define _DEFAULT_DO_FACE_DETECT                 FALSE
181 #define _DEFAULT_DO_AF                          FALSE
182 #define _DEFAULT_SIGNAL_AF                      FALSE
183 #define _DEFAULT_SIGNAL_STILL_CAPTURE           FALSE
184 #define _DEFAULT_PREVIEW_WIDTH                  _DEFAULT_WIDTH
185 #define _DEFAULT_PREVIEW_HEIGHT                 _DEFAULT_HEIGHT
186 #define _DEFAULT_KEEPING_BUFFER                 0
187 #define _DEFAULT_USE_PAD_ALLOC                  FALSE
188 #define _DEFAULT_NUM_ALLOC_BUF                  6
189 #define _DEFAULT_SCRNL_FOURCC                   GST_MAKE_FOURCC('N','V','1','2')
190 #define _MAX_NUM_ALLOC_BUF                      100
191 #define _MAX_TRIAL_WAIT_FRAME                   25
192 #define _PAD_ALLOC_RETRY_PERIOD                 25
193 #define _MAX_PAD_ALLOC_RETRY_COUNT              300
194 #define _CONTINUOUS_SHOT_MARGIN                 50      /* msec */
195 #define _PREVIEW_BUFFER_WAIT_TIMEOUT            2000000 /* usec */
196
197 /*FIXME*/
198 #define _THUMBNAIL_WIDTH                        320
199 #define _THUMBNAIL_HEIGHT                       240
200
201 #define GST_TYPE_CAMERASRC_BUFFER               (gst_camerasrc_buffer_get_type())
202 #define GST_IS_CAMERASRC_BUFFER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_CAMERASRC_BUFFER))
203 #define GST_CAMERASRC_BUFFER(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CAMERASRC_BUFFER, GstCameraBuffer))
204 #define GST_TYPE_CAMERASRC_QUALITY              (gst_camerasrc_quality_get_type())
205
206
207 /* Enumerations */
208 enum {
209         /*signal*/
210         SIGNAL_STILL_CAPTURE,
211         SIGNAL_NEGO_COMPLETE,
212         /*SIGNAL_REGISTER_TROUBLE,*/
213         LAST_SIGNAL
214 };
215
216 enum {
217         ARG_0,
218         /* camera */
219         ARG_CAMERA_HIGH_SPEED_FPS,
220         ARG_CAMERA_AUTO_FPS,
221         ARG_CAMERA_ID,
222         ARG_CAMERA_EXT_VIDEO_FD,
223
224         /* capture */
225         ARG_CAMERA_CAPTURE_FOURCC,
226         ARG_CAMERA_CAPTURE_QUALITY,
227         ARG_CAMERA_CAPTURE_WIDTH,
228         ARG_CAMERA_CAPTURE_HEIGHT,
229         ARG_CAMERA_CAPTURE_INTERVAL,
230         ARG_CAMERA_CAPTURE_COUNT,
231         ARG_CAMERA_CAPTURE_JPG_QUALITY,
232         ARG_CAMERA_CAPTURE_PROVIDE_EXIF,
233
234         /* signal */
235         ARG_SIGNAL_STILLCAPTURE,
236         ARG_REQ_NEGOTIATION,
237
238         ARG_USE_PAD_ALLOC,
239         ARG_NUM_ALLOC_BUF,
240         ARG_OPERATION_STATUS,
241         ARG_HOLD_AF_AFTER_CAPTURE,
242         ARG_FAKE_ESD,
243         ARG_SENSOR_MODE,
244         ARG_VFLIP,
245         ARG_HFLIP,
246         ARG_NUM,
247 };
248
249 enum {
250         VIDEO_IN_MODE_UNKNOWN,
251         VIDEO_IN_MODE_PREVIEW,
252         VIDEO_IN_MODE_VIDEO,
253         VIDEO_IN_MODE_CAPTURE,
254 };
255
256 /* Structures */
257 typedef struct {
258     gint index;
259     gint buffer_data_index;
260     GstCameraSrc *camerasrc;
261 } GST_CAMERASRC_BUFFER_DATA;
262
263 static void gst_camerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
264
265 /* Local variables */
266 static GstBufferClass *camera_buffer_parent_class = NULL;
267
268 static guint gst_camerasrc_signals[LAST_SIGNAL] = { 0 };
269
270 /* For pad_alloc architecture */
271 static camerasrc_usr_buf_t g_present_buf;
272
273 #if _ENABLE_CAMERASRC_DEBUG
274 static unsigned int g_preview_frame_cnt;
275 #endif
276
277 /* Element template variables */
278 static GstStaticPadTemplate src_factory =
279         GST_STATIC_PAD_TEMPLATE("src",
280                                 GST_PAD_SRC,
281                                 GST_PAD_ALWAYS,
282                                 GST_STATIC_CAPS("video/x-raw-yuv,"
283                                                 "format = (fourcc) { UYVY }, "
284                                                 "width = (int) [ 1, 4096 ], "
285                                                 "height = (int) [ 1, 4096 ]; "
286                                                 "video/x-raw-yuv,"
287                                                 "format = (fourcc) { YU12 }, "
288                                                 "width = (int) [ 1, 4096 ], "
289                                                 "height = (int) [ 1, 4096 ]; "
290                                                 "video/x-raw-yuv,"
291                                                 "format = (fourcc) { I420 }, "
292                                                 "width = (int) [ 1, 4096 ], "
293                                                 "height = (int) [ 1, 4096 ]; "
294                                                 "video/x-raw-yuv,"
295                                                 "format = (fourcc) { NV12 }, "
296                                                 "width = (int) [ 1, 4096 ], "
297                                                 "height = (int) [ 1, 4096 ]; "
298                                                 "video/x-raw-yuv,"
299                                                 "format = (fourcc) { SN12 }, "
300                                                 "width = (int) [ 1, 4096 ], "
301                                                 "height = (int) [ 1, 4096 ]; "
302                                                 "video/x-raw-yuv,"
303                                                 "format = (fourcc) { ST12 }, "
304                                                 "width = (int) [ 1, 4096 ], "
305                                                 "height = (int) [ 1, 4096 ]; "
306                                                 "video/x-raw-yuv,"
307                                                 "format = (fourcc) { YUY2 }, "
308                                                 "width = (int) [ 1, 4096 ], "
309                                                 "height = (int) [ 1, 4096 ]; "
310                                                 "video/x-raw-yuv,"
311                                                 "format = (fourcc) { YUYV }, "
312                                                 "width = (int) [ 1, 4096 ], "
313                                                 "height = (int) [ 1, 4096 ]; "
314                                                 "video/x-raw-yuv,"
315                                                 "format = (fourcc) { SUYV }, "
316                                                 "width = (int) [ 1, 4096 ], "
317                                                 "height = (int) [ 1, 4096 ]; "
318                                                 "video/x-raw-yuv,"
319                                                 "format = (fourcc) { SUY2 }, "
320                                                 "width = (int) [ 1, 4096 ], "
321                                                 "height = (int) [ 1, 4096 ]; "
322                                                 "video/x-raw-yuv,"
323                                                 "format = (fourcc) { SYVY }, "
324                                                 "width = (int) [ 1, 4096 ], "
325                                                 "height = (int) [ 1, 4096 ]; "
326                                                 "video/x-raw-yuv,"
327                                                 "format = (fourcc) { S420 }, "
328                                                 "width = (int) [ 1, 4096 ], "
329                                                 "height = (int) [ 1, 4096 ]; "
330                                                 "video/x-raw-rgb,"
331                                                 "width = (int) [ 1, 4096 ], "
332                                                 "height = (int) [ 1, 4096 ]"));
333
334 static GstElementDetails camerasrc_details = {
335         "Camera Source GStreamer Plug-in",
336         "Src/Video",
337         "camera src for videosrc based GStreamer Plug-in",
338         ""
339 };
340
341
342
343 /* Local static functions */
344 static void gst_camerasrc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
345 static void gst_camerasrc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
346
347 static gboolean gst_camerasrc_src_start(GstBaseSrc *src);
348 static gboolean gst_camerasrc_src_stop(GstBaseSrc *src);
349 static gboolean gst_camerasrc_start(GstCameraSrc *camerasrc);
350
351 static GstFlowReturn gst_camerasrc_src_create(GstPushSrc *src, GstBuffer **buffer);
352 static GstFlowReturn gst_camerasrc_read_capture(GstCameraSrc *camerasrc, GstBuffer **buffer, int command);
353 static GstFlowReturn gst_camerasrc_read_preview_mmap(GstCameraSrc *camerasrc, GstBuffer **buffer);
354 static GstFlowReturn gst_camerasrc_read_preview_pad_alloc(GstCameraSrc *camerasrc, GstBuffer **buffer);
355 static unsigned char *gst_camerasrc_make_metadata_for_nonlinear_buffer(GstCameraSrc *avsysvideosrc, guint32 index);
356
357 static GstStateChangeReturn gst_camerasrc_change_state(GstElement *element, GstStateChange transition);
358 static GstCaps *gst_camerasrc_get_caps(GstBaseSrc *src);
359 static gboolean gst_camerasrc_set_caps(GstBaseSrc *src, GstCaps *caps);
360 static gboolean gst_camerasrc_get_caps_info(GstCameraSrc *camerasrc, GstCaps *caps, guint *size);
361 static gboolean gst_camerasrc_fill_ctrl_list(GstCameraSrc *camerasrc);
362 static gboolean gst_camerasrc_empty_ctrl_list(GstCameraSrc *camerasrc);
363 static void gst_camerasrc_finalize(GObject *object);
364
365 static gboolean gst_camerasrc_device_is_open(GstCameraSrc *camerasrc);
366 static gboolean gst_camerasrc_get_timeinfo(GstCameraSrc *camerasrc, GstBuffer *buffer);
367 static int get_proper_index(GstCameraSrc *camerasrc, GstBuffer *pad_alloc_buffer);
368
369 static gboolean gst_camerasrc_capture_start(GstCameraSrc *camerasrc);
370 static gboolean gst_camerasrc_capture_stop(GstCameraSrc *camerasrc);
371
372 static GstCameraBuffer *gst_camerasrc_buffer_new(GstCameraSrc *camerasrc);
373 static GType gst_camerasrc_buffer_get_type(void);
374 static void gst_camerasrc_buffer_class_init(gpointer g_class, gpointer class_data);
375 static void gst_camerasrc_buffer_finalize(GstCameraBuffer *buffer);
376 static void gst_camerasrc_buffer_free(gpointer data);
377 static void gst_camerasrc_buffer_trace(GstCameraSrc *camerasrc);
378 static void gst_camerasrc_error_handler(GstCameraSrc *camerasrc, int ret);
379
380 /* Util functions */
381 static void GenerateYUV420BlackFrame(unsigned char *buf, int buf_size, int width, int height);
382 static void GenerateYUV422BlackFrame(unsigned char *buf, int buf_size, int width, int height);
383 static gboolean GenerateST12BlackFrame(GstCameraSrc *camerasrc, unsigned char *buf, int buf_size, int width, int height);
384 static unsigned long gst_get_current_time(void);
385 static gboolean _gst_camerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize);
386 static gboolean _gst_camerasrc_get_raw_pixel_info(int fourcc, int *pix_format, int *colorspace);
387 static gboolean _gst_camerasrc_get_normal_buffer(GstCameraSrc *camerasrc, int fourcc,
388                                                  unsigned char *base_buf, int width, int height,
389                                                  unsigned char **new_buf, unsigned int *length);
390 #if _ENABLE_CAMERASRC_DEBUG
391 static int __util_write_file(char *filename, void *data, int size);
392 #endif /* _ENABLE_CAMERASRC_DEBUG */
393 static gboolean gst_camerasrc_negotiate (GstBaseSrc * basesrc);
394
395 GST_IMPLEMENT_CAMERASRC_COLOR_BALANCE_METHODS(GstCameraSrc, gst_camera_src);
396 GST_IMPLEMENT_CAMERASRC_CONTROL_METHODS(GstCameraSrc, gst_camera_src);
397
398
399 /******************************************************************************
400  * Implementations
401  *******************************************************************************/
402 static void gst_camerasrc_error_handler(GstCameraSrc *camerasrc, int ret)
403 {
404         switch (ret) {
405         case CAMERASRC_SUCCESS:
406                 break;
407         case CAMERASRC_ERR_IO_CONTROL:
408                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("IO control error"), GST_ERROR_SYSTEM);
409                 break;
410         case CAMERASRC_ERR_DEVICE_OPEN:
411                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ_WRITE, ("camera open failed"), GST_ERROR_SYSTEM);
412                 break;
413         case CAMERASRC_ERR_DEVICE_BUSY:
414                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, BUSY, ("camera device busy"), GST_ERROR_SYSTEM);
415                 break;
416         case CAMERASRC_ERR_DEVICE_NOT_FOUND:
417                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, NOT_FOUND, ("camera device not found"), GST_ERROR_SYSTEM);
418                 break;
419         case CAMERASRC_ERR_DEVICE_UNAVAILABLE:
420                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ, ("camera device unavailable"), GST_ERROR_SYSTEM);
421                 break;
422         case CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT:
423                 gst_camerasrc_buffer_trace(camerasrc);
424                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, TOO_LAZY, (("Timeout[live_buffers=%d]"), camerasrc->num_live_buffers), GST_ERROR_SYSTEM);
425                 break;
426         case CAMERASRC_ERR_DEVICE_NOT_SUPPORT:
427                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("Not supported"), GST_ERROR_SYSTEM);
428                 break;
429         case CAMERASRC_ERR_ALLOCATION:
430                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("memory allocation failed"), GST_ERROR_SYSTEM);
431                 break;
432         case CAMERASRC_ERR_SECURITY_SERVICE:
433                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("Security service failed"), GST_ERROR_SYSTEM);
434                 break;
435         default:
436                 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SEEK, (("General video device error[ret=%x]"), ret), GST_ERROR_SYSTEM);
437                 break;
438         }
439
440         return;
441 }
442
443 static gboolean gst_camerasrc_iface_supported(GstImplementsInterface *iface, GType iface_type)
444 {
445         g_assert(iface_type == GST_TYPE_CAMERA_CONTROL ||
446                  iface_type == GST_TYPE_COLOR_BALANCE);
447
448         return TRUE;
449 }
450
451
452 static void gst_camerasrc_interface_init(GstImplementsInterfaceClass *klass)
453 {
454         /*
455          * default virtual functions
456          */
457         klass->supported = gst_camerasrc_iface_supported;
458 }
459
460
461 void gst_camerasrc_init_interfaces(GType type)
462 {
463         static const GInterfaceInfo urihandler_info = {
464                 gst_camerasrc_uri_handler_init,
465                 NULL,
466                 NULL
467         };
468
469         static const GInterfaceInfo cameraiface_info = {
470                 (GInterfaceInitFunc)gst_camerasrc_interface_init,
471                 NULL,
472                 NULL,
473         };
474
475         static const GInterfaceInfo camerasrc_control_info = {
476                 (GInterfaceInitFunc)gst_camera_src_control_interface_init,
477                 NULL,
478                 NULL,
479         };
480
481         static const GInterfaceInfo camerasrc_color_balance_info = {
482                 (GInterfaceInitFunc)gst_camera_src_color_balance_interface_init,
483                 NULL,
484                 NULL,
485         };
486
487         g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
488         g_type_add_interface_static(type, GST_TYPE_IMPLEMENTS_INTERFACE, &cameraiface_info);
489         g_type_add_interface_static(type, GST_TYPE_CAMERA_CONTROL, &camerasrc_control_info);
490         g_type_add_interface_static(type, GST_TYPE_COLOR_BALANCE, &camerasrc_color_balance_info);
491 }
492
493
494 static GType gst_camerasrc_quality_get_type(void)
495 {
496         static GType camerasrc_quality_type = 0;
497         static const GEnumValue quality_types[] = {
498                 {GST_CAMERASRC_QUALITY_LOW, "Low quality", "low"},
499                 {GST_CAMERASRC_QUALITY_HIGH, "High quality", "high"},
500                 {0, NULL, NULL}
501         };
502
503         if (!camerasrc_quality_type) {
504                 camerasrc_quality_type = g_enum_register_static ("GstCameraSrcQuality", quality_types);
505         }
506         return camerasrc_quality_type;
507 }
508
509 /* VOID:OBJECT,OBJECT (generated by 'glib-genmarshal') */
510 #define g_marshal_value_peek_object(v)   (v)->data[0].v_pointer
511 void gst_camerasrc_VOID__OBJECT_OBJECT(GClosure *closure,
512                                        GValue *return_value,
513                                        guint n_param_values,
514                                        const GValue *param_values,
515                                        gpointer invocation_hint,
516                                        gpointer marshal_data)
517 {
518         typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT)(gpointer data1,
519                                                          gpointer arg_1,
520                                                          gpointer arg_2,
521                                                          gpointer arg_3,
522                                                          gpointer data2);
523         register GMarshalFunc_VOID__OBJECT_OBJECT callback;
524         register GCClosure *cc = (GCClosure*) closure;
525         register gpointer data1, data2;
526
527         g_return_if_fail (n_param_values == 4);
528
529         if (G_CCLOSURE_SWAP_DATA(closure)) {
530                 data1 = closure->data;
531                 data2 = g_value_peek_pointer(param_values + 0);
532         } else {
533                 data1 = g_value_peek_pointer(param_values + 0);
534                 data2 = closure->data;
535         }
536
537         callback = (GMarshalFunc_VOID__OBJECT_OBJECT)(marshal_data ? marshal_data : cc->callback);
538
539         callback(data1,
540                  g_marshal_value_peek_object(param_values + 1),
541                  g_marshal_value_peek_object(param_values + 2),
542                  g_marshal_value_peek_object(param_values + 3),
543                  data2);
544 }
545
546
547 /* use following BOILERPLATE MACRO as _get_type entry */
548 GST_BOILERPLATE_FULL(GstCameraSrc, gst_camerasrc, GstPushSrc, GST_TYPE_PUSH_SRC, gst_camerasrc_init_interfaces);
549
550
551 static int gst_camerasrc_af_cb(camsrc_handle_t handle, int state, void *usr_param)
552 {
553         GstCameraSrc *camerasrc = (GstCameraSrc *)usr_param;
554         GstMessage *m = NULL;
555         GstStructure *s = NULL;
556
557         MMTA_ACUM_ITEM_END("AutoFocus operating time", FALSE);
558
559         GST_INFO_OBJECT(camerasrc, "autofocus callback: state [%d]", state);
560
561         s = gst_structure_new("camerasrc-AF",
562                               "focus-state", G_TYPE_INT, state,
563                               NULL);
564         m = gst_message_new_element(GST_OBJECT(camerasrc), s);
565         gst_element_post_message(GST_ELEMENT(camerasrc), m);
566
567         return CAMERASRC_SUCCESS;
568 }
569
570
571 static gboolean gst_camerasrc_create(GstCameraSrc *camerasrc)
572 {
573         int ret = 0;
574
575         /*create handle*/
576         __ta__("        camerasrc_create",
577         ret = camerasrc_create(&(camerasrc->v4l2_handle));
578         );
579         if (ret != CAMERASRC_SUCCESS) {
580                 GST_ERROR_OBJECT(camerasrc, "camerasrc_create() failed. errcode = 0x%08X", ret);
581                 goto _ERROR;
582         }
583
584         GST_INFO_OBJECT (camerasrc, "camerasrc_create() done");
585
586         if (camerasrc->external_videofd != _FD_DEFAULT) {
587                 __ta__("            camerasrc_set_videofd",
588                 camerasrc_set_videofd(camerasrc->v4l2_handle,camerasrc->external_videofd);
589                 );
590         }
591
592         /*CAMERASRC CAM: realize*/
593         __ta__("            camerasrc_realize",  
594         ret = camerasrc_realize(camerasrc->v4l2_handle);
595         );
596         if (ret != CAMERASRC_SUCCESS) {
597                 goto _ERROR;
598         }
599
600         GST_INFO_OBJECT (camerasrc, "camerasrc_realize() done");
601
602         /*CAMERASRC CAM: start*/
603         __ta__("                camerasrc_start",  
604         ret = camerasrc_start(camerasrc->v4l2_handle);
605         );
606         if (ret != CAMERASRC_SUCCESS) {
607                 GST_ERROR_OBJECT(camerasrc, "camerasrc_start() failed. errcode = 0x%x", ret);
608                 goto _ERROR;
609         }
610
611         /*CAMERASRC CAM: set camera device id*/
612         /**@note if realized, iput device can't change!*/
613         __ta__("            camerasrc_set_input",
614         ret = camerasrc_set_input(camerasrc->v4l2_handle, camerasrc->camera_id);
615         );
616         if (ret != CAMERASRC_SUCCESS) {
617                 GST_ERROR_OBJECT(camerasrc, "camerasrc_set_input() failed. errcode = 0x%x", ret);
618                 goto _ERROR;
619         }
620
621         if (!gst_camerasrc_fill_ctrl_list(camerasrc)) {
622                 GST_WARNING_OBJECT(camerasrc, "Can't fill v4l2 control list.");
623         }
624
625         return TRUE;
626
627  _ERROR:
628         gst_camerasrc_error_handler(camerasrc, ret);
629
630         return FALSE;
631 }
632
633
634 static gboolean gst_camerasrc_destroy(GstCameraSrc *camerasrc)
635 {
636         GST_INFO_OBJECT (camerasrc, "ENTERED");
637
638         if (camerasrc->v4l2_handle) {
639                 /*Empty control list */
640                 gst_camerasrc_empty_ctrl_list(camerasrc);
641
642                 /*CAMERASRC CAM: stop stream*/
643                 /*CAMERASRC CAM: unrealize*/
644                 GST_INFO_OBJECT(camerasrc, "camerasrc_unrealize() calling...");
645                 camerasrc_unrealize(camerasrc->v4l2_handle);
646
647                 /*CAMERASRC CAM: destroy*/
648                 GST_INFO_OBJECT(camerasrc, "camerasrc_destroy() calling...");
649                 camerasrc_destroy(camerasrc->v4l2_handle);
650                 camerasrc->v4l2_handle = NULL;
651                 GST_INFO_OBJECT(camerasrc, "AV cam destroyed.");
652                 camerasrc->mode = VIDEO_IN_MODE_UNKNOWN;
653         }
654
655         GST_INFO_OBJECT(camerasrc, "LEAVED");
656
657         return TRUE;
658 }
659
660
661 static gboolean gst_camerasrc_fill_ctrl_list(GstCameraSrc *camerasrc)
662 {
663         int n = 0;
664         camerasrc_ctrl_info_t ctrl_info;
665
666         g_return_val_if_fail(camerasrc, FALSE);
667         g_return_val_if_fail(camerasrc->v4l2_handle, FALSE);
668
669         GST_DEBUG_OBJECT(camerasrc, "ENTERED");
670
671         for (n = CAMERASRC_CTRL_BRIGHTNESS ; n < CAMERASRC_CTRL_NUM ; n++) {
672                 GstCameraSrcColorBalanceChannel *camerasrc_color_channel = NULL;
673                 GstColorBalanceChannel *color_channel = NULL;
674
675                 GstCamerasrcControlChannel *camerasrc_control_channel = NULL;
676                 GstCameraControlChannel *control_channel = NULL;
677
678                 gint channel_type;
679
680                 memset(&ctrl_info, 0x0, sizeof(camerasrc_ctrl_info_t));
681
682                 if (camerasrc_query_control(camerasrc->v4l2_handle, n, &ctrl_info) != CAMERASRC_SUCCESS) {
683                         /* TODO: */
684                 }
685
686                 switch (n) {
687                         case CAMERASRC_CTRL_BRIGHTNESS:
688                         case CAMERASRC_CTRL_CONTRAST:
689                         case CAMERASRC_CTRL_WHITE_BALANCE:
690                         case CAMERASRC_CTRL_COLOR_TONE:
691                         case CAMERASRC_CTRL_PARTCOLOR_SRC:
692                         case CAMERASRC_CTRL_PARTCOLOR_DST:
693                         case CAMERASRC_CTRL_PARTCOLOR_MODE:
694                         case CAMERASRC_CTRL_SATURATION:
695                         case CAMERASRC_CTRL_SHARPNESS:
696                                 channel_type = INTERFACE_COLOR_BALANCE;
697                                 break;
698                         case CAMERASRC_CTRL_DIGITAL_ZOOM:
699                         case CAMERASRC_CTRL_OPTICAL_ZOOM:
700                         case CAMERASRC_CTRL_PROGRAM_MODE:
701                         case CAMERASRC_CTRL_FLIP:
702                         case CAMERASRC_CTRL_ANTI_HANDSHAKE:
703                         case CAMERASRC_CTRL_WIDE_DYNAMIC_RANGE:
704                                 channel_type = INTERFACE_CAMERA_CONTROL;
705                                 break;
706                         default:
707                                 channel_type = INTERFACE_NONE;
708                                 continue;
709                 }
710
711                 if (channel_type == INTERFACE_COLOR_BALANCE) {
712                         camerasrc_color_channel = g_object_new(GST_TYPE_CAMERASRC_COLOR_BALANCE_CHANNEL, NULL);
713                         color_channel = GST_COLOR_BALANCE_CHANNEL(camerasrc_color_channel);
714
715                         color_channel->label = g_strdup((const gchar *)camerasrc_ctrl_label[n]);
716                         camerasrc_color_channel->id = n;
717                         color_channel->min_value = ctrl_info.min;
718                         color_channel->max_value = ctrl_info.max;
719
720                         camerasrc->colors = g_list_append(camerasrc->colors, (gpointer)color_channel);
721                         GST_INFO_OBJECT(camerasrc, "Adding Color Balance Channel %s (%x)",
722                                                    color_channel->label, camerasrc_color_channel->id);
723                 } else { /* if( channel_type == INTERFACE_CAMERA_CONTROL ) */
724                         camerasrc_control_channel = g_object_new(GST_TYPE_CAMERASRC_CONTROL_CHANNEL, NULL);
725                         control_channel = GST_CAMERA_CONTROL_CHANNEL(camerasrc_control_channel);
726
727                         control_channel->label = g_strdup((const gchar *)camerasrc_ctrl_label[n]);
728                         camerasrc_control_channel->id = n;
729                         control_channel->min_value = ctrl_info.min;
730                         control_channel->max_value = ctrl_info.max;
731
732                         camerasrc->camera_controls = g_list_append(camerasrc->camera_controls, (gpointer)control_channel);
733                         GST_INFO_OBJECT(camerasrc, "Adding Camera Control Channel %s (%x)",
734                                                    control_channel->label, camerasrc_control_channel->id);
735                 }
736         }
737
738         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
739
740         return TRUE;
741 }
742
743
744 static gboolean gst_camerasrc_empty_ctrl_list(GstCameraSrc *camerasrc)
745 {
746         g_return_val_if_fail(camerasrc, FALSE);
747
748         GST_DEBUG_OBJECT (camerasrc, "ENTERED");
749
750         g_list_foreach(camerasrc->colors, (GFunc)g_object_unref, NULL);
751         g_list_free(camerasrc->colors);
752         camerasrc->colors = NULL;
753
754         g_list_foreach(camerasrc->camera_controls, (GFunc)g_object_unref, NULL);
755         g_list_free(camerasrc->camera_controls);
756         camerasrc->camera_controls = NULL;
757
758         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
759
760         return TRUE;
761 }
762
763
764 static GstFlowReturn gst_camerasrc_prepare_preview(GstCameraSrc *camerasrc, int buf_num)
765 {
766         int page_size = getpagesize();
767         int buffer_size = 0;
768         int i = 0;
769         int ret = 0;
770         unsigned int main_buf_sz = 0;
771         unsigned int thumb_buf_sz = 0;
772         GstCaps *negotiated_caps = gst_pad_get_negotiated_caps(GST_BASE_SRC_PAD(camerasrc));
773
774         g_return_val_if_fail(buf_num <= MAX_USR_BUFFER_NUM, GST_FLOW_ERROR);
775
776         camerasrc_query_img_buf_size(camerasrc->v4l2_handle, &main_buf_sz, &thumb_buf_sz);
777
778         buffer_size = (main_buf_sz + page_size - 1) & ~(page_size - 1);
779
780         g_present_buf.present_buffer = calloc(buf_num, sizeof(camerasrc_buffer_t));
781
782         for (i = 0 ; i < buf_num ; i++) {
783                 GST_INFO_OBJECT (camerasrc,"pad_alloc called");
784                 ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD (camerasrc),
785                                            0,
786                                            main_buf_sz,
787                                            negotiated_caps,
788                                            &(camerasrc->usr_buffer[i]));
789
790                 if (!GST_IS_BUFFER(camerasrc->usr_buffer[i])) {
791                         GST_INFO_OBJECT (camerasrc, "[%d] NOT BUFFER!!?", i);
792                 }
793                 if (ret != GST_FLOW_OK) {
794                         GST_ERROR_OBJECT (camerasrc, "gst_pad_alloc_buffer failed. [%d]", ret);
795                         return ret;
796                 }
797
798                 GST_INFO_OBJECT(camerasrc, "Alloced Size %d, Alloced address %p",
799                                            GST_BUFFER_SIZE(camerasrc->usr_buffer[i]),
800                                            GST_BUFFER_DATA(camerasrc->usr_buffer[i]));
801
802                 g_present_buf.present_buffer[i].start = GST_BUFFER_DATA(camerasrc->usr_buffer[i]);
803                 g_present_buf.present_buffer[i].length = buffer_size;
804         }
805
806         g_present_buf.num_buffer = buf_num;
807
808         gst_caps_unref(negotiated_caps);
809         negotiated_caps = NULL;
810
811         ret = camerasrc_present_usr_buffer(camerasrc->v4l2_handle, &g_present_buf, CAMERASRC_IO_METHOD_USRPTR);
812         if (ret != CAMERASRC_SUCCESS) {
813                 GST_ERROR_OBJECT(camerasrc, "camerasrc_present_usr_buffer failed ret = %x", ret);
814         } else {
815                 GST_INFO_OBJECT(camerasrc, "present_buffer success");
816         }
817
818         /*CAMERASRC CAM: start video preview*/
819         ret = camerasrc_start_preview_stream(camerasrc->v4l2_handle);
820         if (ret != CAMERASRC_SUCCESS) {
821                 GST_ERROR_OBJECT (camerasrc, "camerasrc_start_preview_stream() failed. errcode = 0x%08X", ret);
822                 gst_camerasrc_error_handler(camerasrc, ret);
823
824                 return GST_FLOW_ERROR;
825         }
826
827         GST_INFO_OBJECT(camerasrc, "camerasrc_start_preview_stream() done");
828
829         camerasrc->buffer_running = TRUE;
830         camerasrc->buffer_count = buf_num;
831         camerasrc->first_invokation = TRUE;
832
833         return GST_FLOW_OK;
834 }
835
836
837 static gboolean gst_camerasrc_start(GstCameraSrc *camerasrc)
838 {
839         int ret = 0;
840
841         camerasrc_format_t fmt;
842         camerasrc_frac_t frac;
843
844         GST_DEBUG_OBJECT(camerasrc, "ENTERED");
845
846 #ifdef _SPEED_UP_RAW_CAPTURE
847         /* check if from no stream change capture */
848         if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE &&
849             camerasrc->cap_stream_diff == FALSE) {
850                 camerasrc->buffer_running = TRUE;
851                 goto _READY_DONE;
852         }
853
854         camerasrc->cap_stream_diff = FALSE;
855 #endif
856
857         /**@note do not setting at camer starting time*/
858         /*CAMERASRC CAM: set FILTER (by default value)*/
859
860         /*CAMERASRC CAM: callback*/
861         camerasrc_set_focused_callback(camerasrc->v4l2_handle, gst_camerasrc_af_cb, camerasrc);
862
863         CLEAR(fmt);
864         CLEAR(frac);
865
866         /*CAMERASRC CAM: format*/
867         fmt.pix_format = camerasrc->pix_format;
868         fmt.colorspace = camerasrc->colorspace;
869         fmt.is_highquality_mode = 0;    /*Fixed. if preview mode, set 0*/
870         fmt.rotation = camerasrc->rotate;
871
872         /*CAMERASRC CAM: set resolution - Do not care about rotation */
873         CAMERASRC_SET_SIZE_BY_DIMENSION(fmt, camerasrc->width, camerasrc->height);
874
875         /*CAMERASRC CAM: set format*/
876         GST_INFO_OBJECT(camerasrc, "pix [%dx%d] fps %d, format %d, colorspace %d, rotation %d",
877                                    camerasrc->width, camerasrc->height, camerasrc->fps,
878                                    fmt.pix_format, fmt.colorspace, fmt.rotation);
879         ret = camerasrc_set_format(camerasrc->v4l2_handle, &fmt);
880         if (ret != CAMERASRC_SUCCESS) {
881                 GST_ERROR_OBJECT (camerasrc, "camerasrc_set_format() failed. errcode = 0x%08X", ret);
882                 goto _ERROR;
883         }
884
885         /*CAMERASRC CAM: set fps*/
886         if (camerasrc->fps_auto) {
887                 /*if fps is zero, auto fps mode*/
888                 frac.numerator = 0;
889                 frac.denominator = 1;
890                 GST_INFO_OBJECT (camerasrc, "FPS auto(%d)", camerasrc->fps_auto);
891         } else if (camerasrc->high_speed_fps <= 0) {
892                 if (camerasrc->fps <= 0) {
893                         /*if fps is zero, auto fps mode*/
894                         frac.numerator   = 0;
895                         frac.denominator = 1;
896                 } else {
897                         frac.numerator   = 1;
898                         frac.denominator = camerasrc->fps;
899                 }
900         } else {
901                 GST_INFO_OBJECT(camerasrc, "high speed recording(%d)", camerasrc->high_speed_fps);
902                 frac.numerator = 1;
903                 frac.denominator = camerasrc->high_speed_fps;
904         }
905
906         ret = camerasrc_set_timeperframe(camerasrc->v4l2_handle, &frac);
907         if (ret != CAMERASRC_SUCCESS) {
908                 GST_ERROR_OBJECT(camerasrc, "camerasrc_set_timeperframe() failed. errcode = 0x%x", ret);
909                 goto _ERROR;
910         }
911         GST_INFO_OBJECT (camerasrc, "camerasrc_set_timeperframe() done");
912
913         camerasrc->buffer_running = TRUE;
914
915         if ((camerasrc->use_pad_alloc == FALSE)) {
916                 /*CAMERASRC CAM: Set Sensor mode*/
917                 camerasrc_set_sensor_mode(camerasrc->v4l2_handle, camerasrc->sensor_mode);
918
919                 /*CAMERASRC CAM: Set flip*/
920                 camerasrc_set_vflip(camerasrc->v4l2_handle, camerasrc->vflip);
921                 camerasrc_set_hflip(camerasrc->v4l2_handle, camerasrc->hflip);
922
923                 /*CAMERASRC CAM: start video preview*/
924                 __ta__("                camerasrc_start_preview_stream",
925                 ret = camerasrc_start_preview_stream(camerasrc->v4l2_handle);
926                 );
927                 if (ret != CAMERASRC_SUCCESS) {
928                         GST_ERROR_OBJECT(camerasrc, "camerasrc_start_preview_stream() failed. errcode = 0x%x", ret);
929                         camerasrc->buffer_running = FALSE;
930                         goto _ERROR;
931                 }
932
933                 GST_INFO_OBJECT(camerasrc, "camerasrc_start_preview_stream() done");
934
935                 ret = camerasrc_get_num_buffer(camerasrc->v4l2_handle, &(camerasrc->buffer_count));
936                 if (ret != CAMERASRC_SUCCESS) {
937                         GST_ERROR_OBJECT(camerasrc, "camerasrc_get_num_buffer() failed. errcode = 0x%x", ret);
938                         goto _ERROR;
939                 }
940
941                 GST_INFO_OBJECT(camerasrc, "buffer number %d", camerasrc->buffer_count);
942 #ifdef _SPEED_UP_RAW_CAPTURE
943                 camerasrc->cap_stream_diff = FALSE;
944 #endif
945         }
946
947 #ifdef _SPEED_UP_RAW_CAPTURE
948 _READY_DONE:
949 #endif
950         camerasrc->mode = VIDEO_IN_MODE_PREVIEW;
951         camerasrc->current_buffer_data_index = (camerasrc->current_buffer_data_index + 1)%10;
952
953         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
954
955         return TRUE;
956
957 _ERROR:
958         gst_camerasrc_error_handler(camerasrc, ret);
959
960         /* Stop stream */
961         camerasrc_stop_stream(camerasrc->v4l2_handle);
962
963         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
964
965         return FALSE;
966 }
967
968
969 static gboolean gst_camerasrc_stop(GstCameraSrc *camerasrc)
970 {
971         camerasrc_io_method_t io_method;
972
973         GST_DEBUG_OBJECT (camerasrc, "ENTERED");
974
975         if (camerasrc->v4l2_handle) {
976                 /* CAMERASRC CAM: stop stream */
977                 /* To guarantee buffers are valid before finishing */
978                 GMutex *lock_mutex = NULL;
979
980                 if (camerasrc->use_pad_alloc == FALSE) {
981                         lock_mutex = camerasrc->buffer_lock;
982                 } else {
983                         lock_mutex = camerasrc->pad_alloc_mutex;
984                 }
985
986                 g_mutex_lock(lock_mutex);
987                 while (camerasrc->num_live_buffers > _DEFAULT_KEEPING_BUFFER) {
988                         GTimeVal abstimeout;
989                         GST_INFO_OBJECT(camerasrc, "Wait until all live buffers are relased. (Tot=%d, Live=%d)",
990                                                    camerasrc->buffer_count, camerasrc->num_live_buffers);
991
992                         g_get_current_time(&abstimeout);
993                         g_time_val_add(&abstimeout, _PREVIEW_BUFFER_WAIT_TIMEOUT);
994
995                         if (!g_cond_timed_wait(camerasrc->buffer_cond, lock_mutex, &abstimeout)) {
996                                 GST_ERROR_OBJECT(camerasrc, "Buffer wait timeout[%d usec].(Live=%d) Skip waiting...",
997                                                             _PREVIEW_BUFFER_WAIT_TIMEOUT, camerasrc->num_live_buffers);
998                                 gst_camerasrc_buffer_trace(camerasrc);
999                                 break;
1000                         } else {
1001                                 GST_INFO_OBJECT(camerasrc, "Signal received.");
1002                         }
1003                 }
1004                 g_mutex_unlock(lock_mutex);
1005                 GST_INFO_OBJECT(camerasrc, "Waiting free buffer finished. (Live=%d)", camerasrc->num_live_buffers);
1006
1007                 camerasrc_stop_stream(camerasrc->v4l2_handle);
1008
1009                 camerasrc->buffer_running = FALSE;
1010                 camerasrc->mode = VIDEO_IN_MODE_UNKNOWN;
1011
1012                 /* If I/O method is Usrptr, it uses usr_buffer that is member of camerasrc structure */
1013                 /* It must be unreffed when it stops */
1014
1015                 camerasrc_get_io_method(camerasrc->v4l2_handle, &io_method);
1016                 switch (io_method) {
1017                 case CAMERASRC_IO_METHOD_MMAP:
1018                         break;
1019                 case CAMERASRC_IO_METHOD_USRPTR:
1020                         if (g_present_buf.present_buffer) {
1021                                 free(g_present_buf.present_buffer);
1022                                 g_present_buf.present_buffer = NULL;
1023                         }
1024                         break;
1025                 case CAMERASRC_IO_METHOD_READ:
1026                 default:
1027                         break;
1028                 }
1029         }
1030
1031         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
1032
1033         return TRUE;
1034 }
1035
1036
1037 static gboolean gst_camerasrc_capture_start(GstCameraSrc *camerasrc)
1038 {
1039         /*CAMERASRC CAM*/
1040         int ret = 0;
1041         char *pfourcc = NULL;
1042         camerasrc_format_t fmt;
1043         camerasrc_frac_t frac;
1044
1045         GST_INFO_OBJECT(camerasrc, "ENTERED");
1046
1047         if (camerasrc->mode == VIDEO_IN_MODE_PREVIEW) {
1048                 /* To guarantee buffers are valid before finishing. */
1049                 __ta__( "            wait for buffer in gst_camerasrc_capture_start",
1050                 if (camerasrc->use_pad_alloc == FALSE) {
1051                         g_mutex_lock(camerasrc->buffer_lock);
1052                         while (camerasrc->num_live_buffers > _DEFAULT_KEEPING_BUFFER) {
1053                                 GTimeVal abstimeout;
1054                                 GST_INFO_OBJECT(camerasrc, "Wait until all live buffers are relased. (Tot=%d, Live=%d)",
1055                                                            camerasrc->buffer_count, camerasrc->num_live_buffers);
1056
1057                                 g_get_current_time(&abstimeout);
1058                                 g_time_val_add(&abstimeout, _PREVIEW_BUFFER_WAIT_TIMEOUT);
1059
1060                                 if (!g_cond_timed_wait(camerasrc->buffer_cond, camerasrc->buffer_lock, &abstimeout)) {
1061                                         GST_ERROR_OBJECT(camerasrc, "Buffer wait timeout[%d usec].(Live=%d) Skip waiting...",
1062                                                                     _PREVIEW_BUFFER_WAIT_TIMEOUT, camerasrc->num_live_buffers);
1063                                         gst_camerasrc_buffer_trace(camerasrc);
1064                                         break;
1065                                 } else {
1066                                         GST_INFO_OBJECT(camerasrc, "Signal received.");
1067                                 }
1068                         }
1069                         g_mutex_unlock(camerasrc->buffer_lock);
1070                         GST_INFO_OBJECT(camerasrc, "Waiting free buffer is finished. (Live=%d)", camerasrc->num_live_buffers);
1071                 }
1072                 );
1073
1074 #ifdef _SPEED_UP_RAW_CAPTURE
1075                 /* Skip restart stream if format/width/height are all same */
1076                 if (camerasrc->fourcc == camerasrc->cap_fourcc &&
1077                     camerasrc->width == camerasrc->cap_width &&
1078                     camerasrc->height == camerasrc->cap_height) {
1079                         GST_INFO_OBJECT(camerasrc, "fourcc, width and height is same. Skip restarting stream.");
1080                         goto _CAPTURE_READY_DONE;
1081                 }
1082
1083                 camerasrc->cap_stream_diff = TRUE;
1084 #endif
1085
1086                 /*CAMERASRC CAM: stop stream*/
1087                 __ta__( "            camerasrc_stop_stream in gst_camerasrc_capture_start",
1088                 camerasrc_stop_stream(camerasrc->v4l2_handle);
1089                 );
1090
1091                 GST_INFO_OBJECT (camerasrc, "camerasrc_stop_stream() done");
1092                 camerasrc->buffer_running = FALSE;
1093
1094                 pfourcc = (char*)&camerasrc->cap_fourcc;
1095                 GST_INFO_OBJECT(camerasrc, "CAPTURE: Size[%dx%d], fourcc(%c%c%c%c) quality[%d] interval[%d] count[%d]",
1096                                            camerasrc->cap_width, camerasrc->cap_height,
1097                                            pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3],
1098                                            camerasrc->cap_quality, camerasrc->cap_interval, camerasrc->cap_count);
1099
1100                 /*START STILL CAPTURE*/
1101
1102                 /*set current video info*/
1103
1104                 memset(&fmt, 0x00, sizeof (camerasrc_format_t));
1105
1106                 /*CAMERASRC CAM: set format*/
1107                 CAMERASRC_SET_SIZE_BY_DIMENSION(fmt, camerasrc->cap_width, camerasrc->cap_height);
1108
1109                 _gst_camerasrc_get_raw_pixel_info(camerasrc->cap_fourcc, &(fmt.pix_format), &(fmt.colorspace));
1110                 fmt.rotation = 0;
1111
1112                 if (camerasrc->cap_fourcc == GST_MAKE_FOURCC('J', 'P', 'E', 'G') ||
1113                     camerasrc->cap_fourcc == GST_MAKE_FOURCC('j', 'p', 'e', 'g')) {
1114                         fmt.quality = camerasrc->cap_jpg_quality;
1115                         fmt.is_highquality_mode = camerasrc->cap_quality;       /*must be 1*/
1116                 } else {
1117                         fmt.is_highquality_mode = camerasrc->cap_quality;       /*0 or 1 (default: 0)*/
1118                 }
1119
1120                 /*CAMERASRC CAM: format*/
1121                 ret = camerasrc_set_format(camerasrc->v4l2_handle, &fmt);
1122                 if (ret != CAMERASRC_SUCCESS) {
1123                         GST_ERROR_OBJECT(camerasrc, "camerasrc_set_format() failed. errcode = 0x%x", ret);
1124                         goto _ERROR;
1125                 }
1126                 GST_INFO_OBJECT(camerasrc, "camerasrc_set_format() done");
1127
1128                 if (camerasrc->fps_auto || camerasrc->fps <= 0) {
1129                         /*if fps is zero, auto fps mode*/
1130                         frac.numerator   = 0;
1131                         frac.denominator = 1;
1132                         GST_INFO_OBJECT (camerasrc, "FPS auto");
1133                 } else {
1134                         frac.numerator   = 1;
1135                         frac.denominator = camerasrc->fps;
1136                         GST_INFO_OBJECT (camerasrc, "FPS (%d)", camerasrc->fps);
1137                 }
1138
1139                 ret = camerasrc_set_timeperframe(camerasrc->v4l2_handle, &frac);
1140                 if (ret != CAMERASRC_SUCCESS) {
1141                         GST_ERROR_OBJECT(camerasrc, "camerasrc_set_timeperframe() failed. errcode = 0x%x", ret);
1142                         goto _ERROR;
1143                 }
1144                 GST_INFO_OBJECT (camerasrc, "camerasrc_set_timeperframe() done");
1145
1146                 /*CAMERASRC CAM: start stream*/
1147                 __ta__( "            camerasrc_start_still_stream",
1148                 ret = camerasrc_start_still_stream(camerasrc->v4l2_handle);
1149                 );
1150                 if (ret != CAMERASRC_SUCCESS) {
1151                         GST_ERROR_OBJECT(camerasrc, "camerasrc_start_still_stream() failed. errcode = 0x%x", ret);
1152                         goto _ERROR;
1153                 }
1154                 GST_INFO_OBJECT(camerasrc, "camerasrc_start_still_stream() done");
1155
1156                 camerasrc->buffer_running = TRUE;
1157
1158                 /*CAMERASRC CAM: set fps*/
1159                 /*TODO: maybe do not works!*/
1160
1161 #ifdef _SPEED_UP_RAW_CAPTURE
1162 _CAPTURE_READY_DONE:
1163 #endif
1164
1165                 g_mutex_lock(camerasrc->jpg_mutex);
1166                 camerasrc->cap_next_time = 0UL;
1167                 g_mutex_unlock(camerasrc->jpg_mutex);
1168                 camerasrc->cap_count_current = 0;
1169
1170                 /* end change to capture mode*/
1171                 camerasrc->mode = VIDEO_IN_MODE_CAPTURE;
1172
1173                 GST_INFO_OBJECT(camerasrc, "CAPTURE STARTED!");
1174         } else {
1175                 GST_WARNING_OBJECT(camerasrc, "Wrong state[%d]!", camerasrc->mode);
1176         }
1177
1178         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
1179
1180         return TRUE;
1181
1182 _ERROR:
1183         gst_camerasrc_error_handler(camerasrc, ret);
1184
1185         return FALSE;
1186 }
1187
1188
1189 static gboolean gst_camerasrc_capture_stop(GstCameraSrc *camerasrc)
1190 {
1191         GST_DEBUG_OBJECT(camerasrc, "ENTERED");
1192
1193         if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) {
1194 #ifdef _SPEED_UP_RAW_CAPTURE
1195                 if (camerasrc->cap_stream_diff) {
1196                         /*CAMERASRC CAM: stop stream*/
1197                         camerasrc_stop_stream(camerasrc->v4l2_handle);
1198                         camerasrc->buffer_running = FALSE;
1199
1200                         GST_INFO_OBJECT(camerasrc, "camerasrc_stop_stream() done");
1201                 } else {
1202                         GST_INFO_OBJECT(camerasrc, "no need to stop stream(capture format==preview format)");
1203                 }
1204 #else
1205                 /*CAMERASRC CAM: stop stream*/
1206                 camerasrc_stop_stream(camerasrc->v4l2_handle);
1207                 camerasrc->buffer_running = FALSE;
1208
1209                 GST_INFO_OBJECT(camerasrc, "camerasrc_stop_stream() done");
1210 #endif
1211                 GST_INFO_OBJECT(camerasrc, "CAPTURE STOPPED!");
1212         }
1213
1214         GST_DEBUG_OBJECT (camerasrc, "LEAVED");
1215
1216         return TRUE;
1217 }
1218
1219
1220 static GstFlowReturn gst_camerasrc_read_preview_mmap(GstCameraSrc *camerasrc, GstBuffer **buffer)
1221 {
1222         int ret = 0;
1223         int v4l2_buffer_index = 0;
1224         guint i = 0;
1225         unsigned int isize = 0;
1226         unsigned char *pData = NULL;
1227         void *buf = NULL;
1228         camerasrc_buffer_t main_buf;
1229         GstCameraBuffer *vid_buf = NULL;
1230
1231         /*alloc main buffer*/
1232         vid_buf = gst_camerasrc_buffer_new(camerasrc);
1233         buf = (GstCameraBuffer *)vid_buf;
1234
1235         g_mutex_lock(camerasrc->buffer_lock);
1236         GST_LOG_OBJECT(camerasrc, "After lock(buffer live %d, total %d)",
1237                                   camerasrc->num_live_buffers, camerasrc->buffer_count);
1238
1239         for (i = 0 ; i < _MAX_TRIAL_WAIT_FRAME ; i++) {
1240                 /* Wait frame */
1241                 __ta__( "                camerasrc_wait_frame_available",
1242                 ret = camerasrc_wait_frame_available(camerasrc->v4l2_handle, _DEFAULT_DEQUE_WAITINGTIME);
1243                 );
1244                 if (ret != CAMERASRC_SUCCESS) {
1245                         if (ret == CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT && i < (_MAX_TRIAL_WAIT_FRAME - 1)) {
1246                                 GST_ERROR_OBJECT(camerasrc, "SELECT TIMEOUT!!! Retry..(pad_alloc %d, live %d)",
1247                                                             camerasrc->use_pad_alloc, camerasrc->num_live_buffers);
1248                                 continue;
1249                         }
1250
1251                         if (ret == CAMERASRC_ERR_DEVICE_UNAVAILABLE) {
1252                                 GST_ERROR_OBJECT(camerasrc,  "register trouble error!! [%x]", ret);
1253                                 /*g_signal_emit (G_OBJECT (camerasrc), gst_camerasrc_signals[SIGNAL_REGISTER_TROUBLE], (GQuark)NULL);*/
1254                                 g_mutex_unlock(camerasrc->buffer_lock);
1255                                 gst_camerasrc_error_handler(camerasrc, ret);
1256
1257                                 return GST_FLOW_ERROR;
1258                         } else if (ret == CAMERASRC_ERR_INVALID_STATE && (i < _MAX_TRIAL_WAIT_FRAME - 1)) {
1259                                 GST_WARNING_OBJECT(camerasrc, "try again...");
1260                         } else {
1261                                 GST_ERROR_OBJECT(camerasrc, "Frame waiting error[%x]", ret);
1262                                 g_mutex_unlock(camerasrc->buffer_lock);
1263                                 gst_camerasrc_error_handler(camerasrc, ret);
1264
1265                                 return GST_FLOW_ERROR;
1266                         }
1267                 } else {
1268                         GST_LOG_OBJECT(camerasrc, "select success, do DQBUF");
1269                         break;
1270                 }
1271         }
1272
1273         /* Buffer DQ */
1274         __ta__( "                camerasrc_dequeue_buffer",
1275         ret = camerasrc_dequeue_buffer(camerasrc->v4l2_handle, &v4l2_buffer_index, &main_buf, NULL);
1276         );
1277         if (ret != CAMERASRC_SUCCESS) {
1278                 GST_ERROR_OBJECT(camerasrc, "Dequeue frame error[%x]", ret);
1279                 g_mutex_unlock(camerasrc->buffer_lock);
1280                 gst_camerasrc_error_handler(camerasrc, ret);
1281
1282                 return GST_FLOW_ERROR;
1283         }
1284
1285         camerasrc->num_live_buffers++;
1286         GST_LOG_OBJECT (camerasrc, "after : DQBUF (index %d, live bufs %d)",
1287                                    v4l2_buffer_index, camerasrc->num_live_buffers);
1288
1289         g_mutex_unlock (camerasrc->buffer_lock);
1290
1291         if (camerasrc->fourcc == GST_MAKE_FOURCC('S','N','1','2') ||
1292             camerasrc->fourcc == GST_MAKE_FOURCC('S','T','1','2') ||
1293             camerasrc->fourcc == GST_MAKE_FOURCC('S','U','Y','V') ||
1294             camerasrc->fourcc == GST_MAKE_FOURCC('S','U','Y','2') ||
1295             camerasrc->fourcc == GST_MAKE_FOURCC('S','Y','V','Y') ||
1296             camerasrc->fourcc == GST_MAKE_FOURCC('S','4','2','0')) {
1297                 /* for physical address */
1298                 GST_BUFFER_MALLOCDATA(vid_buf) = gst_camerasrc_make_metadata_for_nonlinear_buffer(camerasrc, v4l2_buffer_index);
1299
1300                 /* for virtual address - GST_BUFFER_DATA and SIZE */
1301                 pData = main_buf.start;
1302                 isize = main_buf.length;
1303         } else if (camerasrc->fourcc == GST_MAKE_FOURCC('I','4','2','0') ||
1304                    camerasrc->fourcc == GST_MAKE_FOURCC('N','V','1','2')) {
1305                 ret = _gst_camerasrc_get_normal_buffer(camerasrc, camerasrc->fourcc,
1306                                                        main_buf.start, camerasrc->width, camerasrc->height,
1307                                                        &pData, &isize);
1308                 if (ret == FALSE) {
1309                         g_mutex_unlock( camerasrc->buffer_lock );
1310                         return GST_FLOW_ERROR;
1311                 }
1312
1313                 vid_buf->is_alloc_data = TRUE;
1314         } else {
1315                 pData = main_buf.start;
1316                 isize = main_buf.length;
1317         }
1318
1319         GST_BUFFER_DATA(vid_buf) = pData;
1320         GST_BUFFER_SIZE(vid_buf) = isize;
1321         vid_buf->v4l2_buffer_index = v4l2_buffer_index;
1322
1323         if (camerasrc->firsttime) {
1324                 /** Because of basesrc negotiation , "framerate" field is needed. */
1325                 int fps_nu = 0;
1326                 int fps_de = 0;
1327                 int af_mode = CAMERASRC_AF_MODE_AUTO;
1328                 int af_range = CAMERASRC_AF_RANGE_NORMAL;
1329                 gchar *caps_string = NULL;
1330                 GstCaps *caps = NULL;
1331
1332                 if (camerasrc->fps <= 0) {
1333                         /*if fps is zero, auto fps mode*/
1334                         fps_nu = 0;
1335                         fps_de = 1;
1336                 } else {
1337                         fps_nu = 1;
1338                         fps_de = camerasrc->fps;
1339                 }
1340
1341                 GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]",
1342                                            camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps);
1343
1344                 caps = gst_caps_new_simple("video/x-raw-yuv",
1345                                            "format", GST_TYPE_FOURCC, camerasrc->fourcc,
1346                                            "width", G_TYPE_INT, camerasrc->width,
1347                                            "height", G_TYPE_INT, camerasrc->height,
1348                                            "framerate", GST_TYPE_FRACTION, fps_de, fps_nu,
1349                                            NULL);
1350                 if (caps == NULL) {
1351                         GST_ERROR_OBJECT(camerasrc, "failed to alloc caps");
1352                         gst_buffer_unref((GstBuffer *)vid_buf);
1353                         vid_buf = NULL;
1354                         buf = NULL;
1355                         return GST_FLOW_ERROR;
1356                 }
1357
1358                 if (camerasrc->use_rotate_caps) {
1359                         gst_caps_set_simple(caps, "rotate", G_TYPE_INT, camerasrc->rotate, NULL);
1360                 }
1361
1362                 GST_BUFFER_CAPS(buf) = caps;
1363
1364                 caps_string = gst_caps_to_string(caps);
1365                 GST_INFO_OBJECT(camerasrc, "PREVIEW MODE first time [%dx%d], rotate[%d], caps[%s]",
1366                                            camerasrc->width, camerasrc->height, camerasrc->rotate, caps_string);
1367                 if (caps_string) {
1368                         g_free(caps_string);
1369                         caps_string = NULL;
1370                 }
1371
1372                 if (camerasrc->fourcc == GST_MAKE_FOURCC('N','V','1','2') ||
1373                     camerasrc->fourcc == GST_MAKE_FOURCC('S','N','1','2')) {
1374                         /* Start Focusing when Continuous AF */
1375                         camerasrc_get_autofocusing_mode(camerasrc->v4l2_handle, &af_mode, &af_range);
1376                         if (af_mode == CAMERASRC_AF_MODE_CONTINUOUS) {
1377                                 GST_INFO_OBJECT(camerasrc, "This is (NV12 or SN12) and Continuous AF mode. Start AF");
1378                                 camerasrc_start_autofocusing(camerasrc->v4l2_handle);
1379                         }
1380                 }
1381
1382                 camerasrc->firsttime = FALSE;
1383         }
1384
1385         gst_camerasrc_get_timeinfo(camerasrc, (GstBuffer*)vid_buf);
1386
1387         *buffer = (GstBuffer*)vid_buf;
1388
1389         /*GST_DEBUG_OBJECT(camerasrc, "refcount: %d", GST_OBJECT_REFCOUNT(*buffer));*/
1390
1391 #if _ENABLE_CAMERASRC_DEBUG
1392         g_preview_frame_cnt++;
1393 #endif
1394
1395         return GST_FLOW_OK;
1396 }
1397
1398
1399 static GstFlowReturn gst_camerasrc_read_preview_pad_alloc(GstCameraSrc *camerasrc, GstBuffer **buffer)
1400 {
1401         int ret = 0;
1402         int v4l2_buffer_index = 0;
1403         int is_esd = 0;
1404         guint cnt_again = _MAX_PAD_ALLOC_RETRY_COUNT;
1405         void *buf = NULL;
1406         camerasrc_buffer_t main_buf;
1407         GstBuffer *gst_buf = NULL;
1408         GST_CAMERASRC_BUFFER_DATA *buffer_data = NULL;
1409
1410         /*alloc main buffer*/
1411         gst_buf = *buffer;
1412         buf = (GstBuffer *)gst_buf;
1413
1414         g_mutex_lock(camerasrc->buffer_lock);
1415         GST_LOG_OBJECT(camerasrc, "After lock(lvn %d, buf cnt %d)", camerasrc->num_live_buffers, camerasrc->buffer_count);
1416
1417 AGAIN:
1418         g_mutex_lock (camerasrc->pad_alloc_mutex);
1419         while (!g_queue_is_empty(camerasrc->pad_alloc_list) && !camerasrc->first_invokation) {
1420                 int pad_alloc_index = -1;
1421                 int proper_index = -1;
1422                 camerasrc_buffer_t camerasrc_buffer;
1423                 GstBuffer *pad_alloc_buffer;
1424                 GstCaps *negotiated_caps = NULL;
1425
1426                 g_mutex_unlock (camerasrc->pad_alloc_mutex);
1427
1428                 camerasrc_buffer.start = NULL;
1429                 camerasrc_buffer.length = 0;
1430
1431                 g_mutex_lock (camerasrc->pad_alloc_mutex);
1432                 pad_alloc_index = (int)g_queue_pop_head(camerasrc->pad_alloc_list);
1433                 g_mutex_unlock (camerasrc->pad_alloc_mutex);
1434                 sched_yield();
1435                 GST_LOG_OBJECT (camerasrc, "Index queue have item. pad_alloc_index = %d", pad_alloc_index);
1436
1437                 negotiated_caps = gst_pad_get_negotiated_caps (GST_BASE_SRC_PAD (camerasrc));
1438
1439                 /* pad allocation from sink(or any where) */
1440                 ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD (camerasrc),
1441                                            0,
1442                                            camerasrc->main_buf_sz,
1443                                            negotiated_caps,
1444                                            &pad_alloc_buffer);
1445                 if (ret != GST_FLOW_OK) {
1446                         GST_ERROR_OBJECT(camerasrc, "Pad alloc fail, ret = [%d]", ret);
1447                         g_cond_signal(camerasrc->buffer_cond);
1448                         g_mutex_unlock(camerasrc->buffer_lock);
1449                         gst_caps_unref(negotiated_caps);
1450
1451                         return ret;
1452                 }
1453
1454                 proper_index = get_proper_index(camerasrc, pad_alloc_buffer);
1455                 if (proper_index == -1) {
1456                         GST_INFO_OBJECT(camerasrc, "Proper index doesn't exist");
1457                         g_mutex_unlock(camerasrc->buffer_lock);
1458
1459                         return GST_FLOW_ERROR;
1460                 }
1461
1462                 if (proper_index != pad_alloc_index) {
1463                         GST_LOG_OBJECT(camerasrc, "Proper index different from pad_alloc_index, proper_index = %d, pad_alloc_index = %d",
1464                                                   proper_index, pad_alloc_index);
1465                 }
1466
1467                 GST_LOG_OBJECT(camerasrc, "gst_pad_alloc_buffer called. index = %d, GstBuffer address = %p",
1468                                           proper_index, &(camerasrc->usr_buffer[pad_alloc_index]));
1469
1470                 camerasrc->usr_buffer[proper_index] = pad_alloc_buffer;
1471
1472                 camerasrc_buffer.start = GST_BUFFER_DATA(GST_BUFFER(camerasrc->usr_buffer[proper_index]));
1473                 camerasrc_buffer.length = GST_BUFFER_SIZE(GST_BUFFER(camerasrc->usr_buffer[proper_index]));
1474
1475                 camerasrc_buffer.length = PAGE_ALIGN(camerasrc_buffer.length);
1476
1477                 if (!camerasrc_buffer.start) {
1478                         GST_ERROR_OBJECT(camerasrc, "Data for queueing is not available one, data = %p", camerasrc_buffer.start);
1479                         g_cond_signal(camerasrc->buffer_cond);
1480                         g_mutex_unlock(camerasrc->buffer_lock);
1481
1482                         return GST_FLOW_ERROR;
1483                 }
1484
1485                 if (camerasrc_buffer.length <= 0) {
1486                         GST_ERROR_OBJECT(camerasrc, "Length for queueing is not available one, data = %d", camerasrc_buffer.length);
1487                         g_cond_signal(camerasrc->buffer_cond);
1488                         g_mutex_unlock(camerasrc->buffer_lock);
1489
1490                         return GST_FLOW_ERROR;
1491                 }
1492
1493                 ret = camerasrc_queue_buffer(camerasrc->v4l2_handle, proper_index, &camerasrc_buffer);
1494                 if (ret != CAMERASRC_SUCCESS) {
1495                         GST_ERROR_OBJECT(camerasrc, "Queue frame error, [%x]", ret);
1496                         g_cond_signal(camerasrc->buffer_cond);
1497                         g_mutex_unlock(camerasrc->buffer_lock);
1498                         gst_caps_unref(negotiated_caps);
1499
1500                         return GST_FLOW_ERROR;
1501                 }
1502
1503                 gst_caps_unref(negotiated_caps);
1504
1505                 g_cond_signal(camerasrc->buffer_cond);
1506                 GST_LOG_OBJECT(camerasrc, "QBUF : [idx=%d, lvn=%d]", proper_index, camerasrc->num_live_buffers);
1507                 g_mutex_lock(camerasrc->pad_alloc_mutex);
1508         }
1509
1510         g_mutex_unlock(camerasrc->pad_alloc_mutex);
1511
1512         ret = camerasrc_wait_frame_available(camerasrc->v4l2_handle, _PAD_ALLOC_RETRY_PERIOD);
1513         if (ret == CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT) {
1514                 if (cnt_again--) {
1515                         if ((cnt_again % 100) == 0) {
1516                                 GST_LOG_OBJECT (camerasrc, "Check ESD......");
1517
1518                                 is_esd = 0;
1519                                 ret = camerasrc_check_esd_shock(camerasrc->v4l2_handle, &is_esd);
1520                                 if (is_esd) {
1521                                         /* ESD situation */
1522                                         GST_LOG_OBJECT(camerasrc, "ESD situation. device reset preview");
1523                                         GST_LOG_OBJECT(camerasrc, "register trouble error!! [%x]", CAMERASRC_ERR_DEVICE_UNAVAILABLE);
1524                                         g_mutex_unlock(camerasrc->buffer_lock);
1525
1526                                         gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_UNAVAILABLE);
1527
1528                                         return GST_FLOW_ERROR;
1529                                 }
1530                         }
1531                         goto AGAIN;
1532                 } else {
1533                         GST_LOG_OBJECT (camerasrc, "Check ESD......");
1534
1535                         is_esd = 0;
1536                         ret =  camerasrc_check_esd_shock(camerasrc->v4l2_handle, &is_esd);
1537                         if (!is_esd) {
1538                                 /* Not ESD situation */
1539                                 GST_LOG_OBJECT(camerasrc, "Not ESD situation. normal timeout");
1540                                 g_mutex_unlock(camerasrc->buffer_lock);
1541
1542                                 gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT);
1543
1544                                 return GST_FLOW_WRONG_STATE;
1545                         } else {
1546                                 /* ESD situation */
1547                                 GST_LOG_OBJECT(camerasrc, "ESD situation. device reset preview");
1548                                 GST_LOG_OBJECT(camerasrc, "register trouble error!! [%x]", CAMERASRC_ERR_DEVICE_UNAVAILABLE);
1549                                 g_mutex_unlock(camerasrc->buffer_lock);
1550
1551                                 gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_UNAVAILABLE);
1552
1553                                 return GST_FLOW_ERROR;
1554                         }
1555
1556                         GST_ERROR_OBJECT(camerasrc,  "Time out retried [%d] times %d", _MAX_PAD_ALLOC_RETRY_COUNT - cnt_again + 1);
1557                 }
1558         } else if (ret != CAMERASRC_SUCCESS) {
1559                 g_mutex_unlock(camerasrc->buffer_lock);
1560                 GST_ERROR_OBJECT(camerasrc, "camerasrc_wait_frame_available error [%x]", ret);
1561
1562                 return GST_FLOW_ERROR;
1563         }
1564
1565         /* Buffer DQ */
1566         __ta__( "            camerasrc_dequeue_buffer",
1567         ret = camerasrc_dequeue_buffer(camerasrc->v4l2_handle, &v4l2_buffer_index, &main_buf, NULL);
1568         );
1569         if (ret != CAMERASRC_SUCCESS) {
1570                 GST_ERROR_OBJECT(camerasrc, "Dequeue frame error, [%x]", ret);
1571                 g_mutex_unlock(camerasrc->buffer_lock);
1572                 gst_camerasrc_error_handler(camerasrc, ret);
1573
1574                 return GST_FLOW_ERROR;
1575         }
1576
1577         camerasrc->num_live_buffers++;
1578         GST_LOG_OBJECT(camerasrc, "after : DQBUF (index %d, live number %d)",
1579                                   v4l2_buffer_index, camerasrc->num_live_buffers);
1580         g_mutex_unlock(camerasrc->buffer_lock);
1581
1582         /* For camera state stopped */
1583         gst_buf = camerasrc->usr_buffer[v4l2_buffer_index];
1584         if (gst_buf == NULL) {
1585                 GST_ERROR_OBJECT(camerasrc, "camerasrc->usr_buffer[v4l2_buffer_index] NULL");
1586                 return GST_FLOW_WRONG_STATE;
1587         }
1588
1589         GST_LOG_OBJECT(camerasrc, "Start to set up buffer free structure");
1590
1591         buffer_data = g_malloc(sizeof(GST_CAMERASRC_BUFFER_DATA));
1592         if (buffer_data == NULL) {
1593                 GST_ERROR_OBJECT(camerasrc, "buffer_data NULL");
1594                 return GST_FLOW_WRONG_STATE;
1595         }
1596
1597         buffer_data->camerasrc = camerasrc;
1598         buffer_data->index = v4l2_buffer_index;
1599         buffer_data->buffer_data_index = camerasrc->current_buffer_data_index;
1600
1601         GST_BUFFER_DATA(gst_buf) = main_buf.start;
1602         GST_BUFFER_SIZE(gst_buf) = main_buf.length;
1603         GST_BUFFER_MALLOCDATA(gst_buf) = (guint8 *)buffer_data;
1604         GST_BUFFER_FREE_FUNC(gst_buf) = gst_camerasrc_buffer_free;
1605
1606         GST_LOG_OBJECT(camerasrc, "End to set up buffer free structure");
1607
1608
1609         if (camerasrc->firsttime) {
1610                 /* Because of basesrc negotiation , "framerate" field is needed. */
1611                 int fps_nu = 0;
1612                 int fps_de = 0;
1613                 gchar *caps_string = NULL;
1614                 GstCaps *caps = NULL;
1615
1616                 if (camerasrc->fps <= 0) {
1617                         /*if fps is zero, auto fps mode*/
1618                         fps_nu = 0;
1619                         fps_de = 1;
1620                 } else {
1621                         fps_nu = 1;
1622                         fps_de = camerasrc->fps;
1623                 }
1624
1625                 GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]",
1626                                            camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps);
1627
1628                 caps = gst_caps_new_simple("video/x-raw-yuv",
1629                                            "format", GST_TYPE_FOURCC, camerasrc->fourcc,
1630                                            "width", G_TYPE_INT, camerasrc->width,
1631                                            "height", G_TYPE_INT, camerasrc->height,
1632                                            "framerate", GST_TYPE_FRACTION, fps_de, fps_nu,
1633                                            NULL);
1634                 if (caps == NULL) {
1635                         GST_ERROR_OBJECT(camerasrc, "failed to alloc caps");
1636                         return GST_FLOW_ERROR;
1637                 }
1638
1639                 if (camerasrc->use_rotate_caps) {
1640                         gst_caps_set_simple(caps, "rotate", G_TYPE_INT, camerasrc->rotate, NULL);
1641                 }
1642
1643                 GST_BUFFER_CAPS(gst_buf) = caps;
1644
1645                 caps_string = gst_caps_to_string(caps);
1646                 GST_INFO_OBJECT (camerasrc, "PREVIEW MODE first time [%dx%d], rotate[%d], caps[%s]",
1647                                             camerasrc->width, camerasrc->height, camerasrc->rotate, caps_string);
1648                 if (caps_string) {
1649                         g_free(caps_string);
1650                         caps_string = NULL;
1651                 }
1652
1653                 camerasrc->firsttime = FALSE;
1654         }
1655
1656         gst_camerasrc_get_timeinfo(camerasrc, gst_buf);
1657
1658         *buffer = gst_buf;
1659
1660         g_mutex_lock (camerasrc->pad_alloc_mutex);
1661         if (camerasrc->first_invokation) {
1662                 GST_INFO_OBJECT(camerasrc, "[DEBUG] Check something in pad_alloc_list");
1663                 g_mutex_unlock (camerasrc->pad_alloc_mutex);
1664                 g_mutex_lock (camerasrc->pad_alloc_mutex);
1665
1666                 while (!g_queue_is_empty(camerasrc->pad_alloc_list)) {
1667                         g_mutex_unlock(camerasrc->pad_alloc_mutex);
1668                         g_mutex_lock(camerasrc->pad_alloc_mutex);
1669
1670                         /* Remove all item */
1671
1672                         g_queue_pop_head(camerasrc->pad_alloc_list);
1673                         GST_INFO_OBJECT(camerasrc, "[DEBUG] Something is in pad_alloc_list before first frame. remove it!");
1674
1675                         g_mutex_unlock(camerasrc->pad_alloc_mutex);
1676                         g_mutex_lock(camerasrc->pad_alloc_mutex);
1677                 }
1678
1679                 g_mutex_unlock(camerasrc->pad_alloc_mutex);
1680                 g_mutex_lock(camerasrc->pad_alloc_mutex);
1681                 camerasrc->first_invokation = FALSE;
1682         }
1683         g_mutex_unlock (camerasrc->pad_alloc_mutex);
1684
1685 #if _ENABLE_CAMERASRC_DEBUG
1686         g_preview_frame_cnt++;
1687 #endif
1688
1689         return GST_FLOW_OK;
1690 }
1691
1692
1693 static GstFlowReturn gst_camerasrc_draw_black_preview(GstCameraSrc *camerasrc, GstBuffer **buffer)
1694 {
1695         int fps_nu = 0;
1696         int fps_de = 0;
1697         guint fakebuflen = 0;
1698         GstBuffer *gst_buf = NULL;
1699
1700         /*alloc main buffer*/
1701         if (camerasrc->fourcc == GST_MAKE_FOURCC('Y','U','Y','2')) {
1702                 fakebuflen = camerasrc->width * camerasrc->height * 2;
1703                 gst_buf = gst_buffer_new_and_alloc(fakebuflen);
1704                 GenerateYUV422BlackFrame(GST_BUFFER_MALLOCDATA(gst_buf), fakebuflen, camerasrc->width , camerasrc->height);
1705         } else if (camerasrc->fourcc == GST_MAKE_FOURCC ('I','4','2','0') ||
1706                    camerasrc->fourcc == GST_MAKE_FOURCC ('Y', 'U', '1', '2')) {
1707                 fakebuflen = camerasrc->width * camerasrc->height * 3 / 2;
1708                 gst_buf = gst_buffer_new_and_alloc(fakebuflen);
1709                 GenerateYUV420BlackFrame(GST_BUFFER_MALLOCDATA(gst_buf), fakebuflen, camerasrc->width , camerasrc->height);
1710         } else {
1711                 GST_DEBUG_OBJECT(camerasrc, "Wrong fourcc(%x)", camerasrc->fourcc);
1712                 return GST_FLOW_OK;
1713         }
1714
1715         GST_DEBUG_OBJECT(camerasrc, "gst_camerasrc_draw_black_preview (data=%p, len=%d)",
1716                                     GST_BUFFER_MALLOCDATA(gst_buf), fakebuflen);
1717         /**
1718                 Because of basesrc negotiation , "framerate" field is needed.
1719         */
1720         if (camerasrc->fps <= 0) {
1721                 /*if fps is zero, auto fps mod e*/
1722                 fps_nu = 0;
1723                 fps_de = 1;
1724         } else {
1725                 fps_nu = 1;
1726                 fps_de = camerasrc->fps;
1727         }
1728
1729         GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]",
1730                                    camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps);
1731
1732         GST_BUFFER_CAPS(gst_buf) = gst_caps_new_simple("video/x-raw-yuv",
1733                                                        "format", GST_TYPE_FOURCC, camerasrc->fourcc,
1734                                                        "width", G_TYPE_INT, camerasrc->width,
1735                                                        "height", G_TYPE_INT, camerasrc->height,
1736                                                        "framerate", GST_TYPE_FRACTION, fps_de, fps_nu,
1737                                                        NULL);
1738
1739         GST_DEBUG_OBJECT(camerasrc, "PREVIEW MODE first time [%d] [%d]", camerasrc->width, camerasrc->height);
1740         gst_camerasrc_get_timeinfo(camerasrc, gst_buf);
1741
1742         *buffer = gst_buf;
1743         return GST_FLOW_OK;
1744 }
1745
1746
1747 static GstFlowReturn gst_camerasrc_read_capture(GstCameraSrc *camerasrc, GstBuffer **buffer, int command)
1748 {
1749         int ret;
1750         int buffer_index = 0;
1751         unsigned long cur_time;
1752         gboolean is_jpeg = FALSE;
1753
1754         static gboolean get_stop_command = FALSE;
1755         static gboolean get_stop_multi_command = FALSE;
1756
1757         GstCameraBuffer *buf = NULL;            /*output buffer for preview*/
1758         GstBuffer *buf_cap_signal1 = NULL;      /*output main buffer for capture signal*/
1759         GstBuffer *buf_cap_signal2 = NULL;      /*output thumbnail buffer for capture signal*/
1760         GstBuffer *buf_cap_signal3 = NULL;      /*output screennail buffer for capture signal*/
1761
1762         camerasrc_buffer_t main_buf = {0, NULL, 0};       /*original size buffer*/
1763         camerasrc_buffer_t thumb_buf = {0, NULL, 0};      /*thumbnail size buffer*/
1764         camerasrc_buffer_t scrnl_buf = {0, NULL, 0};      /*screennail size buffer*/
1765
1766         GST_DEBUG_OBJECT(camerasrc, "ENTERED. Command[%d]", command);
1767
1768         GST_INFO_OBJECT(camerasrc, "src size[%dx%d], capture size[%dx%d]",
1769                                    camerasrc->width, camerasrc->height,
1770                                    camerasrc->cap_width, camerasrc->cap_height );
1771
1772         if (command == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP) {
1773                 get_stop_command = TRUE;
1774         } else if (command == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP_MULTISHOT) {
1775                 get_stop_multi_command = TRUE;
1776         }
1777
1778         GST_INFO_OBJECT(camerasrc, "cnt current:%d, reverse:%d, stop cmd:%d, multi stop cmd:%d",
1779                                    camerasrc->cap_count_reverse, camerasrc->cap_count_current,
1780                                    get_stop_command, get_stop_multi_command);
1781
1782         while (TRUE) {
1783                 if (camerasrc->cap_count_reverse == 0 ||
1784                     ((get_stop_command || get_stop_multi_command) &&
1785                      camerasrc->cap_count_current != 0 )) {
1786                         g_mutex_lock(camerasrc->mutex);
1787
1788                         GST_INFO_OBJECT(camerasrc, "Capture finished.");
1789
1790                         __ta__( "        capture: gst_camerasrc_capture_stop",
1791                         gst_camerasrc_capture_stop(camerasrc);
1792                         );
1793                         if (get_stop_command == FALSE) {
1794                                 if (!g_queue_is_empty(camerasrc->command_list)) {
1795                                         command = (int)g_queue_pop_head(camerasrc->command_list);
1796                                         GST_INFO_OBJECT(camerasrc, "Pop command [%d]", command);
1797                                         if (command == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP) {
1798                                                 get_stop_command = TRUE;
1799                                         }
1800                                 }
1801
1802                                 if (get_stop_command == FALSE) {
1803                                         GST_INFO_OBJECT(camerasrc, "Start : Wait for Capture stop signal");
1804                                         __ta__( "            capture: wait for cond after image capture",
1805                                         g_cond_wait(camerasrc->cond, camerasrc->mutex);
1806                                         );
1807                                         GST_INFO_OBJECT(camerasrc, "End   : Wait for Capture stop signal");
1808                                 }
1809                         }
1810
1811                         __ta__("        capture: gst_camerasrc_start",
1812                         gst_camerasrc_start(camerasrc);
1813                         );
1814
1815                         __ta__("        capture: one gst_camerasrc_read_preview_mmap",
1816                         ret = gst_camerasrc_read_preview_mmap(camerasrc, buffer);
1817                         );
1818
1819                         get_stop_command = FALSE;
1820                         get_stop_multi_command = FALSE;
1821
1822                         g_mutex_unlock(camerasrc->mutex);
1823
1824                         MMTA_ACUM_ITEM_END( "    Shot to Shot in gstcamerasrc", FALSE);
1825
1826                         return ret;
1827                 }
1828
1829                 if (camerasrc->cap_fourcc == GST_MAKE_FOURCC('J','P','E','G') ||
1830                     camerasrc->cap_fourcc == GST_MAKE_FOURCC('j','p','e','g')) {
1831                         is_jpeg = TRUE;
1832                 } else {
1833                         is_jpeg = FALSE;
1834                 }
1835
1836                 /**
1837                  *@important JPEG still: always same image generated by camerasrc_read_frame.
1838                  *                              if you want to multi shot, set YUV format !
1839                  */
1840                 __ta__("            camerasrc_read_frame:select,DQ,Copy,Q",
1841                 ret = camerasrc_read_frame(camerasrc->v4l2_handle, &main_buf, &thumb_buf, &buffer_index);
1842                 );
1843                 if (ret != CAMERASRC_SUCCESS) {
1844                         if (ret == CAMERASRC_ERR_DEVICE_UNAVAILABLE) {
1845                                 GST_ERROR_OBJECT (camerasrc, "Video src device return register trouble error!! [%x]", ret);
1846                                 /*g_signal_emit (G_OBJECT (camerasrc), gst_camerasrc_signals[SIGNAL_REGISTER_TROUBLE], (GQuark)NULL);*/
1847                                 gst_camerasrc_error_handler(camerasrc, ret);
1848                                 return GST_FLOW_ERROR;
1849                         } else {
1850                                 GST_ERROR_OBJECT (camerasrc, "camerasrc_read_frame() failed. [ret = 0x%08X]", ret);
1851                                 GST_ERROR_OBJECT (camerasrc, "return GST_FLOW_ERROR");
1852                                 /* should stop capture; */
1853                                 /*retrun EOS*/
1854                                 *buffer = NULL;
1855                                 gst_camerasrc_error_handler(camerasrc, ret);
1856
1857                                 return GST_FLOW_ERROR;
1858                         }
1859                 }
1860
1861                 /* Get screennail buffer */
1862                 scrnl_buf.start = NULL;
1863                 scrnl_buf.length = 0;
1864                 camerasrc_get_screennail_buffer(camerasrc->v4l2_handle, &scrnl_buf);
1865
1866                 GST_INFO_OBJECT(camerasrc, "main(%p,%d), thumb(%p,%d), scrnl(%p,%d)",
1867                                            main_buf.start, main_buf.length,
1868                                            thumb_buf.start, thumb_buf.length,
1869                                            scrnl_buf.start, scrnl_buf.length);
1870
1871 CHECK_CAPTURE_INTERVAL:
1872                 /* get shot time */
1873                 cur_time = gst_get_current_time();
1874
1875                 if (camerasrc->cap_next_time == 0UL) {
1876                         camerasrc->cap_next_time = cur_time;
1877                 }
1878
1879                 if (camerasrc->cap_count_reverse > 0 && camerasrc->cap_next_time <= cur_time) {
1880                         GST_INFO_OBJECT(camerasrc, "CHECK: reverse capture count: %d, next time:%lu current time:%lu",
1881                                                    camerasrc->cap_count_reverse, camerasrc->cap_next_time, cur_time);
1882
1883                         camerasrc->cap_next_time = cur_time + camerasrc->cap_interval;
1884                         camerasrc->cap_count_reverse--;
1885                         camerasrc->cap_count_current++;
1886
1887                         /* alloc buffer for capture callback */
1888                         buf_cap_signal1 = gst_buffer_new ();
1889
1890                         /* make buffers for capture callback and display(raw format) */
1891                         if (is_jpeg) {
1892                                 GST_INFO_OBJECT (camerasrc, "JPEG CAPTURE MODE");
1893
1894                                 GST_BUFFER_DATA(buf_cap_signal1) = main_buf.start;
1895                                 GST_BUFFER_SIZE(buf_cap_signal1) = main_buf.length;
1896                                 GST_BUFFER_CAPS(buf_cap_signal1) = gst_caps_new_simple("image/jpeg",
1897                                                                    "width", G_TYPE_INT, camerasrc->cap_width,
1898                                                                    "height", G_TYPE_INT, camerasrc->cap_height,
1899                                                                    NULL);
1900
1901                                 if (thumb_buf.start) {
1902                                         buf_cap_signal2 = gst_buffer_new();
1903                                         GST_BUFFER_DATA(buf_cap_signal2) = thumb_buf.start;
1904                                         GST_BUFFER_SIZE(buf_cap_signal2) = thumb_buf.length;
1905                                         GST_BUFFER_CAPS(buf_cap_signal2) = gst_caps_new_simple("image/jpeg",
1906                                                                            "width", G_TYPE_INT, _THUMBNAIL_WIDTH,
1907                                                                            "height", G_TYPE_INT, _THUMBNAIL_HEIGHT,
1908                                                                            NULL);
1909                                 } else {
1910                                         buf_cap_signal2 = NULL;
1911                                 }
1912
1913                                 if (scrnl_buf.start && scrnl_buf.length > 0) {
1914                                         buf_cap_signal3 = gst_buffer_new();
1915                                         GST_BUFFER_DATA(buf_cap_signal3) = scrnl_buf.start;
1916                                         GST_BUFFER_SIZE(buf_cap_signal3) = scrnl_buf.length;
1917                                         GST_BUFFER_CAPS(buf_cap_signal3) = gst_caps_new_simple("video/x-raw-yuv",
1918                                                                            "format", GST_TYPE_FOURCC, _DEFAULT_SCRNL_FOURCC,
1919                                                                            "width", G_TYPE_INT, camerasrc->width,
1920                                                                            "height", G_TYPE_INT, camerasrc->height,
1921                                                                            NULL);
1922                                 } else {
1923                                         buf_cap_signal3 = NULL;
1924                                 }
1925
1926                                 *buffer = NULL;
1927                         } else {
1928                                 unsigned char *pMetaData = NULL;
1929
1930                                 GST_INFO_OBJECT (camerasrc, "RAW CAPTURE MODE");
1931
1932                                 /*alloc main buffer*/
1933                                 buf = gst_camerasrc_buffer_new(camerasrc);;
1934                                 if (buf == NULL) {
1935                                         GST_ERROR_OBJECT(camerasrc, "Buffer alloc failed.");
1936                                         *buffer = NULL;
1937                                         gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_ALLOCATION);
1938                                         return GST_FLOW_ERROR;
1939                                 }
1940
1941                                 pMetaData = gst_camerasrc_make_metadata_for_nonlinear_buffer(camerasrc, buffer_index);
1942                                 if (!pMetaData) {
1943                                         GST_ERROR_OBJECT(camerasrc, "Error on making metadata");
1944                                 }
1945
1946                                 GST_BUFFER_MALLOCDATA(buf) = pMetaData;
1947                                 buf->v4l2_buffer_index = buffer_index;
1948
1949                                 if (camerasrc->cap_fourcc == GST_MAKE_FOURCC('I','4','2','0') ||
1950                                     camerasrc->cap_fourcc == GST_MAKE_FOURCC('S','4','2','0') ||
1951                                     camerasrc->cap_fourcc == GST_MAKE_FOURCC('N','V','1','2') ||
1952                                     camerasrc->cap_fourcc == GST_MAKE_FOURCC('S','N','1','2')) {
1953                                         ret = _gst_camerasrc_get_normal_buffer(camerasrc, camerasrc->cap_fourcc,
1954                                                                                main_buf.start, camerasrc->cap_width, camerasrc->cap_height,
1955                                                                                &GST_BUFFER_DATA(buf), &GST_BUFFER_SIZE(buf));
1956                                         if (ret == FALSE) {
1957                                                 g_mutex_unlock( camerasrc->buffer_lock );
1958                                                 return GST_FLOW_ERROR;
1959                                         }
1960
1961                                         buf->is_alloc_data = TRUE;
1962                                 } else {
1963                                         GST_BUFFER_DATA(buf) = main_buf.start;
1964                                         GST_BUFFER_SIZE(buf) = main_buf.length;
1965                                 }
1966
1967                                 *buffer = (GstBuffer *)buf;
1968                                 GST_INFO_OBJECT(camerasrc, "BUF for PREVIEW: addr %p size %d",
1969                                                            GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
1970
1971                                 GST_BUFFER_DATA(buf_cap_signal1) = GST_BUFFER_DATA(buf);
1972                                 GST_BUFFER_SIZE(buf_cap_signal1) = GST_BUFFER_SIZE(buf);
1973                                 GST_BUFFER_CAPS(buf_cap_signal1) = gst_caps_new_simple("video/x-raw-yuv",
1974                                                                    "format", GST_TYPE_FOURCC, camerasrc->cap_fourcc,
1975                                                                    "width", G_TYPE_INT, camerasrc->cap_width,
1976                                                                    "height", G_TYPE_INT, camerasrc->cap_height,
1977                                                                    NULL);
1978                                 buf_cap_signal2 = NULL;
1979                                 buf_cap_signal3 = NULL;
1980                         }
1981
1982                         /*call signal*/
1983                         GST_INFO_OBJECT (camerasrc, "CALL: capture callback");
1984
1985                         g_signal_emit( G_OBJECT (camerasrc),
1986                                        gst_camerasrc_signals[SIGNAL_STILL_CAPTURE],
1987                                        0,
1988                                        buf_cap_signal1,
1989                                        buf_cap_signal2,
1990                                        buf_cap_signal3 );
1991
1992                         GST_INFO_OBJECT (camerasrc, "RETURN: capture callback");
1993
1994                         if (is_jpeg ||
1995                             (!is_jpeg && (camerasrc->fourcc != camerasrc->cap_fourcc ||
1996                                           camerasrc->width != camerasrc->cap_width ||
1997                                           camerasrc->height != camerasrc->cap_height))) {
1998                                 /* Queue buffer */
1999                                 camerasrc_queue_buffer(camerasrc->v4l2_handle, buffer_index, &main_buf);
2000
2001                                 /* release buffer */
2002                                 if (*buffer) {
2003                                         gst_buffer_unref(*buffer);
2004                                         *buffer = NULL;
2005                                 }
2006                         } else {
2007                                 camerasrc->num_live_buffers++;
2008                                 /*escape loop for passing buffer to videosink*/
2009                                 break;
2010                         }
2011                 } else {
2012                         if (camerasrc->cap_next_time < cur_time + _CONTINUOUS_SHOT_MARGIN) {
2013                                 GST_DEBUG_OBJECT(camerasrc, "check again time");
2014                                 usleep((camerasrc->cap_next_time - cur_time) * 1000);
2015                                 goto CHECK_CAPTURE_INTERVAL;
2016                         }
2017
2018                         /* RAW capture buffer should be reach here */
2019                         camerasrc_queue_buffer(camerasrc->v4l2_handle, buffer_index, &main_buf);
2020
2021                         /* Skip passing this buffer */
2022                         *buffer = NULL;
2023
2024                         GST_DEBUG_OBJECT(camerasrc, "Skip pssing this buffer");
2025                         break;
2026                 }
2027         }
2028
2029         GST_DEBUG_OBJECT (camerasrc, "LEAVED");
2030
2031         return GST_FLOW_OK;
2032 }
2033
2034
2035 static GstFlowReturn gst_camerasrc_read(GstCameraSrc *camerasrc, GstBuffer **buffer)
2036 {
2037         int err = 0;
2038         int command = GST_CAMERA_CONTROL_CAPTURE_COMMAND_NONE;
2039         GstFlowReturn ret = GST_FLOW_OK;
2040         camerasrc_state_t state = CAMERASRC_STATE_NONE;
2041
2042         g_mutex_lock(camerasrc->mutex);
2043
2044         if (!g_queue_is_empty(camerasrc->command_list)) {
2045                 command = (int)g_queue_pop_head(camerasrc->command_list);
2046                 GST_INFO_OBJECT(camerasrc, "popped cmd : %d", command);
2047         }
2048
2049         /* Normal Capture Routine */
2050         if (command == GST_CAMERA_CONTROL_CAPTURE_COMMAND_START) {
2051                 MMTA_ACUM_ITEM_BEGIN("    Shot to Shot in gstcamerasrc", FALSE);
2052                 __ta__("        gst_camerasrc_capture_start",
2053                 gst_camerasrc_capture_start(camerasrc);
2054                 );
2055         }
2056
2057         g_mutex_unlock(camerasrc->mutex);
2058
2059         switch (camerasrc->mode) {
2060         case VIDEO_IN_MODE_PREVIEW:
2061         case VIDEO_IN_MODE_VIDEO:
2062                 if (camerasrc->use_pad_alloc == TRUE) {
2063                         err = camerasrc_get_state(camerasrc->v4l2_handle, &state);
2064
2065                         if (state == CAMERASRC_STATE_READY) {
2066                                 GST_INFO_OBJECT (camerasrc,"Prepare buffer");
2067                                 ret = gst_camerasrc_prepare_preview(camerasrc, camerasrc->num_alloc_buf);
2068                         }
2069                 }
2070
2071                 if (camerasrc->use_pad_alloc == TRUE) {
2072                         __ta__("            gst_camerasrc_read_preview_pad_alloc",
2073                         ret = gst_camerasrc_read_preview_pad_alloc(camerasrc, buffer);
2074                         );
2075                 } else {
2076                         __ta__("            gst_camerasrc_read_preview_mmap",
2077                         ret = gst_camerasrc_read_preview_mmap(camerasrc, buffer);
2078                         )
2079                 }
2080                 break;
2081         case VIDEO_IN_MODE_CAPTURE:
2082                 __ta__( "        gst_camerasrc_read_capture",
2083                 ret = gst_camerasrc_read_capture(camerasrc, buffer, command);
2084                 );
2085                 break;
2086         case VIDEO_IN_MODE_UNKNOWN:
2087         default:
2088                 ret = GST_FLOW_ERROR;
2089                 GST_ERROR_OBJECT (camerasrc, "can't reach statement.[camerasrc->mode=%d]", camerasrc->mode);
2090                 break;
2091         }
2092
2093         if (!buffer || !(*buffer) || !GST_IS_BUFFER(*buffer)) {
2094                 /* To avoid seg fault, make dummy buffer. */
2095                 GST_WARNING_OBJECT (camerasrc, "Make a dummy buffer");
2096                 *buffer = gst_buffer_new();
2097                 GST_BUFFER_DATA(*buffer) = NULL;
2098                 GST_BUFFER_SIZE(*buffer) = 0;
2099         }
2100
2101         return ret;
2102 }
2103
2104
2105 /* Buffer related functions */
2106 static void gst_camerasrc_buffer_pad_alloc_qbuf(GstCameraBuffer *buffer)
2107 {
2108         int ret = 0;
2109         gint index = 0;
2110         GstCaps *negotiated_caps = NULL;
2111         GstBuffer *queue_buf = NULL;
2112         GstCameraSrc *camerasrc = NULL;
2113         camerasrc_buffer_t camerasrc_buffer;
2114
2115         if (buffer) {
2116                 camerasrc = buffer->camerasrc;
2117         } else {
2118                 GST_ERROR("buffer is NULL");
2119                 return;
2120         }
2121
2122         if (camerasrc) {
2123                 negotiated_caps = gst_pad_get_negotiated_caps(GST_BASE_SRC_PAD(camerasrc));
2124         } else {
2125                 GST_ERROR("camerasrc is NULL");
2126                 return;
2127         }
2128
2129         index = buffer->v4l2_buffer_index;
2130
2131         GST_LOG_OBJECT(camerasrc, "pad alloc qbuf");
2132
2133         ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD (camerasrc),
2134                                    0,
2135                                    camerasrc->main_buf_sz,
2136                                    negotiated_caps,
2137                                    &queue_buf);
2138         if (!GST_IS_BUFFER(queue_buf)) {
2139                 GST_INFO_OBJECT (camerasrc, "[DEBUG] NOT BUFFER!!?");
2140         }
2141
2142         if (ret != GST_FLOW_OK) {
2143                 GST_ERROR_OBJECT(camerasrc, "gst_pad_alloc_buffer failed. [%d]", ret);
2144                 return;
2145         } else {
2146                 GST_LOG_OBJECT(camerasrc, "Alloced Size = %dAlloced address : %p",
2147                                           GST_BUFFER_SIZE(GST_BUFFER(queue_buf)), GST_BUFFER_DATA(GST_BUFFER(queue_buf)));
2148         }
2149
2150         gst_caps_unref(negotiated_caps);
2151         negotiated_caps = NULL;
2152
2153         camerasrc_buffer.start = GST_BUFFER_DATA(GST_BUFFER(queue_buf));
2154         camerasrc_buffer.length = GST_BUFFER_SIZE(GST_BUFFER(queue_buf));
2155         ret = camerasrc_queue_buffer(camerasrc->v4l2_handle, index, &camerasrc_buffer);
2156         if (ret != CAMERASRC_SUCCESS) {
2157                 GST_ERROR_OBJECT(camerasrc, "QBUF error, [%x]", ret);
2158                 return;
2159         } else {
2160                 GST_LOG_OBJECT (camerasrc, "QBUF : [idx=%d]", index);
2161         }
2162
2163         return;
2164 }
2165
2166
2167 static void gst_camerasrc_buffer_mmap_qbuf(GstCameraBuffer *buffer)
2168 {
2169         int ret = 0;
2170         gint index = 0;
2171         GstCameraSrc *camerasrc = NULL;
2172         camerasrc_buffer_t camerasrc_buffer;
2173
2174         camerasrc = buffer->camerasrc;
2175         index = buffer->v4l2_buffer_index;
2176
2177         ret = camerasrc_queue_buffer(camerasrc->v4l2_handle, index, &camerasrc_buffer);
2178         if (ret != CAMERASRC_SUCCESS) {
2179                 GST_ERROR_OBJECT(camerasrc, "QBUF error, [%x]", ret);
2180         } else {
2181                 GST_LOG_OBJECT(camerasrc, "QBUF : [idx=%d]", index);
2182         }
2183
2184         return;
2185 }
2186
2187 static void gst_camerasrc_buffer_finalize(GstCameraBuffer *buffer)
2188 {
2189         gint index = 0;
2190         GstCameraSrc *camerasrc = NULL;
2191
2192         camerasrc = buffer->camerasrc;
2193         index = buffer->v4l2_buffer_index;
2194
2195         GST_LOG_OBJECT(camerasrc, "finalizing buffer %p, %d [%"
2196                        GST_TIME_FORMAT " dur %" GST_TIME_FORMAT "]", buffer, index,
2197                        GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
2198                        GST_TIME_ARGS(GST_BUFFER_DURATION(buffer)));
2199
2200         if (camerasrc->buffer_running) {
2201                 /* Buffer Q again */
2202                 if (camerasrc->use_pad_alloc == TRUE){
2203                         gst_camerasrc_buffer_pad_alloc_qbuf(buffer);
2204                 } else {
2205                         gst_camerasrc_buffer_mmap_qbuf(buffer);
2206                 }
2207         } else {
2208                 GST_INFO_OBJECT(camerasrc, "It is not running. skip QBUF");
2209         }
2210
2211         camerasrc->num_live_buffers--;
2212         g_cond_signal(camerasrc->buffer_cond);
2213         GST_LOG_OBJECT(camerasrc, "QBUF : [idx=%d, lvn=%d]", index, camerasrc->num_live_buffers);
2214
2215         if (buffer->is_alloc_data) {
2216                 GST_DEBUG("free allocated data %p", GST_BUFFER_DATA(buffer));
2217                 if (GST_BUFFER_DATA(buffer)) {
2218                         free(GST_BUFFER_DATA(buffer));
2219                         GST_BUFFER_DATA(buffer) = NULL;
2220                 }
2221
2222                 buffer->is_alloc_data = FALSE;
2223         }
2224
2225         if (GST_BUFFER_MALLOCDATA(buffer)) {
2226                 free(GST_BUFFER_MALLOCDATA(buffer));
2227                 GST_BUFFER_MALLOCDATA(buffer) = NULL;
2228         }
2229
2230         gst_object_unref(camerasrc);
2231
2232         if (GST_MINI_OBJECT_CLASS (camera_buffer_parent_class)->finalize) {
2233                 GST_MINI_OBJECT_CLASS (camera_buffer_parent_class)->finalize (GST_MINI_OBJECT(buffer));
2234         }
2235
2236         return;
2237 }
2238
2239
2240 static void gst_camerasrc_buffer_class_init(gpointer g_class, gpointer class_data)
2241 {
2242         GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS(g_class);
2243
2244         camera_buffer_parent_class = g_type_class_peek_parent(g_class);
2245         mini_object_class->finalize = (GstMiniObjectFinalizeFunction)gst_camerasrc_buffer_finalize;
2246 }
2247
2248
2249 static GType gst_camerasrc_buffer_get_type(void)
2250 {
2251         static GType _gst_camerasrc_buffer_type;
2252
2253         if (G_UNLIKELY(_gst_camerasrc_buffer_type == 0)) {
2254                 static const GTypeInfo camera_buffer_info = {
2255                         sizeof (GstBufferClass),
2256                         NULL,
2257                         NULL,
2258                         gst_camerasrc_buffer_class_init,
2259                         NULL,
2260                         NULL,
2261                         sizeof (GstCameraBuffer),
2262                         0,
2263                         NULL,
2264                         NULL
2265                 };
2266
2267                 _gst_camerasrc_buffer_type = g_type_register_static(GST_TYPE_BUFFER,
2268                                                                     "GstCameraBuffer",
2269                                                                     &camera_buffer_info, 0);
2270         }
2271
2272         return _gst_camerasrc_buffer_type;
2273 }
2274
2275
2276 static GstCameraBuffer *gst_camerasrc_buffer_new(GstCameraSrc *camerasrc)
2277 {
2278         GstCameraBuffer *ret = NULL;
2279
2280         ret = (GstCameraBuffer *)gst_mini_object_new(GST_TYPE_CAMERASRC_BUFFER);
2281
2282         GST_LOG_OBJECT(camerasrc, "creating buffer : %p", ret);
2283
2284         ret->camerasrc = gst_object_ref(GST_OBJECT(camerasrc));
2285         ret->is_alloc_data = FALSE;
2286
2287         return ret;
2288 }
2289
2290
2291 static void gst_camerasrc_buffer_free(gpointer data)
2292 {
2293         GST_CAMERASRC_BUFFER_DATA *buffer_data = (GST_CAMERASRC_BUFFER_DATA *)data;
2294
2295         GST_LOG_OBJECT(buffer_data->camerasrc, "freeing buffer with %p %d",
2296                                                buffer_data->camerasrc, buffer_data->index);
2297
2298         g_mutex_lock(buffer_data->camerasrc->pad_alloc_mutex);
2299
2300         if (buffer_data->buffer_data_index == buffer_data->camerasrc->current_buffer_data_index) {
2301                 GST_LOG_OBJECT(buffer_data->camerasrc, "Push index [%d] to pad_alloc_list", buffer_data->index);
2302                 g_queue_push_tail(buffer_data->camerasrc->pad_alloc_list, (gpointer)buffer_data->index);
2303         } else {
2304                 GST_WARNING_OBJECT(buffer_data->camerasrc, "Skip Pushing index [%d] to pad_alloc_list.", buffer_data->index );
2305                 GST_WARNING_OBJECT(buffer_data->camerasrc, "buffer_data_index [%d], current_buffer_data_index [%d]",
2306                                                            buffer_data->buffer_data_index,
2307                                                            buffer_data->camerasrc->current_buffer_data_index);
2308         }
2309
2310         buffer_data->camerasrc->num_live_buffers--;
2311
2312         g_mutex_unlock(buffer_data->camerasrc->pad_alloc_mutex);
2313         g_cond_signal(buffer_data->camerasrc->buffer_cond);
2314
2315         buffer_data->camerasrc = NULL;
2316         buffer_data->index = -1;
2317
2318         /* Free data argument */
2319         g_free(data);
2320
2321         return;
2322 }
2323
2324
2325 static void gst_camerasrc_buffer_trace(GstCameraSrc *camerasrc)
2326 {
2327         int i = 0;
2328         GstBuffer *buf = NULL;
2329
2330         if (!camerasrc) {
2331                 GST_ERROR_OBJECT(camerasrc, "Element is NULL");
2332                 return;
2333         }
2334
2335         for (i = 0 ; i < camerasrc->num_alloc_buf ; i ++) {
2336                 buf = camerasrc->usr_buffer[i];
2337                 if (GST_IS_BUFFER(buf)) {
2338                         GST_ELEMENT_WARNING(camerasrc, RESOURCE, FAILED,
2339                                             NULL, (("Chainfunc of buf[%d]=%s()"), i,
2340                                             GST_DEBUG_FUNCPTR_NAME(buf->_gst_reserved[0])));
2341                 } else {
2342                         GST_ELEMENT_WARNING(camerasrc, RESOURCE, FAILED,
2343                                             NULL, (("buf[%d] is not GstBuffer"), i));
2344                 }
2345         }
2346
2347         return;
2348 }
2349
2350
2351 static unsigned char *gst_camerasrc_make_metadata_for_nonlinear_buffer(GstCameraSrc *camerasrc, guint32 index)
2352 {
2353         unsigned char *meta_string = NULL;
2354         camerasrc_frame_data_t data;
2355         SCMN_IMGB *psimgb = NULL;
2356
2357         /*GST_LOG_OBJECT (camerasrc, "index[%d],pix_format[%x]", index, camerasrc->fourcc);*/
2358
2359         psimgb = (SCMN_IMGB *)malloc(sizeof(SCMN_IMGB));
2360         if (psimgb == NULL) {
2361                 GST_ERROR_OBJECT(camerasrc, "failed to alloc SCMN_IMGB");
2362                 return NULL;
2363         }
2364
2365         memset(psimgb, 0x00, sizeof(SCMN_IMGB));
2366
2367         data.index = index;
2368         camerasrc_get_frame_data(camerasrc->v4l2_handle, &data);
2369
2370         psimgb->p[0] = (void *)data.phyAddrY;
2371         psimgb->a[0] = (void *)data.virAddrY;
2372         psimgb->p[1] = (void *)data.phyAddrCbCr;
2373         psimgb->a[1] = (void *)data.virAddrCbCr;
2374
2375         psimgb->w[0] = camerasrc->width;
2376         psimgb->h[0] = camerasrc->height;
2377
2378         if (camerasrc->fourcc == GST_MAKE_FOURCC('S','T','1','2')) {
2379                 psimgb->cs = SCMN_CS_NV12;
2380                 psimgb->w[1] = camerasrc->width;
2381                 psimgb->h[1] = camerasrc->height >> 1;
2382
2383                 psimgb->s[0] = GST_ROUND_UP_16(psimgb->w[0]);
2384                 psimgb->e[0] = GST_ROUND_UP_16(psimgb->h[0]);
2385                 psimgb->s[1] = GST_ROUND_UP_16(psimgb->w[1]);
2386                 psimgb->e[1] = GST_ROUND_UP_16(psimgb->h[1]);
2387         } else {
2388                 if (camerasrc->fourcc == GST_MAKE_FOURCC('S','N','1','2')) {
2389                         psimgb->cs = SCMN_CS_NV12_T64X32;
2390                         psimgb->w[1] = camerasrc->width;
2391                         psimgb->h[1] = camerasrc->height >> 1;
2392                 } else if (camerasrc->fourcc == GST_MAKE_FOURCC('S','U','Y','V')) {
2393                         psimgb->cs = SCMN_CS_YUYV;
2394                 } else if (camerasrc->fourcc == GST_MAKE_FOURCC('S','U','Y','2')) {
2395                         psimgb->cs = SCMN_CS_YUY2;
2396                 } else if (camerasrc->fourcc == GST_MAKE_FOURCC('S','Y','V','Y')) {
2397                         psimgb->cs = SCMN_CS_UYVY;
2398                 } else if (camerasrc->fourcc == GST_MAKE_FOURCC('S','4','2','0')) {
2399                         guint offset = 0;
2400
2401                         psimgb->cs = SCMN_CS_I420;
2402                         offset = CAMERASRC_ALIGN(camerasrc->width * camerasrc->height >> 2, ALIGN_SIZE_I420);
2403                         psimgb->p[2] = (void *)(data.phyAddrCbCr + offset);
2404                         psimgb->a[2] = (void *)(data.virAddrCbCr + offset);
2405
2406                         psimgb->w[1] = psimgb->w[2] = camerasrc->width;
2407                         psimgb->h[1] = psimgb->h[2] = camerasrc->height >> 2;
2408                 } else {
2409                         GST_WARNING_OBJECT (camerasrc, "Unknown pixel format.");
2410                 }
2411
2412                 psimgb->s[0] = psimgb->w[0];
2413                 psimgb->e[0] = psimgb->h[0];
2414                 psimgb->s[1] = psimgb->w[1];
2415                 psimgb->e[1] = psimgb->h[1];
2416                 psimgb->s[2] = psimgb->w[2];
2417                 psimgb->e[2] = psimgb->h[2];
2418         }
2419
2420         /*GST_LOG_OBJECT(camerasrc, "index[%d],Plane0[%p],Plane1[%p],Plane2[%p]",
2421                                   index, psimgb->p[0], psimgb->p[1], psimgb->p[2]);*/
2422         meta_string = (unsigned char*)psimgb;
2423
2424         return meta_string;
2425 }
2426
2427
2428 static gboolean gst_camerasrc_device_is_open(GstCameraSrc *camerasrc)
2429 {
2430         return camerasrc_device_is_open((camsrc_handle_t)camerasrc->v4l2_handle);
2431 }
2432
2433
2434 static gboolean gst_camerasrc_get_timeinfo(GstCameraSrc *camerasrc, GstBuffer  *buffer)
2435 {
2436         int fps_nu = 0;
2437         int fps_de = 0;
2438         GstClock *clock = NULL;
2439         GstClockTime timestamp = GST_CLOCK_TIME_NONE;
2440         GstClockTime duration = GST_CLOCK_TIME_NONE;
2441
2442         if (!camerasrc || !buffer) {
2443                 GST_WARNING_OBJECT (camerasrc, "Invalid pointer [hadle:%p, buffer:%p]", camerasrc, buffer);
2444                 return FALSE;
2445         }
2446
2447         /* timestamps, LOCK to get clock and base time. */
2448         clock = GST_ELEMENT_CLOCK(camerasrc);
2449         if (clock) {
2450                 /* the time now is the time of the clock minus the base time */
2451                 gst_object_ref(clock);
2452                 timestamp = gst_clock_get_time(clock) - GST_ELEMENT(camerasrc)->base_time;
2453                 gst_object_unref(clock);
2454
2455                 /* if we have a framerate adjust timestamp for frame latency */
2456                 if (camerasrc->fps_auto) {
2457                         /*if fps is zero, auto fps mode*/
2458                         duration = GST_CLOCK_TIME_NONE;
2459                 } else {
2460                         if (camerasrc->fps <= 0) {
2461                                 /*if fps is zero, auto fps mode*/
2462                                 fps_nu = 0;
2463                                 fps_de = 1;
2464                         } else {
2465                                 fps_nu = 1;
2466                                 fps_de = camerasrc->fps;
2467                         }
2468
2469                         if (fps_nu > 0 && fps_de > 0) {
2470                                 GstClockTime latency;
2471
2472                                 latency = gst_util_uint64_scale_int(GST_SECOND, fps_nu, fps_de);
2473                                 duration = latency;
2474                         }
2475                 }
2476         } else {
2477                 /* no clock, can't set timestamps */
2478                 timestamp = GST_CLOCK_TIME_NONE;
2479         }
2480
2481         GST_BUFFER_TIMESTAMP(buffer) = timestamp;
2482         GST_BUFFER_DURATION(buffer) = duration;
2483 /*
2484         GST_INFO_OBJECT(camerasrc, "[%"GST_TIME_FORMAT" dur %" GST_TIME_FORMAT "]",
2485                                    GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
2486                                    GST_TIME_ARGS(GST_BUFFER_DURATION(buffer)));
2487 */
2488
2489         return TRUE;
2490 }
2491
2492
2493 static int get_proper_index(GstCameraSrc *camerasrc, GstBuffer *pad_alloc_buffer)
2494 {
2495         int temp_idx = 0;
2496
2497         while (GST_BUFFER_DATA(GST_BUFFER(pad_alloc_buffer)) != g_present_buf.present_buffer[temp_idx++].start) {
2498                 if (temp_idx >= camerasrc->num_alloc_buf) {
2499                         return -1;
2500                 }
2501         }
2502
2503         return temp_idx - 1; /* -1 is caused that it already increased in ++ */
2504 }
2505
2506
2507 /* Gstreamer general functions */
2508 static gboolean gst_camerasrc_src_start(GstBaseSrc *src)
2509 {
2510         int ret = TRUE;
2511         GstCameraSrc *camerasrc = GST_CAMERA_SRC (src);
2512
2513         GST_DEBUG_OBJECT(camerasrc, "ENTERED");
2514
2515 #if _ENABLE_CAMERASRC_DEBUG
2516         g_preview_frame_cnt = 0;
2517 #endif
2518
2519         camerasrc->firsttime = TRUE;
2520         /* 'gst_camerasrc_set_caps' will call gst_camerasrc_start(). So skip to call it. */
2521         /*ret = gst_camerasrc_start(camerasrc);*/
2522
2523         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
2524
2525         return ret;
2526 }
2527
2528
2529 static gboolean gst_camerasrc_src_stop(GstBaseSrc *src)
2530 {
2531         int ret = 0;
2532         GstCameraSrc *camerasrc = GST_CAMERA_SRC(src);
2533
2534         GST_DEBUG_OBJECT (camerasrc, "ENTERED");
2535
2536         ret = gst_camerasrc_stop(camerasrc);
2537
2538         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
2539
2540         return TRUE;
2541 }
2542
2543
2544 static GstFlowReturn gst_camerasrc_src_create(GstPushSrc *src, GstBuffer **buffer)
2545 {
2546         GstCameraSrc *camerasrc = GST_CAMERA_SRC (src);
2547         GstFlowReturn ret;
2548
2549         /*GST_DEBUG_OBJECT(camerasrc, "ENTERED");*/
2550
2551         if (camerasrc->req_negotiation) {
2552                 GST_INFO_OBJECT(camerasrc, "negotiation start");
2553
2554                 GST_BASE_SRC_GET_CLASS(camerasrc)->negotiate(GST_BASE_SRC(camerasrc));
2555                 camerasrc->req_negotiation = FALSE;
2556                 g_signal_emit(G_OBJECT(camerasrc), gst_camerasrc_signals[SIGNAL_NEGO_COMPLETE], (GQuark)NULL);
2557
2558                 GST_INFO_OBJECT (camerasrc, "negotiation stop");
2559         }
2560
2561         __ta__("            gst_camerasrc_read",  
2562         ret = gst_camerasrc_read(camerasrc, buffer);
2563         )
2564         /*GST_DEBUG_OBJECT (camerasrc, "LEAVED");*/
2565
2566         return ret;
2567 }
2568
2569
2570 static void gst_camerasrc_set_property(GObject *object, guint prop_id,
2571                                        const GValue *value, GParamSpec *pspec)
2572 {
2573         int tmp = 0;
2574         GstCameraSrc *camerasrc = NULL;
2575
2576         g_return_if_fail(GST_IS_CAMERA_SRC(object));
2577         camerasrc = GST_CAMERA_SRC(object);
2578
2579         switch (prop_id) {
2580         case ARG_REQ_NEGOTIATION:
2581                 camerasrc->req_negotiation = g_value_get_boolean(value);
2582                 break;
2583         case ARG_CAMERA_HIGH_SPEED_FPS:
2584                 tmp = g_value_get_int(value);
2585                 camerasrc->high_speed_fps = tmp;
2586                 break;
2587         case ARG_CAMERA_AUTO_FPS:
2588                 camerasrc->fps_auto = g_value_get_boolean(value);
2589                 GST_DEBUG_OBJECT(camerasrc, "Set AUTO_FPS:%d", camerasrc->fps_auto);
2590                 break;
2591         case ARG_CAMERA_ID:
2592                 camerasrc->camera_id = g_value_get_int(value);
2593                 break;
2594         case ARG_CAMERA_EXT_VIDEO_FD:
2595                 camerasrc->external_videofd = g_value_get_int(value);
2596                 break;
2597         case ARG_CAMERA_CAPTURE_FOURCC:
2598                 camerasrc->cap_fourcc = g_value_get_uint(value);
2599                 break;
2600         case ARG_CAMERA_CAPTURE_QUALITY:
2601                 camerasrc->cap_quality = g_value_get_enum(value);
2602                 break;
2603         case ARG_CAMERA_CAPTURE_WIDTH:
2604                 camerasrc->cap_width = g_value_get_int(value);
2605                 break;
2606         case ARG_CAMERA_CAPTURE_HEIGHT:
2607                 camerasrc->cap_height = g_value_get_int(value);
2608                 break;
2609         case ARG_CAMERA_CAPTURE_INTERVAL:
2610                 camerasrc->cap_interval = g_value_get_int(value);
2611                 break;
2612         case ARG_CAMERA_CAPTURE_COUNT:
2613                 tmp = g_value_get_int(value);
2614                 camerasrc->cap_count = tmp;
2615                 g_mutex_lock(camerasrc->jpg_mutex);
2616                 camerasrc->cap_count_reverse = tmp;
2617                 g_mutex_unlock(camerasrc->jpg_mutex);
2618                 GST_INFO("SET reverse capture count: %d", camerasrc->cap_count_reverse);
2619                 break;
2620         case ARG_CAMERA_CAPTURE_JPG_QUALITY:
2621                 camerasrc->cap_jpg_quality = g_value_get_int(value);
2622                 GST_INFO("SET jpeg compress ratio : %d", camerasrc->cap_jpg_quality);
2623                 break;
2624         case ARG_SIGNAL_STILLCAPTURE:
2625                 camerasrc->signal_still_capture = g_value_get_boolean(value);
2626                 break;
2627         case ARG_USE_PAD_ALLOC:
2628                 camerasrc->use_pad_alloc = g_value_get_boolean(value);
2629                 break;
2630         case ARG_NUM_ALLOC_BUF:
2631                 camerasrc->num_alloc_buf = g_value_get_int(value);
2632                 break;
2633         case ARG_HOLD_AF_AFTER_CAPTURE:
2634                 camerasrc->hold_af_after_capturing = g_value_get_boolean(value);
2635                 camerasrc_set_af_hold_after_capture(camerasrc->v4l2_handle, (int)camerasrc->hold_af_after_capturing);
2636                 break;
2637         case ARG_SENSOR_MODE:
2638                 camerasrc->sensor_mode = g_value_get_int(value);
2639                 break;
2640         case ARG_VFLIP:
2641                 camerasrc->vflip = g_value_get_boolean(value);
2642                 break;
2643         case ARG_HFLIP:
2644                 camerasrc->hflip = g_value_get_boolean(value);
2645                 break;
2646         default:
2647                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
2648                 break;
2649         }
2650 }
2651
2652
2653 static void gst_camerasrc_get_property(GObject *object, guint prop_id,
2654                                        GValue *value, GParamSpec *pspec)
2655 {
2656         GstCameraSrc *camerasrc;
2657
2658         g_return_if_fail(GST_IS_CAMERA_SRC(object));
2659         camerasrc = GST_CAMERA_SRC(object);
2660
2661         switch (prop_id) {
2662         case ARG_REQ_NEGOTIATION:
2663                 g_value_set_boolean(value, camerasrc->req_negotiation);
2664                 break;
2665         case ARG_CAMERA_HIGH_SPEED_FPS:
2666                 g_value_set_int(value, camerasrc->high_speed_fps);
2667                 break;
2668         case ARG_CAMERA_AUTO_FPS:
2669                 g_value_set_boolean(value, camerasrc->fps_auto);
2670                 break;
2671         case ARG_CAMERA_ID:
2672                 g_value_set_int(value, camerasrc->camera_id);
2673                 break;
2674         case ARG_CAMERA_EXT_VIDEO_FD:
2675                 g_value_set_int(value, camerasrc->external_videofd);
2676                 break;
2677         case ARG_CAMERA_CAPTURE_FOURCC:
2678                 g_value_set_uint(value, camerasrc->cap_fourcc);
2679                 break;
2680         case ARG_CAMERA_CAPTURE_QUALITY:
2681                 g_value_set_enum(value, camerasrc->cap_quality);
2682                 break;
2683         case ARG_CAMERA_CAPTURE_WIDTH:
2684                 g_value_set_int(value, camerasrc->cap_width);
2685                 break;
2686         case ARG_CAMERA_CAPTURE_HEIGHT:
2687                 g_value_set_int(value, camerasrc->cap_height);
2688                 break;
2689         case ARG_CAMERA_CAPTURE_INTERVAL:
2690                 g_value_set_int(value, camerasrc->cap_interval);
2691                 break;
2692         case ARG_CAMERA_CAPTURE_COUNT:
2693                 g_value_set_int(value, camerasrc->cap_count);
2694                 break;
2695         case ARG_CAMERA_CAPTURE_JPG_QUALITY:
2696                 g_value_set_int(value, camerasrc->cap_jpg_quality);
2697                 GST_INFO("GET jpeg compress ratio : %d", camerasrc->cap_jpg_quality);
2698                 break;
2699         case ARG_CAMERA_CAPTURE_PROVIDE_EXIF:
2700                 camerasrc_support_embed_exif(camerasrc->v4l2_handle, &(camerasrc->cap_provide_exif));
2701                 g_value_set_boolean(value, camerasrc->cap_provide_exif);
2702                 GST_INFO("Is Exif provided? : %d", camerasrc->cap_provide_exif);
2703                 break;
2704         case ARG_SIGNAL_STILLCAPTURE:
2705                 g_value_set_boolean(value, camerasrc->signal_still_capture);
2706                 break;
2707         case ARG_USE_PAD_ALLOC:
2708                 g_value_set_boolean(value, camerasrc->use_pad_alloc);
2709                 break;
2710         case ARG_NUM_ALLOC_BUF:
2711                 g_value_set_int(value, camerasrc->num_alloc_buf);
2712                 break;
2713         case ARG_OPERATION_STATUS:
2714                 g_value_set_int(value, 0);
2715                 gst_camerasrc_buffer_trace(camerasrc);
2716                 break;
2717         case ARG_HOLD_AF_AFTER_CAPTURE:
2718                 g_value_set_boolean(value, camerasrc->hold_af_after_capturing);
2719                 break;
2720         case ARG_SENSOR_MODE:
2721                 g_value_set_int(value, camerasrc->sensor_mode);
2722                 break;
2723         case ARG_VFLIP:
2724                 g_value_set_boolean(value, camerasrc->vflip);
2725                 break;
2726         case ARG_HFLIP:
2727                 g_value_set_boolean(value, camerasrc->hflip);
2728                 break;
2729         default:
2730                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
2731                 break;
2732         }
2733 }
2734
2735
2736 static GstStateChangeReturn gst_camerasrc_change_state(GstElement *element, GstStateChange transition)
2737 {
2738         GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2739         GstCameraSrc *camerasrc;
2740         camerasrc = GST_CAMERA_SRC (element);
2741
2742         switch (transition) {
2743         case GST_STATE_CHANGE_NULL_TO_READY:
2744                 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: NULL -> READY");
2745                 __ta__("    gst_camerasrc_create",
2746                 if (!gst_camerasrc_create(camerasrc)){
2747                         goto statechange_failed;
2748                 }
2749                 );
2750                 break;
2751         case GST_STATE_CHANGE_READY_TO_PAUSED:
2752                 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: READY -> PAUSED");
2753                 ret = GST_STATE_CHANGE_NO_PREROLL;
2754                 break;
2755         case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2756                 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> PLAYING");
2757                 break;
2758         default:
2759                 break;
2760         }
2761
2762         ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
2763         if (ret == GST_STATE_CHANGE_FAILURE){
2764                 return ret;
2765         }
2766
2767         switch (transition) {
2768         case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2769                 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PLAYING -> PAUSED");
2770                 ret = GST_STATE_CHANGE_NO_PREROLL;
2771                 break;
2772         case GST_STATE_CHANGE_PAUSED_TO_READY:
2773                 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> READY");
2774                 break;
2775         case GST_STATE_CHANGE_READY_TO_NULL:
2776                 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: READY -> NULL");
2777                 __ta__("    gst_camerasrc_destroy",
2778                 if (!gst_camerasrc_destroy(camerasrc)){
2779                         goto statechange_failed;
2780                 }
2781                 );
2782                 break;
2783         default:
2784                 break;
2785         }
2786
2787         return ret;
2788
2789  statechange_failed:
2790         /* subclass must post a meaningfull error message */
2791         GST_ERROR_OBJECT(camerasrc, "state change failed");
2792
2793         return GST_STATE_CHANGE_FAILURE;
2794 }
2795
2796
2797 static void gst_camerasrc_finalize(GObject *object)
2798 {
2799         GstCameraSrc *camerasrc = GST_CAMERA_SRC(object);
2800
2801 #if _ENABLE_CAMERASRC_DEBUG
2802         GST_INFO_OBJECT(camerasrc, "total [%u] preview frame(s) outputed.",g_preview_frame_cnt);
2803 #endif
2804
2805         g_mutex_free(camerasrc->jpg_mutex);
2806         g_mutex_free(camerasrc->mutex);
2807         g_cond_free(camerasrc->cond);
2808         g_mutex_free(camerasrc->buffer_lock);
2809         g_cond_broadcast(camerasrc->buffer_cond);
2810         g_cond_free(camerasrc->buffer_cond);
2811
2812         if (camerasrc->command_list != NULL) {
2813                 g_queue_free(camerasrc->command_list);
2814                 camerasrc->command_list = NULL;
2815         }
2816
2817         G_OBJECT_CLASS(parent_class)->finalize(object);
2818 }
2819
2820
2821 void gst_camerasrc_set_capture_command(GstCameraSrc *camerasrc, GstCameraControlCaptureCommand cmd)
2822 {
2823         gboolean is_zsl = FALSE;
2824
2825         if (camerasrc == NULL) {
2826                 GST_ERROR_OBJECT(camerasrc, "camerasrc is NULL");
2827                 return;
2828         }
2829
2830         GST_INFO_OBJECT(camerasrc, "ENTERED");
2831
2832         g_mutex_lock(camerasrc->mutex);
2833
2834         /* Do not push command when ZSL mode */
2835         if (!is_zsl) {
2836                 g_queue_push_tail(camerasrc->command_list, (gpointer)cmd);
2837                 GST_INFO_OBJECT(camerasrc, "ACTION: Push capture command [%d] finished.", cmd);
2838         }
2839
2840         if (cmd == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP) {
2841                 g_cond_signal(camerasrc->cond);
2842                 GST_INFO_OBJECT(camerasrc, "Send signal for CAPTURE STOP");
2843         }
2844
2845         g_mutex_unlock(camerasrc->mutex);
2846
2847         return;
2848 }
2849
2850
2851 static gboolean gst_camerasrc_negotiate (GstBaseSrc * basesrc)
2852 {
2853         GstCaps *thiscaps;
2854         GstCaps *caps = NULL;
2855         GstCaps *peercaps = NULL;
2856         gboolean result = FALSE;
2857         GstStructure *s;
2858         GstCameraSrc *camerasrc = GST_CAMERA_SRC(basesrc);
2859
2860         GST_INFO_OBJECT(camerasrc, "ENTERED");
2861         /* first see what is possible on our source pad */
2862         thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));
2863         GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps);
2864
2865         /* nothing or anything is allowed, we're done */
2866         if (thiscaps == NULL || gst_caps_is_any (thiscaps))
2867                 goto no_nego_needed;
2868
2869         /* get the peer caps */
2870         peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
2871         GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps);
2872         //LOG_CAPS (basesrc, peercaps);
2873         if (peercaps && !gst_caps_is_any (peercaps)) {
2874                 GstCaps *icaps = NULL;
2875                 int i;
2876
2877                 /* Prefer the first caps we are compatible with that the peer proposed */
2878                 for (i = 0; i < gst_caps_get_size (peercaps); i++) {
2879                         /* get intersection */
2880                         GstCaps *ipcaps = gst_caps_copy_nth (peercaps, i);
2881
2882                         icaps = gst_caps_intersect (thiscaps, ipcaps);
2883                         gst_caps_unref (ipcaps);
2884
2885                         if (!gst_caps_is_empty (icaps))
2886                                 break;
2887
2888                         gst_caps_unref (icaps);
2889                         icaps = NULL;
2890                 }
2891
2892                 GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, icaps);
2893                 if (icaps) {
2894                         /* If there are multiple intersections pick the one with the smallest
2895                         * resolution strictly bigger than the first peer caps */
2896                         if (gst_caps_get_size (icaps) > 1) {
2897                                 s = gst_caps_get_structure (peercaps, 0);
2898                                 int best = 0;
2899                                 int twidth, theight;
2900                                 int width = G_MAXINT, height = G_MAXINT;
2901
2902                                 if (gst_structure_get_int (s, "width", &twidth)
2903                                         && gst_structure_get_int (s, "height", &theight)) {
2904
2905                                         /* Walk the structure backwards to get the first entry of the
2906                                         * smallest resolution bigger (or equal to) the preferred resolution)
2907                                         */
2908                                         for (i = gst_caps_get_size (icaps) - 1; i >= 0; i--) {
2909                                                 GstStructure *is = gst_caps_get_structure (icaps, i);
2910                                                 int w, h;
2911
2912                                                 if (gst_structure_get_int (is, "width", &w)
2913                                                         && gst_structure_get_int (is, "height", &h)) {
2914                                                         if (w >= twidth && w <= width && h >= theight && h <= height) {
2915                                                                 width = w;
2916                                                                 height = h;
2917                                                                 best = i;
2918                                                         }
2919                                                 }
2920                                         }
2921                                 }
2922
2923                                 caps = gst_caps_copy_nth (icaps, best);
2924                                 gst_caps_unref (icaps);
2925                         } else {
2926                                 caps = icaps;
2927                         }
2928                 }
2929                 gst_caps_unref (thiscaps);
2930                 gst_caps_unref (peercaps);
2931         } else {
2932                 /* no peer or peer has ANY caps, work with our own caps then */
2933                 caps = thiscaps;
2934         }
2935         if (caps) {
2936                 caps = gst_caps_make_writable (caps);
2937                 gst_caps_truncate (caps);
2938
2939                 /* now fixate */
2940                 if (!gst_caps_is_empty (caps)) {
2941                         gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
2942                         GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
2943
2944                         if (gst_caps_is_any (caps)) {
2945                                 /* hmm, still anything, so element can do anything and
2946                                 * nego is not needed */
2947                                 result = TRUE;
2948                         } else if (gst_caps_is_fixed (caps)) {
2949                                 /* yay, fixed caps, use those then */
2950                                 if (gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps))
2951                                 result = TRUE;
2952                         }
2953                 }
2954                 gst_caps_unref (caps);
2955         }
2956         return result;
2957
2958 no_nego_needed:
2959         {
2960                 GST_DEBUG_OBJECT (basesrc, "no negotiation needed");
2961                 if (thiscaps)
2962                         gst_caps_unref (thiscaps);
2963                 return TRUE;
2964         }
2965 }
2966
2967
2968 static GstCaps *gst_camerasrc_get_caps(GstBaseSrc *src)
2969 {
2970         GstCameraSrc *camerasrc = GST_CAMERA_SRC(src);
2971         GstCaps *ret = NULL;
2972
2973         GST_DEBUG_OBJECT(camerasrc, "ENTERED");
2974
2975         if (camerasrc->mode == VIDEO_IN_MODE_UNKNOWN) {
2976                 GST_INFO_OBJECT(camerasrc, "Unknown mode. Just return template caps.");
2977                 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
2978
2979                 return gst_caps_copy(gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc)));
2980         }
2981
2982         /*FIXME: Using "VIDIOC_ENUM_FMT".*/
2983         ret = gst_caps_copy(gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc)));
2984
2985         GST_INFO_OBJECT(camerasrc, "probed caps: %x", ret);
2986         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
2987
2988         return ret;
2989 }
2990
2991
2992 static gboolean _gst_camerasrc_get_raw_pixel_info(int fourcc, int *pix_format, int *colorspace)
2993 {
2994         switch (fourcc) {
2995         case GST_MAKE_FOURCC('I','4','2','0'):  /* V4L2_PIX_FMT_YUV420 */
2996         case GST_MAKE_FOURCC('I','Y','U','V'):
2997         case GST_MAKE_FOURCC('Y','U','1','2'):
2998         case GST_MAKE_FOURCC('S','4','2','0'):
2999                 *pix_format = CAMERASRC_PIX_YUV420P;
3000                 *colorspace = CAMERASRC_COL_RAW;
3001                 break;
3002         case GST_MAKE_FOURCC('Y','U','Y','V'):  /* V4L2_PIX_FMT_YUYV */
3003         case GST_MAKE_FOURCC('Y','U','Y','2'):  /* V4L2_PIX_FMT_YUYV */
3004         case GST_MAKE_FOURCC('S','U','Y','V'):
3005         case GST_MAKE_FOURCC('S','U','Y','2'):
3006                 *pix_format = CAMERASRC_PIX_YUY2;
3007                 *colorspace = CAMERASRC_COL_RAW;
3008                 break;
3009         case GST_MAKE_FOURCC('U','Y','V','Y'):  /* V4L2_PIX_FMT_UYVY */
3010         case GST_MAKE_FOURCC('S','Y','V','Y'):  /* V4L2_PIX_FMT_UYVY */
3011                 *pix_format = CAMERASRC_PIX_UYVY;
3012                 *colorspace = CAMERASRC_COL_RAW;
3013                 break;
3014         case GST_MAKE_FOURCC('4','2','2','P'):  /* V4L2_PIX_FMT_YUV422P */
3015         case GST_MAKE_FOURCC('Y','4','2','B'):  /* V4L2_PIX_FMT_YUV422P */
3016                 *pix_format = CAMERASRC_PIX_YUV422P;
3017                 *colorspace = CAMERASRC_COL_RAW;
3018                 break;
3019         case GST_MAKE_FOURCC('N','V','1','2'):  /* V4L2_PIX_FMT_NV12 */
3020                 *pix_format = CAMERASRC_PIX_NV12;
3021                 *colorspace = CAMERASRC_COL_RAW;
3022                 break;
3023         case GST_MAKE_FOURCC('S','N','1','2'):  /* V4L2_PIX_FMT_NV12 non-linear */
3024                 *pix_format = CAMERASRC_PIX_SN12;
3025                 *colorspace = CAMERASRC_COL_RAW;
3026                 break;
3027         case GST_MAKE_FOURCC('S','T','1','2'):  /* V4L2_PIX_FMT_NV12 tiled non-linear */
3028                 *pix_format = CAMERASRC_PIX_ST12;
3029                 *colorspace = CAMERASRC_COL_RAW;
3030                 break;
3031         case GST_MAKE_FOURCC('J','P','E','G'):
3032         case GST_MAKE_FOURCC('j','p','e','g'):
3033                 *pix_format = CAMERASRC_PIX_RGGB8;
3034                 *colorspace = CAMERASRC_COL_JPEG;
3035                 break;
3036         case GST_MAKE_FOURCC('Y','4','1','P'):  /* V4L2_PIX_FMT_Y41P */
3037         case GST_MAKE_FOURCC('N','V','2','1'):  /* V4L2_PIX_FMT_NV21 */
3038         case GST_MAKE_FOURCC('Y','4','1','B'):  /* V4L2_PIX_FMT_YUV411P */
3039         case GST_MAKE_FOURCC('Y','V','1','2'):  /* V4L2_PIX_FMT_YVU420 */
3040         default:
3041                 /* ERROR */
3042                 *pix_format = CAMERASRC_PIX_NONE;
3043                 *colorspace = CAMERASRC_COL_NONE;
3044                 break;
3045         }
3046
3047         return TRUE;
3048 }
3049
3050
3051 static gboolean _gst_camerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize)
3052 {
3053         switch (fourcc) {
3054         case GST_MAKE_FOURCC('I','4','2','0'):  /* V4L2_PIX_FMT_YUV420 */
3055         case GST_MAKE_FOURCC('I','Y','U','V'):
3056         case GST_MAKE_FOURCC('Y','U','1','2'):
3057         case GST_MAKE_FOURCC('Y','V','1','2'):
3058         case GST_MAKE_FOURCC('S','4','2','0'):  /* V4L2_PIX_FMT_NV12 tiled non-linear */
3059                 *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
3060                 *outsize += 2 * ((GST_ROUND_UP_8 (width) / 2) * (GST_ROUND_UP_2 (height) / 2));
3061                 break;
3062         case GST_MAKE_FOURCC('Y','U','Y','V'):  /* V4L2_PIX_FMT_YUYV */
3063         case GST_MAKE_FOURCC('Y','U','Y','2'):  /* V4L2_PIX_FMT_YUYV */
3064         case GST_MAKE_FOURCC('S','U','Y','V'):
3065         case GST_MAKE_FOURCC('S','U','Y','2'):
3066         case GST_MAKE_FOURCC('U','Y','V','Y'):  /* V4L2_PIX_FMT_UYVY */
3067         case GST_MAKE_FOURCC('S','Y','V','Y'):  /* V4L2_PIX_FMT_UYVY */
3068         case GST_MAKE_FOURCC('4','2','2','P'):  /* V4L2_PIX_FMT_YUV422P */
3069         case GST_MAKE_FOURCC('Y','4','2','B'):  /* V4L2_PIX_FMT_YUV422P */
3070         case GST_MAKE_FOURCC('Y','4','1','P'):  /* V4L2_PIX_FMT_Y41P */
3071                 *outsize = (GST_ROUND_UP_2 (width) * 2) * height;
3072                 break;
3073         case GST_MAKE_FOURCC('Y','4','1','B'):  /* V4L2_PIX_FMT_YUV411P */
3074                 *outsize = GST_ROUND_UP_4 (width) * height;
3075                 *outsize += 2 * ((GST_ROUND_UP_8 (width) / 4) * height);
3076                 break;
3077         case GST_MAKE_FOURCC('N','V','1','2'):  /* V4L2_PIX_FMT_NV12 */
3078         case GST_MAKE_FOURCC('N','V','2','1'):  /* V4L2_PIX_FMT_NV21 */
3079         case GST_MAKE_FOURCC('S','N','1','2'):  /* V4L2_PIX_FMT_NV12 non-linear */
3080         case GST_MAKE_FOURCC('S','T','1','2'):  /* V4L2_PIX_FMT_NV12 tiled non-linear */
3081                 *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
3082                 *outsize += (GST_ROUND_UP_4 (width) * height) / 2;
3083                 break;
3084         case GST_MAKE_FOURCC('J','P','E','G'):
3085         case GST_MAKE_FOURCC('j','p','e','g'):
3086                 /* jpeg size can't be calculated here. */
3087                 *outsize = 0;
3088                 break;
3089         default:
3090                 /* unkown format!! */
3091                 *outsize = 0;
3092                 break;
3093         }
3094
3095         return TRUE;
3096 }
3097
3098 static gboolean _gst_camerasrc_get_normal_buffer(GstCameraSrc *camerasrc, int fourcc,
3099                                                  unsigned char *base_buffer, int width, int height,
3100                                                  unsigned char **new_buffer, unsigned int *new_buffer_length)
3101 {
3102         unsigned char *copy_data = NULL;
3103         guint length_Y = 0;
3104
3105         if (camerasrc == NULL || base_buffer == NULL ||
3106             new_buffer == NULL || new_buffer_length == NULL) {
3107                 GST_WARNING_OBJECT(camerasrc, "something is NULL(%p,%p,%p,%p)",
3108                                               camerasrc, base_buffer, new_buffer, new_buffer_length);
3109                 return FALSE;
3110         }
3111
3112         switch (fourcc) {
3113         case GST_MAKE_FOURCC('I','4','2','0'):
3114         case GST_MAKE_FOURCC('S','4','2','0'):
3115         {
3116                 guint length_Cb = 0;
3117                 guint length_Cr = 0;
3118                 guint offset_Cb = 0;
3119                 guint offset_Cr = 0;
3120
3121                 length_Y = width * height;
3122                 length_Cb = length_Cr = (width * height) >> 2;
3123
3124                 copy_data = (unsigned char*)malloc(length_Y + length_Cb + length_Cr);
3125                 if (copy_data == NULL) {
3126                         GST_ERROR_OBJECT(camerasrc, "New buffer data ALLOC FAILED");
3127                         gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_ALLOCATION);
3128                         return FALSE;
3129                 }
3130
3131                 offset_Cb = CAMERASRC_ALIGN(length_Y, ALIGN_SIZE_I420);
3132                 offset_Cr = offset_Cb + CAMERASRC_ALIGN(length_Cb, ALIGN_SIZE_I420);
3133
3134                 memcpy(copy_data, base_buffer, length_Y);
3135                 memcpy(copy_data + length_Y, base_buffer + offset_Cb, length_Cb);
3136                 memcpy(copy_data + length_Y + length_Cb, base_buffer + offset_Cr, length_Cr);
3137
3138                 *new_buffer = copy_data;
3139                 *new_buffer_length = length_Y + length_Cb + length_Cr;
3140
3141                 GST_DEBUG_OBJECT(camerasrc, "Total(0x%x), I420(S420) length Y(0x%x),Cb(0x%x),Cr(0x%x), offset Cb(0x%x),Cr(0x%x)",
3142                                             *new_buffer_length, length_Y, length_Cb, length_Cr, offset_Cb, offset_Cr);
3143                 break;
3144         }
3145         case GST_MAKE_FOURCC('N','V','1','2'):
3146         case GST_MAKE_FOURCC('S','N','1','2'):
3147         {
3148                 guint length_CbCr = 0;
3149                 guint offset_CbCr = 0;
3150
3151                 length_Y = width * height;
3152                 length_CbCr = (width * height) >> 1;
3153
3154                 copy_data = (unsigned char*)malloc(length_Y + length_CbCr);
3155                 if (copy_data == NULL) {
3156                         GST_ERROR_OBJECT(camerasrc, "New buffer data ALLOC FAILED");
3157                         gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_ALLOCATION);
3158                         return FALSE;
3159                 }
3160
3161                 offset_CbCr = CAMERASRC_ALIGN(length_Y, ALIGN_SIZE_NV12);
3162
3163                 memcpy(copy_data, base_buffer, length_Y);
3164                 memcpy(copy_data + length_Y, base_buffer + offset_CbCr, length_CbCr);
3165
3166                 *new_buffer = copy_data;
3167                 *new_buffer_length = length_Y + length_CbCr;
3168
3169                 GST_DEBUG_OBJECT(camerasrc, "Total(0x%x), NV12(SN12) length Y(0x%x),CbCr(0x%x), offset CbCr(0x%x)",
3170                                             *new_buffer_length, length_Y, length_CbCr, offset_CbCr);
3171                 break;
3172         }
3173         default:
3174         {
3175                 char *pfourcc = (char*)&fourcc;
3176                 GST_WARNING_OBJECT(camerasrc, "Unknown fourcc(%c%c%c%c)",
3177                                               pfourcc[0], pfourcc[1], pfourcc[2], pfourcc[3]);
3178                 *new_buffer = NULL;
3179                 *new_buffer_length = 0;
3180                 return FALSE;
3181         }
3182         }
3183
3184         GST_DEBUG_OBJECT(camerasrc, "Done.");
3185
3186         return TRUE;
3187 }
3188
3189
3190 static gboolean gst_camerasrc_get_caps_info(GstCameraSrc *camerasrc, GstCaps *caps, guint *size)
3191 {
3192         gint fps_n = 0;
3193         gint fps_d = 0;
3194         gint w = 0;
3195         gint h = 0;
3196         gint rot = 0;
3197         gchar *caps_string = NULL;
3198         const gchar *mimetype;
3199         const GValue *framerate;
3200         GstStructure *structure = NULL;
3201
3202         GST_INFO_OBJECT(camerasrc, "ENTERED Collect data for given caps.(caps:%x)", caps);
3203
3204         structure = gst_caps_get_structure(caps, 0);
3205
3206         if (!gst_structure_get_int(structure, "width", &w)) {
3207                 goto _caps_info_failed;
3208         }
3209
3210         if (!gst_structure_get_int(structure, "height", &h)) {
3211                 goto _caps_info_failed;
3212         }
3213
3214         if (!gst_structure_get_int(structure, "rotate", &rot)) {
3215                 GST_WARNING_OBJECT(camerasrc, "Failed to get rotate info in caps. set default 0.");
3216                 camerasrc->use_rotate_caps = FALSE;
3217         } else {
3218                 GST_INFO_OBJECT(camerasrc, "Succeed to get rotate[%d] info in caps", rot);
3219                 camerasrc->use_rotate_caps = TRUE;
3220         }
3221
3222         /* set default size if there is no capsfilter */
3223         if (w == 1) {
3224                 w = _DEFAULT_WIDTH * 2;
3225         }
3226
3227         if (h == 1) {
3228                 h = _DEFAULT_HEIGHT * 2;
3229         }
3230
3231         camerasrc->width = w;
3232         camerasrc->height = h;
3233         camerasrc->rotate = rot;
3234
3235         framerate = gst_structure_get_value(structure, "framerate");
3236         if (!framerate) {
3237                 GST_INFO("Set FPS as default");
3238
3239                 /* set default fps if framerate is not existed in caps */
3240                 fps_n = _DEFAULT_FPS;
3241                 fps_d = 1;
3242         } else {
3243                 fps_n = gst_value_get_fraction_numerator(framerate);
3244                 fps_d = gst_value_get_fraction_denominator(framerate);
3245
3246                 /* numerator and denominator should be bigger than zero */
3247                 if (fps_n <= 0) {
3248                         GST_WARNING("numerator of FPS is %d. make it default(15).", fps_n);
3249                         fps_n = _DEFAULT_FPS;
3250                 }
3251
3252                 if (fps_d <= 0) {
3253                         GST_WARNING("denominator of FPS is %d. make it 1.", fps_d);
3254                         fps_d = 1;
3255                 }
3256         }
3257
3258         camerasrc->fps = (int)((float)fps_n / (float)fps_d);
3259
3260         mimetype = gst_structure_get_name (structure);
3261
3262         *size = 0;
3263
3264         if (!strcmp(mimetype, "video/x-raw-yuv")) {
3265                 gst_structure_get_fourcc(structure, "format", &camerasrc->fourcc);
3266                 if (camerasrc->fourcc == 0) {
3267                         GST_INFO_OBJECT(camerasrc, "Getting fourcc is zero.");
3268                         goto _caps_info_failed;
3269                 }
3270
3271                 _gst_camerasrc_get_frame_size(camerasrc->fourcc, w, h, size);
3272                 _gst_camerasrc_get_raw_pixel_info(camerasrc->fourcc, &(camerasrc->pix_format), &(camerasrc->colorspace));
3273         } else if (!strcmp (mimetype, "video/x-raw-rgb")) {
3274                 gint depth = 0;
3275                 gint endianness = 0;
3276                 gint r_mask = 0;
3277
3278                 gst_structure_get_int(structure, "depth", &depth);
3279                 gst_structure_get_int(structure, "endianness", &endianness);
3280                 gst_structure_get_int(structure, "red_mask", &r_mask);
3281
3282                 switch (depth) {
3283                 case 8:  /* V4L2_PIX_FMT_RGB332 */
3284                         camerasrc->pix_format = CAMERASRC_PIX_RGGB8;
3285                         camerasrc->colorspace = CAMERASRC_COL_RAW;
3286                         break;
3287                 case 15: /* V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB555X */
3288                         camerasrc->pix_format = CAMERASRC_PIX_NONE;
3289                         camerasrc->colorspace = CAMERASRC_COL_NONE;
3290                         break;
3291                 case 16: /* V4L2_PIX_FMT_RGB565 : V4L2_PIX_FMT_RGB565X */
3292                         camerasrc->pix_format = CAMERASRC_PIX_NONE;
3293                         camerasrc->colorspace = CAMERASRC_COL_NONE;
3294                         break;
3295                 case 24: /* V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24 */
3296                         camerasrc->pix_format = CAMERASRC_PIX_NONE;
3297                         camerasrc->colorspace = CAMERASRC_COL_NONE;
3298                         break;
3299                 case 32: /* V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32 */
3300                         camerasrc->pix_format = CAMERASRC_PIX_NONE;
3301                         camerasrc->colorspace = CAMERASRC_COL_NONE;
3302                         break;
3303                 }
3304         } else if (strcmp(mimetype, "video/x-dv") == 0) { /* V4L2_PIX_FMT_DV */
3305                 camerasrc->pix_format = CAMERASRC_PIX_NONE;
3306                 camerasrc->colorspace = CAMERASRC_COL_NONE;
3307         } else if (strcmp(mimetype, "image/jpeg") == 0) { /* V4L2_PIX_FMT_JPEG */
3308                 camerasrc->pix_format = CAMERASRC_PIX_RGGB8; /* default */
3309                 camerasrc->colorspace = CAMERASRC_COL_JPEG;
3310         }
3311
3312         caps_string = gst_caps_to_string(caps);
3313         GST_INFO_OBJECT(camerasrc, "pixformat %d, colorspace %d, size %d, caps : [%s]",
3314                                    camerasrc->pix_format, camerasrc->colorspace, *size, caps_string);
3315         if (caps_string) {
3316                 g_free(caps_string);
3317                 caps_string = NULL;
3318         }
3319
3320         return TRUE;
3321
3322 _caps_info_failed:
3323         GST_INFO_OBJECT(camerasrc, "Failed to get caps info.");
3324         GST_DEBUG_OBJECT(camerasrc, "LEAVED");
3325         return FALSE;
3326 }
3327
3328
3329 static gboolean gst_camerasrc_set_caps(GstBaseSrc *src, GstCaps *caps)
3330 {
3331         guint size;
3332         GstCameraSrc *camerasrc = NULL;
3333
3334         camerasrc = GST_CAMERA_SRC(src);
3335
3336         GST_INFO_OBJECT(camerasrc, "ENTERED");
3337
3338         if (camerasrc->mode == VIDEO_IN_MODE_PREVIEW ||
3339             camerasrc->mode == VIDEO_IN_MODE_VIDEO) {
3340                 GST_INFO_OBJECT(camerasrc, "Proceed set_caps");
3341                 __ta__("            gst_camerasrc_stop",
3342                 if (!gst_camerasrc_stop(camerasrc)) {
3343                         GST_INFO_OBJECT(camerasrc, "Cam sensor stop failed.");
3344                 }
3345                 );
3346         } else if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) {
3347                 GST_ERROR_OBJECT(camerasrc, "A mode of avsystem camera is capture. Not to proceed set_caps.");
3348                 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
3349                 return FALSE;
3350         } else {
3351                 GST_INFO_OBJECT(camerasrc, "A mode of avsystem camera is unknown[%d]. Proceed set_caps.", camerasrc->mode);
3352         }
3353
3354         /* we want our own v4l2 type of fourcc codes */
3355         if (!gst_camerasrc_get_caps_info(camerasrc, caps, &size)) {
3356                 GST_INFO_OBJECT(camerasrc, "can't get capture information from caps %x", caps);
3357                 return FALSE;
3358         }
3359
3360         __ta__("            gst_camerasrc_start",
3361         if (!gst_camerasrc_start(camerasrc)) {
3362                 GST_INFO_OBJECT (camerasrc,  "Cam sensor start failed.");
3363         }
3364         );
3365
3366         GST_INFO_OBJECT (camerasrc, "LEAVED");
3367
3368         return TRUE;
3369 }
3370
3371
3372 static void gst_camerasrc_base_init(gpointer klass)
3373 {
3374         GstElementClass *element_class = GST_ELEMENT_CLASS(klass);
3375
3376         GST_DEBUG_CATEGORY_INIT(camerasrc_debug, "camerasrc", 0, "camerasrc element");
3377
3378         GST_INFO("ENTERED");
3379
3380         gst_element_class_add_pad_template(element_class, gst_static_pad_template_get (&src_factory));
3381         gst_element_class_set_details(element_class, &camerasrc_details);
3382
3383         GST_INFO("LEAVED");
3384 }
3385
3386
3387 static void gst_camerasrc_class_init(GstCameraSrcClass *klass)
3388 {
3389         GObjectClass *gobject_class;
3390         GstElementClass *element_class;
3391         GstBaseSrcClass *basesrc_class;
3392         GstPushSrcClass *pushsrc_class;
3393
3394         GST_DEBUG("ENTERED");
3395
3396         gobject_class = G_OBJECT_CLASS(klass);
3397         element_class = GST_ELEMENT_CLASS(klass);
3398         basesrc_class = GST_BASE_SRC_CLASS(klass);
3399         pushsrc_class = GST_PUSH_SRC_CLASS(klass);
3400
3401         gobject_class->set_property = gst_camerasrc_set_property;
3402         gobject_class->get_property = gst_camerasrc_get_property;
3403         gobject_class->finalize = gst_camerasrc_finalize;
3404         element_class->change_state = gst_camerasrc_change_state;
3405         basesrc_class->start = gst_camerasrc_src_start;
3406         basesrc_class->stop = gst_camerasrc_src_stop;
3407         basesrc_class->get_caps = gst_camerasrc_get_caps;
3408         basesrc_class->set_caps = gst_camerasrc_set_caps;
3409         basesrc_class->negotiate = gst_camerasrc_negotiate;
3410         pushsrc_class->create = gst_camerasrc_src_create;
3411
3412         g_object_class_install_property(gobject_class, ARG_REQ_NEGOTIATION,
3413                                         g_param_spec_boolean("req-negotiation", "Request re-negotiation",
3414                                                              "Request to negotiate while on playing",
3415                                                              FALSE,
3416                                                              G_PARAM_READWRITE));
3417
3418         g_object_class_install_property(gobject_class, ARG_CAMERA_HIGH_SPEED_FPS,
3419                                         g_param_spec_int("high-speed-fps", "Fps for high speed recording",
3420                                                          "If this value is 0, the element doesn't activate high speed recording.",
3421                                                          0, G_MAXINT, _DEFAULT_HIGH_SPEED_FPS,
3422                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3423
3424         g_object_class_install_property(gobject_class, ARG_CAMERA_AUTO_FPS,
3425                                         g_param_spec_boolean("fps-auto", "FPS Auto",
3426                                                              "Field for auto fps setting",
3427                                                              _DEFAULT_FPS_AUTO,
3428                                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3429
3430         g_object_class_install_property(gobject_class, ARG_CAMERA_EXT_VIDEO_FD,
3431                                         g_param_spec_int("extern_videofd", "External video file descriptor",
3432                                                          "External video file descriptor",
3433                                                          _FD_MIN, _FD_MAX, _FD_MIN,
3434                                                          G_PARAM_READWRITE));
3435
3436         g_object_class_install_property(gobject_class, ARG_CAMERA_ID,
3437                                         g_param_spec_int("camera-id", "index number of camera to activate",
3438                                                          "index number of camera to activate",
3439                                                          _FD_MIN, _FD_MAX, 0,
3440                                                          G_PARAM_READWRITE));
3441
3442         /*Capture*/
3443         g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_FOURCC,
3444                                         g_param_spec_uint("capture-fourcc", "Capture format",
3445                                                           "Fourcc value for capture format",
3446                                                           0, G_MAXUINT, 0,
3447                                                           G_PARAM_READWRITE));
3448
3449         g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_QUALITY,
3450                                         g_param_spec_enum("capture-quality", "Capture quality",
3451                                                           "Quality of capture image (JPEG: 'high', RAW: 'high' or 'low')",
3452                                                           GST_TYPE_CAMERASRC_QUALITY, _DEFAULT_CAP_QUALITY,
3453                                                           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3454
3455         g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_WIDTH,
3456                                         g_param_spec_int("capture-width", "Capture width",
3457                                                          "Width for camera size to capture",
3458                                                          0, G_MAXINT, _DEFAULT_CAP_WIDTH,
3459                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3460
3461         g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_HEIGHT,
3462                                         g_param_spec_int("capture-height", "Capture height",
3463                                                          "Height for camera size to capture",
3464                                                          0, G_MAXINT, _DEFAULT_CAP_HEIGHT,
3465                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3466
3467         g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_INTERVAL,
3468                                         g_param_spec_int("capture-interval", "Capture interval",
3469                                                          "Interval time to capture (millisecond)",
3470                                                          0, G_MAXINT, _DEFAULT_CAP_INTERVAL,
3471                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3472
3473         g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_COUNT,
3474                                         g_param_spec_int("capture-count", "Capture count",
3475                                                          "Capture conut for multishot",
3476                                                          1, G_MAXINT, _DEFAULT_CAP_COUNT,
3477                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3478
3479         g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_JPG_QUALITY,
3480                                         g_param_spec_int("capture-jpg-quality", "JPEG Capture compress ratio",
3481                                                          "Quality of capture image compress ratio",
3482                                                          1, 100, _DEFAULT_CAP_JPG_QUALITY,
3483                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3484
3485         g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_PROVIDE_EXIF,
3486                                         g_param_spec_boolean("provide-exif", "Whether EXIF is provided",
3487                                                              "Does capture provide EXIF?",
3488                                                              _DEFAULT_CAP_PROVIDE_EXIF,
3489                                                              G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
3490
3491         g_object_class_install_property(gobject_class, ARG_SIGNAL_STILLCAPTURE,
3492                                         g_param_spec_boolean("signal-still-capture", "Signal still capture",
3493                                                              "Send a signal before pushing the buffer",
3494                                                              _DEFAULT_SIGNAL_STILL_CAPTURE,
3495                                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3496
3497         g_object_class_install_property(gobject_class, ARG_USE_PAD_ALLOC,
3498                                         g_param_spec_boolean("use-pad-alloc", "Use pad alloc",
3499                                                              "Use gst_pad_alloc_buffer() for image frame buffer",
3500                                                              _DEFAULT_USE_PAD_ALLOC,
3501                                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3502
3503         g_object_class_install_property(gobject_class, ARG_NUM_ALLOC_BUF,
3504                                         g_param_spec_int("num-alloc-buf", "Number alloced buffer",
3505                                                          "Number of buffer to alloc using gst_pad_alloc_buffer()",
3506                                                          1, _MAX_NUM_ALLOC_BUF, _DEFAULT_NUM_ALLOC_BUF,
3507                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3508
3509         g_object_class_install_property(gobject_class, ARG_OPERATION_STATUS,
3510                                         g_param_spec_int("operation-status", "Check operation status of camerasrc",
3511                                                          "This value has bit flags that describe current operation status.",
3512                                                          G_MININT, G_MAXINT, 0,
3513                                                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
3514
3515         g_object_class_install_property(gobject_class, ARG_HOLD_AF_AFTER_CAPTURE,
3516                                         g_param_spec_boolean("hold-af-after-capturing", "Hold af after capturing",
3517                                                              "Hold af position after capturing",
3518                                                              FALSE, G_PARAM_READWRITE));
3519
3520         g_object_class_install_property(gobject_class, ARG_FAKE_ESD,
3521                                         g_param_spec_boolean("fake-esd", "Fake ESD generate",
3522                                                              "Generate fake esd situation",
3523                                                              FALSE, G_PARAM_READWRITE));
3524
3525         g_object_class_install_property(gobject_class, ARG_SENSOR_MODE,
3526                                         g_param_spec_int("sensor-mode", "Sensor mode",
3527                                                          "Set sensor mode as CAMERA or MOVIE(camcorder)",
3528                                                          CAMERASRC_SENSOR_MODE_CAMERA, CAMERASRC_SENSOR_MODE_MOVIE, CAMERASRC_SENSOR_MODE_CAMERA,
3529                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3530
3531         g_object_class_install_property(gobject_class, ARG_VFLIP,
3532                                         g_param_spec_boolean("vflip", "Flip vertically",
3533                                                              "Flip camera input vertically",
3534                                                              0,
3535                                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3536
3537         g_object_class_install_property(gobject_class, ARG_HFLIP,
3538                                         g_param_spec_boolean("hflip", "Flip horizontally",
3539                                                              "Flip camera input horizontally",
3540                                                              0,
3541                                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3542
3543         /**
3544         * GstCameraSrc::still-capture:
3545         * @camerasrc: the camerasrc instance
3546         * @buffer: the buffer that will be pushed - Main
3547         * @buffer: the buffer that will be pushed - Thumbnail
3548         * @buffer: the buffer that will be pushed - Screennail
3549         *
3550         * This signal gets emitted before sending the buffer.
3551         */
3552         gst_camerasrc_signals[SIGNAL_STILL_CAPTURE] =
3553                 g_signal_new("still-capture",
3554                              G_TYPE_FROM_CLASS(klass),
3555                              G_SIGNAL_RUN_LAST,
3556                              G_STRUCT_OFFSET(GstCameraSrcClass, still_capture),
3557                              NULL,
3558                              NULL,
3559                              gst_camerasrc_VOID__OBJECT_OBJECT,
3560                              G_TYPE_NONE,
3561                              3, /* Number of parameter */
3562                              GST_TYPE_BUFFER,  /* Main image buffer */
3563                              GST_TYPE_BUFFER,  /* Thumbnail image buffer */
3564                              GST_TYPE_BUFFER); /* Screennail image buffer */
3565
3566
3567         /* wh01.cho:req-negotiation:+:To notify user of camerasrc, after changing resolution. */
3568         /**
3569         * GstCameraSrc::nego-complete:
3570         * @camerasrc: the camerasrc instance
3571         * @start: when re-negotiation is finished.
3572         *
3573         */
3574         gst_camerasrc_signals[SIGNAL_NEGO_COMPLETE] =
3575                 g_signal_new("nego-complete",
3576                              G_TYPE_FROM_CLASS (klass),
3577                              G_SIGNAL_RUN_LAST,
3578                              G_STRUCT_OFFSET(GstCameraSrcClass, nego_complete),
3579                              NULL,
3580                              NULL,
3581                              gst_marshal_VOID__VOID,
3582                              G_TYPE_NONE, 0);
3583
3584         GST_DEBUG("LEAVED");
3585 }
3586
3587
3588 static void gst_camerasrc_init(GstCameraSrc *camerasrc, GstCameraSrcClass *klass)
3589 {
3590         GST_DEBUG_OBJECT (camerasrc, "ENTERED");
3591
3592         camerasrc->v4l2_handle = NULL;
3593         camerasrc->mode = VIDEO_IN_MODE_UNKNOWN;
3594         camerasrc->firsttime = TRUE;
3595         camerasrc->main_buf_sz = 0;
3596         camerasrc->cap_count_current = -1;
3597         camerasrc->cap_count_reverse = _DEFAULT_CAP_COUNT;
3598         camerasrc->cap_next_time = 0UL;
3599         camerasrc->command_list = g_queue_new ();
3600         camerasrc->cond = g_cond_new ();
3601         camerasrc->mutex = g_mutex_new ();
3602
3603         /*camera*/
3604         camerasrc->width = _DEFAULT_WIDTH;
3605         camerasrc->height = _DEFAULT_HEIGHT;
3606         camerasrc->fps = _DEFAULT_FPS;
3607         camerasrc->rotate = 0;
3608         camerasrc->use_rotate_caps = FALSE;
3609         camerasrc->high_speed_fps = _DEFAULT_HIGH_SPEED_FPS;
3610         camerasrc->fps_auto = _DEFAULT_FPS_AUTO;
3611         camerasrc->pix_format = _DEFAULT_PIX_FORMAT;
3612         camerasrc->colorspace = _DEFAULT_COLORSPACE;
3613         camerasrc->fourcc = _DEFAULT_FOURCC;
3614         camerasrc->req_negotiation = FALSE;
3615         camerasrc->num_live_buffers = _DEFAULT_NUM_LIVE_BUFFER;
3616         camerasrc->buffer_count = _DEFAULT_BUFFER_COUNT;
3617         camerasrc->buffer_running = _DEFAULT_BUFFER_RUNNING;
3618         camerasrc->buffer_lock = g_mutex_new ();
3619         camerasrc->buffer_cond = g_cond_new ();
3620         camerasrc->bfirst = TRUE;
3621         camerasrc->pad_alloc_list = g_queue_new ();
3622         camerasrc->pad_alloc_mutex = g_mutex_new ();
3623         camerasrc->current_buffer_data_index = 0;
3624         camerasrc->sensor_mode = CAMERASRC_SENSOR_MODE_CAMERA;
3625         camerasrc->vflip = 0;
3626         camerasrc->hflip = 0;
3627
3628         /* Initialize usr buffer to be alloced by sink to NULL */
3629         {
3630                 int i = 0;
3631                 for(i = 0; i < MAX_USR_BUFFER_NUM; i++) {
3632                         camerasrc->usr_buffer[i] = NULL;
3633                 }
3634         }
3635         camerasrc->use_pad_alloc = FALSE;
3636         camerasrc->num_alloc_buf = 0;
3637         camerasrc->camera_id = _DEFAULT_CAMERA_ID;
3638
3639         /*capture*/
3640         camerasrc->cap_fourcc = _DEFAULT_FOURCC;
3641         camerasrc->cap_quality = _DEFAULT_CAP_QUALITY;
3642         camerasrc->cap_width = _DEFAULT_CAP_WIDTH;
3643         camerasrc->cap_height = _DEFAULT_CAP_HEIGHT;
3644         camerasrc->cap_interval = _DEFAULT_CAP_INTERVAL;
3645         camerasrc->cap_count = _DEFAULT_CAP_COUNT;
3646         camerasrc->cap_jpg_quality = _DEFAULT_CAP_JPG_QUALITY;
3647         camerasrc->cap_provide_exif = _DEFAULT_CAP_PROVIDE_EXIF;
3648         camerasrc->signal_still_capture = _DEFAULT_SIGNAL_STILL_CAPTURE;
3649         camerasrc->hold_af_after_capturing = FALSE;
3650         camerasrc->create_jpeg = FALSE;
3651         camerasrc->jpg_mutex = g_mutex_new();
3652         camerasrc->first_invokation = TRUE;
3653         camerasrc->external_videofd = _FD_DEFAULT;
3654
3655 #ifdef _SPEED_UP_RAW_CAPTURE
3656         camerasrc->cap_stream_diff = FALSE;
3657 #endif /* _SPEED_UP_RAW_CAPTURE */
3658
3659         /* we operate in time */
3660         gst_base_src_set_format(GST_BASE_SRC(camerasrc), GST_FORMAT_TIME);
3661         gst_base_src_set_live(GST_BASE_SRC(camerasrc), TRUE);
3662         gst_base_src_set_do_timestamp(GST_BASE_SRC(camerasrc), TRUE);
3663
3664         GST_DEBUG("LEAVED");
3665 }
3666
3667
3668 static void GenerateYUV420BlackFrame(unsigned char *buf, int buf_size, int width, int height)
3669 {
3670         int i;
3671         int y_len = 0;
3672         int yuv_len = 0;
3673
3674         y_len = width * height;
3675         yuv_len = (width * height * 3) >> 1;
3676
3677         if (buf_size < yuv_len) {
3678                 return;
3679         }
3680
3681         if (width % 4) {
3682                 for (i = 0 ; i < y_len ; i++) {
3683                         buf[i] = 0x10;
3684                 }
3685
3686                 for ( ; i < yuv_len ; i++) {
3687                         buf[i] = 0x80;
3688                 }
3689         } else {
3690                 /* faster way */
3691                 int *ibuf = NULL;
3692                 short *sbuf = NULL;
3693                 ibuf = (int *)buf;
3694
3695                 for (i = 0 ; i < y_len / 4 ; i++) {
3696                         ibuf[i] = 0x10101010; /* set YYYY */
3697                 }
3698
3699                 sbuf = (short*)(&buf[y_len]);
3700
3701                 for (i = 0 ; i < (yuv_len - y_len) / 2 ; i++) {
3702                         sbuf[i] = 0x8080; /* set UV */
3703                 }
3704         }
3705
3706         return;
3707 }
3708
3709
3710 static void GenerateYUV422BlackFrame(unsigned char *buf, int buf_size, int width, int height)
3711 {
3712         /* YUYV */
3713         int i;
3714         int yuv_len = 0;
3715         int *ibuf = NULL;
3716
3717         ibuf = (int *)buf;
3718
3719         yuv_len = (width * height * 2);
3720
3721         if (buf_size < yuv_len) {
3722                 return;
3723         }
3724
3725         for (i = 0 ; i < yuv_len / 4 ; i++) {
3726                 ibuf[i] = 0x80108010; /* YUYV -> 0xVYUY */
3727         }
3728
3729         return;
3730 }
3731
3732
3733 static gboolean GenerateST12BlackFrame(GstCameraSrc *camerasrc, unsigned char *buf, int buf_size, int width, int height)
3734 {
3735         int i;
3736         int y_len = 0;
3737         int yuv_len = 0;
3738         int ystride = 0;
3739         int uvstride = 0;
3740         int yelevation = 0;
3741         int uvelevation = 0;
3742         gboolean boolret = TRUE;
3743         unsigned char *blkframe = NULL;
3744
3745         /* Calculation of stride. need to be confirmation from driver team */
3746         if ((width % 128) != 0 ) {
3747                 ystride = width + (128 - (width % 128));
3748                 uvstride = ystride;
3749         } else {
3750                 ystride = width;
3751                 uvstride = width;
3752         }
3753
3754         /* Calculation of elevation. need to be confirmation from driver team */
3755         /* Y elevation */
3756         if ((height % 32) != 0) {
3757                 yelevation= height + (32 - (height % 32));
3758         } else {
3759                 yelevation = height;
3760         }
3761         /* UV elevation */
3762         if (((height >>1) % 32) != 0) {
3763                 uvelevation = (height >> 1) + (32 - ((height >> 1) % 32));
3764         } else {
3765                 uvelevation = (height >> 1);
3766         }
3767
3768         GST_DEBUG("ystride = %d and uvstride = %d", ystride, uvstride);
3769         GST_DEBUG("yelevation = %d and uvelevation = %d", yelevation, uvelevation);
3770
3771         y_len = ystride * yelevation;
3772         yuv_len = y_len + uvstride * uvelevation;
3773
3774         /* Generate black frame */
3775         blkframe = (unsigned char*)g_malloc(yuv_len);
3776
3777         if (blkframe == NULL) {
3778                 GST_ERROR ("ST12Blk: Failed to allocate memory...");
3779                 boolret = FALSE;
3780                 goto FINISH;
3781         }
3782
3783         for (i = 0 ; i < y_len ; i++) {
3784                 blkframe [i] = 0x10;
3785         }
3786
3787         for (; i < yuv_len ; i++) {
3788                 blkframe [i] = 0x80;
3789         }
3790
3791
3792 FINISH:
3793         if (blkframe != NULL) {
3794                 g_free (blkframe);
3795         }
3796
3797         return boolret;
3798
3799 }
3800
3801
3802 static unsigned long gst_get_current_time(void)
3803 {
3804         struct timeval lc_time;
3805
3806         gettimeofday(&lc_time, NULL);
3807
3808         return ((unsigned long)(lc_time.tv_sec * 1000L) + (unsigned long)(lc_time.tv_usec / 1000L));
3809 }
3810
3811
3812 #if _ENABLE_CAMERASRC_DEBUG
3813 #include <stdio.h>
3814 static int __util_write_file(char *filename, void *data, int size)
3815 {
3816         FILE *fp = NULL;
3817
3818         fp = fopen(filename, "wb");
3819         if (!fp) {
3820                 return FALSE;
3821         }
3822
3823         fwrite(data, 1, size, fp);
3824         fclose(fp);
3825
3826         return TRUE;
3827 }
3828 #endif
3829
3830
3831 static gboolean plugin_init(GstPlugin *plugin)
3832 {
3833         gboolean error;
3834
3835         error = gst_element_register(plugin, "camerasrc", GST_RANK_PRIMARY + 100, GST_TYPE_CAMERA_SRC);
3836
3837         return error;
3838 }
3839
3840
3841 GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
3842                   GST_VERSION_MINOR,
3843                   "camerasrc",
3844                   "Camera source plug-in",
3845                   plugin_init,
3846                   PACKAGE_VERSION,
3847                   "LGPL",
3848                   "Samsung Electronics Co",
3849                   "http://www.samsung.com")
3850
3851 /* GstURIHandler interface */
3852 static GstURIType gst_camerasrc_uri_get_type (void)
3853 {
3854         return GST_URI_SRC;
3855 }
3856
3857 static gchar ** gst_camerasrc_uri_get_protocols (void)
3858 {
3859         static gchar *protocols[] = { (char *) "camera", NULL };
3860         return protocols;
3861 }
3862
3863 static const gchar * gst_camerasrc_uri_get_uri (GstURIHandler * handler)
3864 {
3865         GstCameraSrc *camerasrc = GST_CAMERA_SRC (handler);
3866
3867         gchar uri[256];
3868         g_snprintf (uri, sizeof (uri), "camera://0");
3869         return g_intern_string (uri);
3870 }
3871
3872 static gboolean gst_camerasrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
3873 {
3874         GstCameraSrc *camerasrc = GST_CAMERA_SRC (handler);
3875         const gchar *device = "0";
3876         if (strcmp (uri, "camera://") != 0) {
3877                 device = uri + 9;
3878         }
3879         g_object_set (camerasrc, "camera-id", atoi(device), NULL);
3880
3881         return TRUE;
3882 }
3883
3884
3885 static void gst_camerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
3886 {
3887         GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
3888
3889         iface->get_type = gst_camerasrc_uri_get_type;
3890         iface->get_protocols = gst_camerasrc_uri_get_protocols;
3891         iface->get_uri = gst_camerasrc_uri_get_uri;
3892         iface->set_uri = gst_camerasrc_uri_set_uri;
3893 }
3894 /* EOF */