4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jeongmo Yang <jm80.yang@samsung.com>
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)
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.
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
29 #include <gst/gstutils.h>
30 #include <glib-object.h>
33 #include <sys/types.h>
36 #include <sched.h> /* sched_yield() */
38 #include "gstcamerasrc.h"
39 #include "gstcamerasrccontrol.h"
40 #include "gstcamerasrccolorbalance.h"
43 /******************************************************************************
45 *******************************************************************************/
46 GST_DEBUG_CATEGORY (camerasrc_debug);
47 #define GST_CAT_DEFAULT camerasrc_debug
49 #define USE_FRAME_SAFETY_MARGIN
51 #if defined (USE_FRAME_SAFETY_MARGIN)
52 #define FRAME_SAFETY_MARGIN 4096
54 #define FRAME_SAFETY_MARGIN 0
58 #define YUV422_SIZE(width,height) ( ((width)*(height)) << 1 )
62 #define YUV420_SIZE(width,height) ( ((width)*(height)*3) >> 1 )
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
73 /* max channel count *********************************************************/
74 #define SCMN_IMGB_MAX_PLANE (4)
76 /* image buffer definition ***************************************************
78 +------------------------------------------+ ---
81 | +---------------------------+ --- | |
83 | |<---------- w[] ---------->| | | |
91 | +---------------------------+ --- | |
93 +------------------------------------------+ ---
95 |<----------------- s[] ------------------>|
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 */
114 /* left postion, if needs */
116 /* top position, if needs */
118 /* to align memory */
124 #if !defined (PAGE_SHIFT)
125 #define PAGE_SHIFT sysconf(_SC_PAGESIZE)
127 #if !defined (PAGE_SIZE)
128 #define PAGE_SIZE (1UL << PAGE_SHIFT)
130 #if !defined (PAGE_MASK)
131 #define PAGE_MASK (~(PAGE_SIZE-1))
133 #if !defined (PAGE_ALIGN)
134 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
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)))
142 #define CLEAR(x) memset(&(x), 0, sizeof(x))
147 #define _ENABLE_CAMERASRC_DEBUG 0
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
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 */
168 #define _FD_DEFAULT (-1)
170 #define _FD_MAX (1<<15) /* 2^15 == 32768 */
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 */
198 #define _THUMBNAIL_WIDTH 320
199 #define _THUMBNAIL_HEIGHT 240
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())
210 SIGNAL_STILL_CAPTURE,
211 SIGNAL_NEGO_COMPLETE,
212 /*SIGNAL_REGISTER_TROUBLE,*/
219 ARG_CAMERA_HIGH_SPEED_FPS,
222 ARG_CAMERA_EXT_VIDEO_FD,
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,
235 ARG_SIGNAL_STILLCAPTURE,
240 ARG_OPERATION_STATUS,
241 ARG_HOLD_AF_AFTER_CAPTURE,
250 VIDEO_IN_MODE_UNKNOWN,
251 VIDEO_IN_MODE_PREVIEW,
253 VIDEO_IN_MODE_CAPTURE,
259 gint buffer_data_index;
260 GstCameraSrc *camerasrc;
261 } GST_CAMERASRC_BUFFER_DATA;
263 static void gst_camerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
265 /* Local variables */
266 static GstBufferClass *camera_buffer_parent_class = NULL;
268 static guint gst_camerasrc_signals[LAST_SIGNAL] = { 0 };
270 /* For pad_alloc architecture */
271 static camerasrc_usr_buf_t g_present_buf;
273 #if _ENABLE_CAMERASRC_DEBUG
274 static unsigned int g_preview_frame_cnt;
277 /* Element template variables */
278 static GstStaticPadTemplate src_factory =
279 GST_STATIC_PAD_TEMPLATE("src",
282 GST_STATIC_CAPS("video/x-raw-yuv,"
283 "format = (fourcc) { UYVY }, "
284 "width = (int) [ 1, 4096 ], "
285 "height = (int) [ 1, 4096 ]; "
287 "format = (fourcc) { YU12 }, "
288 "width = (int) [ 1, 4096 ], "
289 "height = (int) [ 1, 4096 ]; "
291 "format = (fourcc) { I420 }, "
292 "width = (int) [ 1, 4096 ], "
293 "height = (int) [ 1, 4096 ]; "
295 "format = (fourcc) { NV12 }, "
296 "width = (int) [ 1, 4096 ], "
297 "height = (int) [ 1, 4096 ]; "
299 "format = (fourcc) { SN12 }, "
300 "width = (int) [ 1, 4096 ], "
301 "height = (int) [ 1, 4096 ]; "
303 "format = (fourcc) { ST12 }, "
304 "width = (int) [ 1, 4096 ], "
305 "height = (int) [ 1, 4096 ]; "
307 "format = (fourcc) { YUY2 }, "
308 "width = (int) [ 1, 4096 ], "
309 "height = (int) [ 1, 4096 ]; "
311 "format = (fourcc) { YUYV }, "
312 "width = (int) [ 1, 4096 ], "
313 "height = (int) [ 1, 4096 ]; "
315 "format = (fourcc) { SUYV }, "
316 "width = (int) [ 1, 4096 ], "
317 "height = (int) [ 1, 4096 ]; "
319 "format = (fourcc) { SUY2 }, "
320 "width = (int) [ 1, 4096 ], "
321 "height = (int) [ 1, 4096 ]; "
323 "format = (fourcc) { SYVY }, "
324 "width = (int) [ 1, 4096 ], "
325 "height = (int) [ 1, 4096 ]; "
327 "format = (fourcc) { S420 }, "
328 "width = (int) [ 1, 4096 ], "
329 "height = (int) [ 1, 4096 ]; "
331 "width = (int) [ 1, 4096 ], "
332 "height = (int) [ 1, 4096 ]"));
334 static GstElementDetails camerasrc_details = {
335 "Camera Source GStreamer Plug-in",
337 "camera src for videosrc based GStreamer Plug-in",
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);
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);
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);
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);
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);
369 static gboolean gst_camerasrc_capture_start(GstCameraSrc *camerasrc);
370 static gboolean gst_camerasrc_capture_stop(GstCameraSrc *camerasrc);
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);
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);
395 GST_IMPLEMENT_CAMERASRC_COLOR_BALANCE_METHODS(GstCameraSrc, gst_camera_src);
396 GST_IMPLEMENT_CAMERASRC_CONTROL_METHODS(GstCameraSrc, gst_camera_src);
399 /******************************************************************************
401 *******************************************************************************/
402 static void gst_camerasrc_error_handler(GstCameraSrc *camerasrc, int ret)
405 case CAMERASRC_SUCCESS:
407 case CAMERASRC_ERR_IO_CONTROL:
408 GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("IO control error"), GST_ERROR_SYSTEM);
410 case CAMERASRC_ERR_DEVICE_OPEN:
411 GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ_WRITE, ("camera open failed"), GST_ERROR_SYSTEM);
413 case CAMERASRC_ERR_DEVICE_BUSY:
414 GST_ELEMENT_ERROR(camerasrc, RESOURCE, BUSY, ("camera device busy"), GST_ERROR_SYSTEM);
416 case CAMERASRC_ERR_DEVICE_NOT_FOUND:
417 GST_ELEMENT_ERROR(camerasrc, RESOURCE, NOT_FOUND, ("camera device not found"), GST_ERROR_SYSTEM);
419 case CAMERASRC_ERR_DEVICE_UNAVAILABLE:
420 GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ, ("camera device unavailable"), GST_ERROR_SYSTEM);
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);
426 case CAMERASRC_ERR_DEVICE_NOT_SUPPORT:
427 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("Not supported"), GST_ERROR_SYSTEM);
429 case CAMERASRC_ERR_ALLOCATION:
430 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("memory allocation failed"), GST_ERROR_SYSTEM);
432 case CAMERASRC_ERR_SECURITY_SERVICE:
433 GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("Security service failed"), GST_ERROR_SYSTEM);
436 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SEEK, (("General video device error[ret=%x]"), ret), GST_ERROR_SYSTEM);
443 static gboolean gst_camerasrc_iface_supported(GstImplementsInterface *iface, GType iface_type)
445 g_assert(iface_type == GST_TYPE_CAMERA_CONTROL ||
446 iface_type == GST_TYPE_COLOR_BALANCE);
452 static void gst_camerasrc_interface_init(GstImplementsInterfaceClass *klass)
455 * default virtual functions
457 klass->supported = gst_camerasrc_iface_supported;
461 void gst_camerasrc_init_interfaces(GType type)
463 static const GInterfaceInfo urihandler_info = {
464 gst_camerasrc_uri_handler_init,
469 static const GInterfaceInfo cameraiface_info = {
470 (GInterfaceInitFunc)gst_camerasrc_interface_init,
475 static const GInterfaceInfo camerasrc_control_info = {
476 (GInterfaceInitFunc)gst_camera_src_control_interface_init,
481 static const GInterfaceInfo camerasrc_color_balance_info = {
482 (GInterfaceInitFunc)gst_camera_src_color_balance_interface_init,
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);
494 static GType gst_camerasrc_quality_get_type(void)
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"},
503 if (!camerasrc_quality_type) {
504 camerasrc_quality_type = g_enum_register_static ("GstCameraSrcQuality", quality_types);
506 return camerasrc_quality_type;
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)
518 typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT)(gpointer data1,
523 register GMarshalFunc_VOID__OBJECT_OBJECT callback;
524 register GCClosure *cc = (GCClosure*) closure;
525 register gpointer data1, data2;
527 g_return_if_fail (n_param_values == 4);
529 if (G_CCLOSURE_SWAP_DATA(closure)) {
530 data1 = closure->data;
531 data2 = g_value_peek_pointer(param_values + 0);
533 data1 = g_value_peek_pointer(param_values + 0);
534 data2 = closure->data;
537 callback = (GMarshalFunc_VOID__OBJECT_OBJECT)(marshal_data ? marshal_data : cc->callback);
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),
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);
551 static int gst_camerasrc_af_cb(camsrc_handle_t handle, int state, void *usr_param)
553 GstCameraSrc *camerasrc = (GstCameraSrc *)usr_param;
554 GstMessage *m = NULL;
555 GstStructure *s = NULL;
557 MMTA_ACUM_ITEM_END("AutoFocus operating time", FALSE);
559 GST_INFO_OBJECT(camerasrc, "autofocus callback: state [%d]", state);
561 s = gst_structure_new("camerasrc-AF",
562 "focus-state", G_TYPE_INT, state,
564 m = gst_message_new_element(GST_OBJECT(camerasrc), s);
565 gst_element_post_message(GST_ELEMENT(camerasrc), m);
567 return CAMERASRC_SUCCESS;
571 static gboolean gst_camerasrc_create(GstCameraSrc *camerasrc)
576 __ta__(" camerasrc_create",
577 ret = camerasrc_create(&(camerasrc->v4l2_handle));
579 if (ret != CAMERASRC_SUCCESS) {
580 GST_ERROR_OBJECT(camerasrc, "camerasrc_create() failed. errcode = 0x%08X", ret);
584 GST_INFO_OBJECT (camerasrc, "camerasrc_create() done");
586 if (camerasrc->external_videofd != _FD_DEFAULT) {
587 __ta__(" camerasrc_set_videofd",
588 camerasrc_set_videofd(camerasrc->v4l2_handle,camerasrc->external_videofd);
592 /*CAMERASRC CAM: realize*/
593 __ta__(" camerasrc_realize",
594 ret = camerasrc_realize(camerasrc->v4l2_handle);
596 if (ret != CAMERASRC_SUCCESS) {
600 GST_INFO_OBJECT (camerasrc, "camerasrc_realize() done");
602 /*CAMERASRC CAM: start*/
603 __ta__(" camerasrc_start",
604 ret = camerasrc_start(camerasrc->v4l2_handle);
606 if (ret != CAMERASRC_SUCCESS) {
607 GST_ERROR_OBJECT(camerasrc, "camerasrc_start() failed. errcode = 0x%x", ret);
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);
616 if (ret != CAMERASRC_SUCCESS) {
617 GST_ERROR_OBJECT(camerasrc, "camerasrc_set_input() failed. errcode = 0x%x", ret);
621 if (!gst_camerasrc_fill_ctrl_list(camerasrc)) {
622 GST_WARNING_OBJECT(camerasrc, "Can't fill v4l2 control list.");
628 gst_camerasrc_error_handler(camerasrc, ret);
634 static gboolean gst_camerasrc_destroy(GstCameraSrc *camerasrc)
636 GST_INFO_OBJECT (camerasrc, "ENTERED");
638 if (camerasrc->v4l2_handle) {
639 /*Empty control list */
640 gst_camerasrc_empty_ctrl_list(camerasrc);
642 /*CAMERASRC CAM: stop stream*/
643 /*CAMERASRC CAM: unrealize*/
644 GST_INFO_OBJECT(camerasrc, "camerasrc_unrealize() calling...");
645 camerasrc_unrealize(camerasrc->v4l2_handle);
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;
655 GST_INFO_OBJECT(camerasrc, "LEAVED");
661 static gboolean gst_camerasrc_fill_ctrl_list(GstCameraSrc *camerasrc)
664 camerasrc_ctrl_info_t ctrl_info;
666 g_return_val_if_fail(camerasrc, FALSE);
667 g_return_val_if_fail(camerasrc->v4l2_handle, FALSE);
669 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
671 for (n = CAMERASRC_CTRL_BRIGHTNESS ; n < CAMERASRC_CTRL_NUM ; n++) {
672 GstCameraSrcColorBalanceChannel *camerasrc_color_channel = NULL;
673 GstColorBalanceChannel *color_channel = NULL;
675 GstCamerasrcControlChannel *camerasrc_control_channel = NULL;
676 GstCameraControlChannel *control_channel = NULL;
680 memset(&ctrl_info, 0x0, sizeof(camerasrc_ctrl_info_t));
682 if (camerasrc_query_control(camerasrc->v4l2_handle, n, &ctrl_info) != CAMERASRC_SUCCESS) {
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;
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;
707 channel_type = INTERFACE_NONE;
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);
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;
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);
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;
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);
738 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
744 static gboolean gst_camerasrc_empty_ctrl_list(GstCameraSrc *camerasrc)
746 g_return_val_if_fail(camerasrc, FALSE);
748 GST_DEBUG_OBJECT (camerasrc, "ENTERED");
750 g_list_foreach(camerasrc->colors, (GFunc)g_object_unref, NULL);
751 g_list_free(camerasrc->colors);
752 camerasrc->colors = NULL;
754 g_list_foreach(camerasrc->camera_controls, (GFunc)g_object_unref, NULL);
755 g_list_free(camerasrc->camera_controls);
756 camerasrc->camera_controls = NULL;
758 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
764 static GstFlowReturn gst_camerasrc_prepare_preview(GstCameraSrc *camerasrc, int buf_num)
766 int page_size = getpagesize();
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));
774 g_return_val_if_fail(buf_num <= MAX_USR_BUFFER_NUM, GST_FLOW_ERROR);
776 camerasrc_query_img_buf_size(camerasrc->v4l2_handle, &main_buf_sz, &thumb_buf_sz);
778 buffer_size = (main_buf_sz + page_size - 1) & ~(page_size - 1);
780 g_present_buf.present_buffer = calloc(buf_num, sizeof(camerasrc_buffer_t));
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),
788 &(camerasrc->usr_buffer[i]));
790 if (!GST_IS_BUFFER(camerasrc->usr_buffer[i])) {
791 GST_INFO_OBJECT (camerasrc, "[%d] NOT BUFFER!!?", i);
793 if (ret != GST_FLOW_OK) {
794 GST_ERROR_OBJECT (camerasrc, "gst_pad_alloc_buffer failed. [%d]", ret);
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]));
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;
806 g_present_buf.num_buffer = buf_num;
808 gst_caps_unref(negotiated_caps);
809 negotiated_caps = NULL;
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);
815 GST_INFO_OBJECT(camerasrc, "present_buffer success");
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);
824 return GST_FLOW_ERROR;
827 GST_INFO_OBJECT(camerasrc, "camerasrc_start_preview_stream() done");
829 camerasrc->buffer_running = TRUE;
830 camerasrc->buffer_count = buf_num;
831 camerasrc->first_invokation = TRUE;
837 static gboolean gst_camerasrc_start(GstCameraSrc *camerasrc)
841 camerasrc_format_t fmt;
842 camerasrc_frac_t frac;
844 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
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;
854 camerasrc->cap_stream_diff = FALSE;
857 /**@note do not setting at camer starting time*/
858 /*CAMERASRC CAM: set FILTER (by default value)*/
860 /*CAMERASRC CAM: callback*/
861 camerasrc_set_focused_callback(camerasrc->v4l2_handle, gst_camerasrc_af_cb, camerasrc);
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;
872 /*CAMERASRC CAM: set resolution - Do not care about rotation */
873 CAMERASRC_SET_SIZE_BY_DIMENSION(fmt, camerasrc->width, camerasrc->height);
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);
885 /*CAMERASRC CAM: set fps*/
886 if (camerasrc->fps_auto) {
887 /*if fps is zero, auto fps mode*/
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*/
895 frac.denominator = 1;
898 frac.denominator = camerasrc->fps;
901 GST_INFO_OBJECT(camerasrc, "high speed recording(%d)", camerasrc->high_speed_fps);
903 frac.denominator = camerasrc->high_speed_fps;
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);
911 GST_INFO_OBJECT (camerasrc, "camerasrc_set_timeperframe() done");
913 camerasrc->buffer_running = TRUE;
915 if ((camerasrc->use_pad_alloc == FALSE)) {
916 /*CAMERASRC CAM: Set Sensor mode*/
917 camerasrc_set_sensor_mode(camerasrc->v4l2_handle, camerasrc->sensor_mode);
919 /*CAMERASRC CAM: Set flip*/
920 camerasrc_set_vflip(camerasrc->v4l2_handle, camerasrc->vflip);
921 camerasrc_set_hflip(camerasrc->v4l2_handle, camerasrc->hflip);
923 /*CAMERASRC CAM: start video preview*/
924 __ta__(" camerasrc_start_preview_stream",
925 ret = camerasrc_start_preview_stream(camerasrc->v4l2_handle);
927 if (ret != CAMERASRC_SUCCESS) {
928 GST_ERROR_OBJECT(camerasrc, "camerasrc_start_preview_stream() failed. errcode = 0x%x", ret);
929 camerasrc->buffer_running = FALSE;
933 GST_INFO_OBJECT(camerasrc, "camerasrc_start_preview_stream() done");
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);
941 GST_INFO_OBJECT(camerasrc, "buffer number %d", camerasrc->buffer_count);
942 #ifdef _SPEED_UP_RAW_CAPTURE
943 camerasrc->cap_stream_diff = FALSE;
947 #ifdef _SPEED_UP_RAW_CAPTURE
950 camerasrc->mode = VIDEO_IN_MODE_PREVIEW;
951 camerasrc->current_buffer_data_index = (camerasrc->current_buffer_data_index + 1)%10;
953 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
958 gst_camerasrc_error_handler(camerasrc, ret);
961 camerasrc_stop_stream(camerasrc->v4l2_handle);
963 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
969 static gboolean gst_camerasrc_stop(GstCameraSrc *camerasrc)
971 camerasrc_io_method_t io_method;
973 GST_DEBUG_OBJECT (camerasrc, "ENTERED");
975 if (camerasrc->v4l2_handle) {
976 /* CAMERASRC CAM: stop stream */
977 /* To guarantee buffers are valid before finishing */
978 GMutex *lock_mutex = NULL;
980 if (camerasrc->use_pad_alloc == FALSE) {
981 lock_mutex = camerasrc->buffer_lock;
983 lock_mutex = camerasrc->pad_alloc_mutex;
986 g_mutex_lock(lock_mutex);
987 while (camerasrc->num_live_buffers > _DEFAULT_KEEPING_BUFFER) {
989 GST_INFO_OBJECT(camerasrc, "Wait until all live buffers are relased. (Tot=%d, Live=%d)",
990 camerasrc->buffer_count, camerasrc->num_live_buffers);
992 g_get_current_time(&abstimeout);
993 g_time_val_add(&abstimeout, _PREVIEW_BUFFER_WAIT_TIMEOUT);
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);
1001 GST_INFO_OBJECT(camerasrc, "Signal received.");
1004 g_mutex_unlock(lock_mutex);
1005 GST_INFO_OBJECT(camerasrc, "Waiting free buffer finished. (Live=%d)", camerasrc->num_live_buffers);
1007 camerasrc_stop_stream(camerasrc->v4l2_handle);
1009 camerasrc->buffer_running = FALSE;
1010 camerasrc->mode = VIDEO_IN_MODE_UNKNOWN;
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 */
1015 camerasrc_get_io_method(camerasrc->v4l2_handle, &io_method);
1016 switch (io_method) {
1017 case CAMERASRC_IO_METHOD_MMAP:
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;
1025 case CAMERASRC_IO_METHOD_READ:
1031 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
1037 static gboolean gst_camerasrc_capture_start(GstCameraSrc *camerasrc)
1041 char *pfourcc = NULL;
1042 camerasrc_format_t fmt;
1043 camerasrc_frac_t frac;
1045 GST_INFO_OBJECT(camerasrc, "ENTERED");
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);
1057 g_get_current_time(&abstimeout);
1058 g_time_val_add(&abstimeout, _PREVIEW_BUFFER_WAIT_TIMEOUT);
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);
1066 GST_INFO_OBJECT(camerasrc, "Signal received.");
1069 g_mutex_unlock(camerasrc->buffer_lock);
1070 GST_INFO_OBJECT(camerasrc, "Waiting free buffer is finished. (Live=%d)", camerasrc->num_live_buffers);
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;
1083 camerasrc->cap_stream_diff = TRUE;
1086 /*CAMERASRC CAM: stop stream*/
1087 __ta__( " camerasrc_stop_stream in gst_camerasrc_capture_start",
1088 camerasrc_stop_stream(camerasrc->v4l2_handle);
1091 GST_INFO_OBJECT (camerasrc, "camerasrc_stop_stream() done");
1092 camerasrc->buffer_running = FALSE;
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);
1100 /*START STILL CAPTURE*/
1102 /*set current video info*/
1104 memset(&fmt, 0x00, sizeof (camerasrc_format_t));
1106 /*CAMERASRC CAM: set format*/
1107 CAMERASRC_SET_SIZE_BY_DIMENSION(fmt, camerasrc->cap_width, camerasrc->cap_height);
1109 _gst_camerasrc_get_raw_pixel_info(camerasrc->cap_fourcc, &(fmt.pix_format), &(fmt.colorspace));
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*/
1117 fmt.is_highquality_mode = camerasrc->cap_quality; /*0 or 1 (default: 0)*/
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);
1126 GST_INFO_OBJECT(camerasrc, "camerasrc_set_format() done");
1128 if (camerasrc->fps_auto || camerasrc->fps <= 0) {
1129 /*if fps is zero, auto fps mode*/
1131 frac.denominator = 1;
1132 GST_INFO_OBJECT (camerasrc, "FPS auto");
1135 frac.denominator = camerasrc->fps;
1136 GST_INFO_OBJECT (camerasrc, "FPS (%d)", camerasrc->fps);
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);
1144 GST_INFO_OBJECT (camerasrc, "camerasrc_set_timeperframe() done");
1146 /*CAMERASRC CAM: start stream*/
1147 __ta__( " camerasrc_start_still_stream",
1148 ret = camerasrc_start_still_stream(camerasrc->v4l2_handle);
1150 if (ret != CAMERASRC_SUCCESS) {
1151 GST_ERROR_OBJECT(camerasrc, "camerasrc_start_still_stream() failed. errcode = 0x%x", ret);
1154 GST_INFO_OBJECT(camerasrc, "camerasrc_start_still_stream() done");
1156 camerasrc->buffer_running = TRUE;
1158 /*CAMERASRC CAM: set fps*/
1159 /*TODO: maybe do not works!*/
1161 #ifdef _SPEED_UP_RAW_CAPTURE
1162 _CAPTURE_READY_DONE:
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;
1170 /* end change to capture mode*/
1171 camerasrc->mode = VIDEO_IN_MODE_CAPTURE;
1173 GST_INFO_OBJECT(camerasrc, "CAPTURE STARTED!");
1175 GST_WARNING_OBJECT(camerasrc, "Wrong state[%d]!", camerasrc->mode);
1178 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
1183 gst_camerasrc_error_handler(camerasrc, ret);
1189 static gboolean gst_camerasrc_capture_stop(GstCameraSrc *camerasrc)
1191 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
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;
1200 GST_INFO_OBJECT(camerasrc, "camerasrc_stop_stream() done");
1202 GST_INFO_OBJECT(camerasrc, "no need to stop stream(capture format==preview format)");
1205 /*CAMERASRC CAM: stop stream*/
1206 camerasrc_stop_stream(camerasrc->v4l2_handle);
1207 camerasrc->buffer_running = FALSE;
1209 GST_INFO_OBJECT(camerasrc, "camerasrc_stop_stream() done");
1211 GST_INFO_OBJECT(camerasrc, "CAPTURE STOPPED!");
1214 GST_DEBUG_OBJECT (camerasrc, "LEAVED");
1220 static GstFlowReturn gst_camerasrc_read_preview_mmap(GstCameraSrc *camerasrc, GstBuffer **buffer)
1223 int v4l2_buffer_index = 0;
1225 unsigned int isize = 0;
1226 unsigned char *pData = NULL;
1228 camerasrc_buffer_t main_buf;
1229 GstCameraBuffer *vid_buf = NULL;
1231 /*alloc main buffer*/
1232 vid_buf = gst_camerasrc_buffer_new(camerasrc);
1233 buf = (GstCameraBuffer *)vid_buf;
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);
1239 for (i = 0 ; i < _MAX_TRIAL_WAIT_FRAME ; i++) {
1241 __ta__( " camerasrc_wait_frame_available",
1242 ret = camerasrc_wait_frame_available(camerasrc->v4l2_handle, _DEFAULT_DEQUE_WAITINGTIME);
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);
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);
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...");
1261 GST_ERROR_OBJECT(camerasrc, "Frame waiting error[%x]", ret);
1262 g_mutex_unlock(camerasrc->buffer_lock);
1263 gst_camerasrc_error_handler(camerasrc, ret);
1265 return GST_FLOW_ERROR;
1268 GST_LOG_OBJECT(camerasrc, "select success, do DQBUF");
1274 __ta__( " camerasrc_dequeue_buffer",
1275 ret = camerasrc_dequeue_buffer(camerasrc->v4l2_handle, &v4l2_buffer_index, &main_buf, NULL);
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);
1282 return GST_FLOW_ERROR;
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);
1289 g_mutex_unlock (camerasrc->buffer_lock);
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);
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,
1309 g_mutex_unlock( camerasrc->buffer_lock );
1310 return GST_FLOW_ERROR;
1313 vid_buf->is_alloc_data = TRUE;
1315 pData = main_buf.start;
1316 isize = main_buf.length;
1319 GST_BUFFER_DATA(vid_buf) = pData;
1320 GST_BUFFER_SIZE(vid_buf) = isize;
1321 vid_buf->v4l2_buffer_index = v4l2_buffer_index;
1323 if (camerasrc->firsttime) {
1324 /** Because of basesrc negotiation , "framerate" field is needed. */
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;
1332 if (camerasrc->fps <= 0) {
1333 /*if fps is zero, auto fps mode*/
1338 fps_de = camerasrc->fps;
1341 GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]",
1342 camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps);
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,
1351 GST_ERROR_OBJECT(camerasrc, "failed to alloc caps");
1352 gst_buffer_unref((GstBuffer *)vid_buf);
1355 return GST_FLOW_ERROR;
1358 if (camerasrc->use_rotate_caps) {
1359 gst_caps_set_simple(caps, "rotate", G_TYPE_INT, camerasrc->rotate, NULL);
1362 GST_BUFFER_CAPS(buf) = caps;
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);
1368 g_free(caps_string);
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);
1382 camerasrc->firsttime = FALSE;
1385 gst_camerasrc_get_timeinfo(camerasrc, (GstBuffer*)vid_buf);
1387 *buffer = (GstBuffer*)vid_buf;
1389 /*GST_DEBUG_OBJECT(camerasrc, "refcount: %d", GST_OBJECT_REFCOUNT(*buffer));*/
1391 #if _ENABLE_CAMERASRC_DEBUG
1392 g_preview_frame_cnt++;
1399 static GstFlowReturn gst_camerasrc_read_preview_pad_alloc(GstCameraSrc *camerasrc, GstBuffer **buffer)
1402 int v4l2_buffer_index = 0;
1404 guint cnt_again = _MAX_PAD_ALLOC_RETRY_COUNT;
1406 camerasrc_buffer_t main_buf;
1407 GstBuffer *gst_buf = NULL;
1408 GST_CAMERASRC_BUFFER_DATA *buffer_data = NULL;
1410 /*alloc main buffer*/
1412 buf = (GstBuffer *)gst_buf;
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);
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;
1426 g_mutex_unlock (camerasrc->pad_alloc_mutex);
1428 camerasrc_buffer.start = NULL;
1429 camerasrc_buffer.length = 0;
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);
1435 GST_LOG_OBJECT (camerasrc, "Index queue have item. pad_alloc_index = %d", pad_alloc_index);
1437 negotiated_caps = gst_pad_get_negotiated_caps (GST_BASE_SRC_PAD (camerasrc));
1439 /* pad allocation from sink(or any where) */
1440 ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD (camerasrc),
1442 camerasrc->main_buf_sz,
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);
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);
1459 return GST_FLOW_ERROR;
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);
1467 GST_LOG_OBJECT(camerasrc, "gst_pad_alloc_buffer called. index = %d, GstBuffer address = %p",
1468 proper_index, &(camerasrc->usr_buffer[pad_alloc_index]));
1470 camerasrc->usr_buffer[proper_index] = pad_alloc_buffer;
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]));
1475 camerasrc_buffer.length = PAGE_ALIGN(camerasrc_buffer.length);
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);
1482 return GST_FLOW_ERROR;
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);
1490 return GST_FLOW_ERROR;
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);
1500 return GST_FLOW_ERROR;
1503 gst_caps_unref(negotiated_caps);
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);
1510 g_mutex_unlock(camerasrc->pad_alloc_mutex);
1512 ret = camerasrc_wait_frame_available(camerasrc->v4l2_handle, _PAD_ALLOC_RETRY_PERIOD);
1513 if (ret == CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT) {
1515 if ((cnt_again % 100) == 0) {
1516 GST_LOG_OBJECT (camerasrc, "Check ESD......");
1519 ret = camerasrc_check_esd_shock(camerasrc->v4l2_handle, &is_esd);
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);
1526 gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_UNAVAILABLE);
1528 return GST_FLOW_ERROR;
1533 GST_LOG_OBJECT (camerasrc, "Check ESD......");
1536 ret = camerasrc_check_esd_shock(camerasrc->v4l2_handle, &is_esd);
1538 /* Not ESD situation */
1539 GST_LOG_OBJECT(camerasrc, "Not ESD situation. normal timeout");
1540 g_mutex_unlock(camerasrc->buffer_lock);
1542 gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT);
1544 return GST_FLOW_WRONG_STATE;
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);
1551 gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_DEVICE_UNAVAILABLE);
1553 return GST_FLOW_ERROR;
1556 GST_ERROR_OBJECT(camerasrc, "Time out retried [%d] times %d", _MAX_PAD_ALLOC_RETRY_COUNT - cnt_again + 1);
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);
1562 return GST_FLOW_ERROR;
1566 __ta__( " camerasrc_dequeue_buffer",
1567 ret = camerasrc_dequeue_buffer(camerasrc->v4l2_handle, &v4l2_buffer_index, &main_buf, NULL);
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);
1574 return GST_FLOW_ERROR;
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);
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;
1589 GST_LOG_OBJECT(camerasrc, "Start to set up buffer free structure");
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;
1597 buffer_data->camerasrc = camerasrc;
1598 buffer_data->index = v4l2_buffer_index;
1599 buffer_data->buffer_data_index = camerasrc->current_buffer_data_index;
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;
1606 GST_LOG_OBJECT(camerasrc, "End to set up buffer free structure");
1609 if (camerasrc->firsttime) {
1610 /* Because of basesrc negotiation , "framerate" field is needed. */
1613 gchar *caps_string = NULL;
1614 GstCaps *caps = NULL;
1616 if (camerasrc->fps <= 0) {
1617 /*if fps is zero, auto fps mode*/
1622 fps_de = camerasrc->fps;
1625 GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]",
1626 camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps);
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,
1635 GST_ERROR_OBJECT(camerasrc, "failed to alloc caps");
1636 return GST_FLOW_ERROR;
1639 if (camerasrc->use_rotate_caps) {
1640 gst_caps_set_simple(caps, "rotate", G_TYPE_INT, camerasrc->rotate, NULL);
1643 GST_BUFFER_CAPS(gst_buf) = caps;
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);
1649 g_free(caps_string);
1653 camerasrc->firsttime = FALSE;
1656 gst_camerasrc_get_timeinfo(camerasrc, gst_buf);
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);
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);
1670 /* Remove all item */
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!");
1675 g_mutex_unlock(camerasrc->pad_alloc_mutex);
1676 g_mutex_lock(camerasrc->pad_alloc_mutex);
1679 g_mutex_unlock(camerasrc->pad_alloc_mutex);
1680 g_mutex_lock(camerasrc->pad_alloc_mutex);
1681 camerasrc->first_invokation = FALSE;
1683 g_mutex_unlock (camerasrc->pad_alloc_mutex);
1685 #if _ENABLE_CAMERASRC_DEBUG
1686 g_preview_frame_cnt++;
1693 static GstFlowReturn gst_camerasrc_draw_black_preview(GstCameraSrc *camerasrc, GstBuffer **buffer)
1697 guint fakebuflen = 0;
1698 GstBuffer *gst_buf = NULL;
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);
1711 GST_DEBUG_OBJECT(camerasrc, "Wrong fourcc(%x)", camerasrc->fourcc);
1715 GST_DEBUG_OBJECT(camerasrc, "gst_camerasrc_draw_black_preview (data=%p, len=%d)",
1716 GST_BUFFER_MALLOCDATA(gst_buf), fakebuflen);
1718 Because of basesrc negotiation , "framerate" field is needed.
1720 if (camerasrc->fps <= 0) {
1721 /*if fps is zero, auto fps mod e*/
1726 fps_de = camerasrc->fps;
1729 GST_INFO_OBJECT(camerasrc, "FPS auto[%d], FPS[%d], High speed FPS[%d]",
1730 camerasrc->fps_auto, camerasrc->fps, camerasrc->high_speed_fps);
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,
1739 GST_DEBUG_OBJECT(camerasrc, "PREVIEW MODE first time [%d] [%d]", camerasrc->width, camerasrc->height);
1740 gst_camerasrc_get_timeinfo(camerasrc, gst_buf);
1747 static GstFlowReturn gst_camerasrc_read_capture(GstCameraSrc *camerasrc, GstBuffer **buffer, int command)
1750 int buffer_index = 0;
1751 unsigned long cur_time;
1752 gboolean is_jpeg = FALSE;
1754 static gboolean get_stop_command = FALSE;
1755 static gboolean get_stop_multi_command = FALSE;
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*/
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*/
1766 GST_DEBUG_OBJECT(camerasrc, "ENTERED. Command[%d]", command);
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 );
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;
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);
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);
1788 GST_INFO_OBJECT(camerasrc, "Capture finished.");
1790 __ta__( " capture: gst_camerasrc_capture_stop",
1791 gst_camerasrc_capture_stop(camerasrc);
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;
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);
1807 GST_INFO_OBJECT(camerasrc, "End : Wait for Capture stop signal");
1811 __ta__(" capture: gst_camerasrc_start",
1812 gst_camerasrc_start(camerasrc);
1815 __ta__(" capture: one gst_camerasrc_read_preview_mmap",
1816 ret = gst_camerasrc_read_preview_mmap(camerasrc, buffer);
1819 get_stop_command = FALSE;
1820 get_stop_multi_command = FALSE;
1822 g_mutex_unlock(camerasrc->mutex);
1824 MMTA_ACUM_ITEM_END( " Shot to Shot in gstcamerasrc", FALSE);
1829 if (camerasrc->cap_fourcc == GST_MAKE_FOURCC('J','P','E','G') ||
1830 camerasrc->cap_fourcc == GST_MAKE_FOURCC('j','p','e','g')) {
1837 *@important JPEG still: always same image generated by camerasrc_read_frame.
1838 * if you want to multi shot, set YUV format !
1840 __ta__(" camerasrc_read_frame:select,DQ,Copy,Q",
1841 ret = camerasrc_read_frame(camerasrc->v4l2_handle, &main_buf, &thumb_buf, &buffer_index);
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;
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; */
1855 gst_camerasrc_error_handler(camerasrc, ret);
1857 return GST_FLOW_ERROR;
1861 /* Get screennail buffer */
1862 scrnl_buf.start = NULL;
1863 scrnl_buf.length = 0;
1864 camerasrc_get_screennail_buffer(camerasrc->v4l2_handle, &scrnl_buf);
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);
1871 CHECK_CAPTURE_INTERVAL:
1873 cur_time = gst_get_current_time();
1875 if (camerasrc->cap_next_time == 0UL) {
1876 camerasrc->cap_next_time = cur_time;
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);
1883 camerasrc->cap_next_time = cur_time + camerasrc->cap_interval;
1884 camerasrc->cap_count_reverse--;
1885 camerasrc->cap_count_current++;
1887 /* alloc buffer for capture callback */
1888 buf_cap_signal1 = gst_buffer_new ();
1890 /* make buffers for capture callback and display(raw format) */
1892 GST_INFO_OBJECT (camerasrc, "JPEG CAPTURE MODE");
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,
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,
1910 buf_cap_signal2 = NULL;
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,
1923 buf_cap_signal3 = NULL;
1928 unsigned char *pMetaData = NULL;
1930 GST_INFO_OBJECT (camerasrc, "RAW CAPTURE MODE");
1932 /*alloc main buffer*/
1933 buf = gst_camerasrc_buffer_new(camerasrc);;
1935 GST_ERROR_OBJECT(camerasrc, "Buffer alloc failed.");
1937 gst_camerasrc_error_handler(camerasrc, CAMERASRC_ERR_ALLOCATION);
1938 return GST_FLOW_ERROR;
1941 pMetaData = gst_camerasrc_make_metadata_for_nonlinear_buffer(camerasrc, buffer_index);
1943 GST_ERROR_OBJECT(camerasrc, "Error on making metadata");
1946 GST_BUFFER_MALLOCDATA(buf) = pMetaData;
1947 buf->v4l2_buffer_index = buffer_index;
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));
1957 g_mutex_unlock( camerasrc->buffer_lock );
1958 return GST_FLOW_ERROR;
1961 buf->is_alloc_data = TRUE;
1963 GST_BUFFER_DATA(buf) = main_buf.start;
1964 GST_BUFFER_SIZE(buf) = main_buf.length;
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));
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,
1978 buf_cap_signal2 = NULL;
1979 buf_cap_signal3 = NULL;
1983 GST_INFO_OBJECT (camerasrc, "CALL: capture callback");
1985 g_signal_emit( G_OBJECT (camerasrc),
1986 gst_camerasrc_signals[SIGNAL_STILL_CAPTURE],
1992 GST_INFO_OBJECT (camerasrc, "RETURN: capture callback");
1995 (!is_jpeg && (camerasrc->fourcc != camerasrc->cap_fourcc ||
1996 camerasrc->width != camerasrc->cap_width ||
1997 camerasrc->height != camerasrc->cap_height))) {
1999 camerasrc_queue_buffer(camerasrc->v4l2_handle, buffer_index, &main_buf);
2001 /* release buffer */
2003 gst_buffer_unref(*buffer);
2007 camerasrc->num_live_buffers++;
2008 /*escape loop for passing buffer to videosink*/
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;
2018 /* RAW capture buffer should be reach here */
2019 camerasrc_queue_buffer(camerasrc->v4l2_handle, buffer_index, &main_buf);
2021 /* Skip passing this buffer */
2024 GST_DEBUG_OBJECT(camerasrc, "Skip pssing this buffer");
2029 GST_DEBUG_OBJECT (camerasrc, "LEAVED");
2035 static GstFlowReturn gst_camerasrc_read(GstCameraSrc *camerasrc, GstBuffer **buffer)
2038 int command = GST_CAMERA_CONTROL_CAPTURE_COMMAND_NONE;
2039 GstFlowReturn ret = GST_FLOW_OK;
2040 camerasrc_state_t state = CAMERASRC_STATE_NONE;
2042 g_mutex_lock(camerasrc->mutex);
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);
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);
2057 g_mutex_unlock(camerasrc->mutex);
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);
2065 if (state == CAMERASRC_STATE_READY) {
2066 GST_INFO_OBJECT (camerasrc,"Prepare buffer");
2067 ret = gst_camerasrc_prepare_preview(camerasrc, camerasrc->num_alloc_buf);
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);
2076 __ta__(" gst_camerasrc_read_preview_mmap",
2077 ret = gst_camerasrc_read_preview_mmap(camerasrc, buffer);
2081 case VIDEO_IN_MODE_CAPTURE:
2082 __ta__( " gst_camerasrc_read_capture",
2083 ret = gst_camerasrc_read_capture(camerasrc, buffer, command);
2086 case VIDEO_IN_MODE_UNKNOWN:
2088 ret = GST_FLOW_ERROR;
2089 GST_ERROR_OBJECT (camerasrc, "can't reach statement.[camerasrc->mode=%d]", camerasrc->mode);
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;
2105 /* Buffer related functions */
2106 static void gst_camerasrc_buffer_pad_alloc_qbuf(GstCameraBuffer *buffer)
2110 GstCaps *negotiated_caps = NULL;
2111 GstBuffer *queue_buf = NULL;
2112 GstCameraSrc *camerasrc = NULL;
2113 camerasrc_buffer_t camerasrc_buffer;
2116 camerasrc = buffer->camerasrc;
2118 GST_ERROR("buffer is NULL");
2123 negotiated_caps = gst_pad_get_negotiated_caps(GST_BASE_SRC_PAD(camerasrc));
2125 GST_ERROR("camerasrc is NULL");
2129 index = buffer->v4l2_buffer_index;
2131 GST_LOG_OBJECT(camerasrc, "pad alloc qbuf");
2133 ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD (camerasrc),
2135 camerasrc->main_buf_sz,
2138 if (!GST_IS_BUFFER(queue_buf)) {
2139 GST_INFO_OBJECT (camerasrc, "[DEBUG] NOT BUFFER!!?");
2142 if (ret != GST_FLOW_OK) {
2143 GST_ERROR_OBJECT(camerasrc, "gst_pad_alloc_buffer failed. [%d]", ret);
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)));
2150 gst_caps_unref(negotiated_caps);
2151 negotiated_caps = NULL;
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);
2160 GST_LOG_OBJECT (camerasrc, "QBUF : [idx=%d]", index);
2167 static void gst_camerasrc_buffer_mmap_qbuf(GstCameraBuffer *buffer)
2171 GstCameraSrc *camerasrc = NULL;
2172 camerasrc_buffer_t camerasrc_buffer;
2174 camerasrc = buffer->camerasrc;
2175 index = buffer->v4l2_buffer_index;
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);
2181 GST_LOG_OBJECT(camerasrc, "QBUF : [idx=%d]", index);
2187 static void gst_camerasrc_buffer_finalize(GstCameraBuffer *buffer)
2190 GstCameraSrc *camerasrc = NULL;
2192 camerasrc = buffer->camerasrc;
2193 index = buffer->v4l2_buffer_index;
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)));
2200 if (camerasrc->buffer_running) {
2201 /* Buffer Q again */
2202 if (camerasrc->use_pad_alloc == TRUE){
2203 gst_camerasrc_buffer_pad_alloc_qbuf(buffer);
2205 gst_camerasrc_buffer_mmap_qbuf(buffer);
2208 GST_INFO_OBJECT(camerasrc, "It is not running. skip QBUF");
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);
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;
2222 buffer->is_alloc_data = FALSE;
2225 if (GST_BUFFER_MALLOCDATA(buffer)) {
2226 free(GST_BUFFER_MALLOCDATA(buffer));
2227 GST_BUFFER_MALLOCDATA(buffer) = NULL;
2230 gst_object_unref(camerasrc);
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));
2240 static void gst_camerasrc_buffer_class_init(gpointer g_class, gpointer class_data)
2242 GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS(g_class);
2244 camera_buffer_parent_class = g_type_class_peek_parent(g_class);
2245 mini_object_class->finalize = (GstMiniObjectFinalizeFunction)gst_camerasrc_buffer_finalize;
2249 static GType gst_camerasrc_buffer_get_type(void)
2251 static GType _gst_camerasrc_buffer_type;
2253 if (G_UNLIKELY(_gst_camerasrc_buffer_type == 0)) {
2254 static const GTypeInfo camera_buffer_info = {
2255 sizeof (GstBufferClass),
2258 gst_camerasrc_buffer_class_init,
2261 sizeof (GstCameraBuffer),
2267 _gst_camerasrc_buffer_type = g_type_register_static(GST_TYPE_BUFFER,
2269 &camera_buffer_info, 0);
2272 return _gst_camerasrc_buffer_type;
2276 static GstCameraBuffer *gst_camerasrc_buffer_new(GstCameraSrc *camerasrc)
2278 GstCameraBuffer *ret = NULL;
2280 ret = (GstCameraBuffer *)gst_mini_object_new(GST_TYPE_CAMERASRC_BUFFER);
2282 GST_LOG_OBJECT(camerasrc, "creating buffer : %p", ret);
2284 ret->camerasrc = gst_object_ref(GST_OBJECT(camerasrc));
2285 ret->is_alloc_data = FALSE;
2291 static void gst_camerasrc_buffer_free(gpointer data)
2293 GST_CAMERASRC_BUFFER_DATA *buffer_data = (GST_CAMERASRC_BUFFER_DATA *)data;
2295 GST_LOG_OBJECT(buffer_data->camerasrc, "freeing buffer with %p %d",
2296 buffer_data->camerasrc, buffer_data->index);
2298 g_mutex_lock(buffer_data->camerasrc->pad_alloc_mutex);
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);
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);
2310 buffer_data->camerasrc->num_live_buffers--;
2312 g_mutex_unlock(buffer_data->camerasrc->pad_alloc_mutex);
2313 g_cond_signal(buffer_data->camerasrc->buffer_cond);
2315 buffer_data->camerasrc = NULL;
2316 buffer_data->index = -1;
2318 /* Free data argument */
2325 static void gst_camerasrc_buffer_trace(GstCameraSrc *camerasrc)
2328 GstBuffer *buf = NULL;
2331 GST_ERROR_OBJECT(camerasrc, "Element is NULL");
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])));
2342 GST_ELEMENT_WARNING(camerasrc, RESOURCE, FAILED,
2343 NULL, (("buf[%d] is not GstBuffer"), i));
2351 static unsigned char *gst_camerasrc_make_metadata_for_nonlinear_buffer(GstCameraSrc *camerasrc, guint32 index)
2353 unsigned char *meta_string = NULL;
2354 camerasrc_frame_data_t data;
2355 SCMN_IMGB *psimgb = NULL;
2357 /*GST_LOG_OBJECT (camerasrc, "index[%d],pix_format[%x]", index, camerasrc->fourcc);*/
2359 psimgb = (SCMN_IMGB *)malloc(sizeof(SCMN_IMGB));
2360 if (psimgb == NULL) {
2361 GST_ERROR_OBJECT(camerasrc, "failed to alloc SCMN_IMGB");
2365 memset(psimgb, 0x00, sizeof(SCMN_IMGB));
2368 camerasrc_get_frame_data(camerasrc->v4l2_handle, &data);
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;
2375 psimgb->w[0] = camerasrc->width;
2376 psimgb->h[0] = camerasrc->height;
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;
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]);
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')) {
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);
2406 psimgb->w[1] = psimgb->w[2] = camerasrc->width;
2407 psimgb->h[1] = psimgb->h[2] = camerasrc->height >> 2;
2409 GST_WARNING_OBJECT (camerasrc, "Unknown pixel format.");
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];
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;
2428 static gboolean gst_camerasrc_device_is_open(GstCameraSrc *camerasrc)
2430 return camerasrc_device_is_open((camsrc_handle_t)camerasrc->v4l2_handle);
2434 static gboolean gst_camerasrc_get_timeinfo(GstCameraSrc *camerasrc, GstBuffer *buffer)
2438 GstClock *clock = NULL;
2439 GstClockTime timestamp = GST_CLOCK_TIME_NONE;
2440 GstClockTime duration = GST_CLOCK_TIME_NONE;
2442 if (!camerasrc || !buffer) {
2443 GST_WARNING_OBJECT (camerasrc, "Invalid pointer [hadle:%p, buffer:%p]", camerasrc, buffer);
2447 /* timestamps, LOCK to get clock and base time. */
2448 clock = GST_ELEMENT_CLOCK(camerasrc);
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);
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;
2460 if (camerasrc->fps <= 0) {
2461 /*if fps is zero, auto fps mode*/
2466 fps_de = camerasrc->fps;
2469 if (fps_nu > 0 && fps_de > 0) {
2470 GstClockTime latency;
2472 latency = gst_util_uint64_scale_int(GST_SECOND, fps_nu, fps_de);
2477 /* no clock, can't set timestamps */
2478 timestamp = GST_CLOCK_TIME_NONE;
2481 GST_BUFFER_TIMESTAMP(buffer) = timestamp;
2482 GST_BUFFER_DURATION(buffer) = duration;
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)));
2493 static int get_proper_index(GstCameraSrc *camerasrc, GstBuffer *pad_alloc_buffer)
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) {
2503 return temp_idx - 1; /* -1 is caused that it already increased in ++ */
2507 /* Gstreamer general functions */
2508 static gboolean gst_camerasrc_src_start(GstBaseSrc *src)
2511 GstCameraSrc *camerasrc = GST_CAMERA_SRC (src);
2513 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
2515 #if _ENABLE_CAMERASRC_DEBUG
2516 g_preview_frame_cnt = 0;
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);*/
2523 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
2529 static gboolean gst_camerasrc_src_stop(GstBaseSrc *src)
2532 GstCameraSrc *camerasrc = GST_CAMERA_SRC(src);
2534 GST_DEBUG_OBJECT (camerasrc, "ENTERED");
2536 ret = gst_camerasrc_stop(camerasrc);
2538 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
2544 static GstFlowReturn gst_camerasrc_src_create(GstPushSrc *src, GstBuffer **buffer)
2546 GstCameraSrc *camerasrc = GST_CAMERA_SRC (src);
2549 /*GST_DEBUG_OBJECT(camerasrc, "ENTERED");*/
2551 if (camerasrc->req_negotiation) {
2552 GST_INFO_OBJECT(camerasrc, "negotiation start");
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);
2558 GST_INFO_OBJECT (camerasrc, "negotiation stop");
2561 __ta__(" gst_camerasrc_read",
2562 ret = gst_camerasrc_read(camerasrc, buffer);
2564 /*GST_DEBUG_OBJECT (camerasrc, "LEAVED");*/
2570 static void gst_camerasrc_set_property(GObject *object, guint prop_id,
2571 const GValue *value, GParamSpec *pspec)
2574 GstCameraSrc *camerasrc = NULL;
2576 g_return_if_fail(GST_IS_CAMERA_SRC(object));
2577 camerasrc = GST_CAMERA_SRC(object);
2580 case ARG_REQ_NEGOTIATION:
2581 camerasrc->req_negotiation = g_value_get_boolean(value);
2583 case ARG_CAMERA_HIGH_SPEED_FPS:
2584 tmp = g_value_get_int(value);
2585 camerasrc->high_speed_fps = tmp;
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);
2592 camerasrc->camera_id = g_value_get_int(value);
2594 case ARG_CAMERA_EXT_VIDEO_FD:
2595 camerasrc->external_videofd = g_value_get_int(value);
2597 case ARG_CAMERA_CAPTURE_FOURCC:
2598 camerasrc->cap_fourcc = g_value_get_uint(value);
2600 case ARG_CAMERA_CAPTURE_QUALITY:
2601 camerasrc->cap_quality = g_value_get_enum(value);
2603 case ARG_CAMERA_CAPTURE_WIDTH:
2604 camerasrc->cap_width = g_value_get_int(value);
2606 case ARG_CAMERA_CAPTURE_HEIGHT:
2607 camerasrc->cap_height = g_value_get_int(value);
2609 case ARG_CAMERA_CAPTURE_INTERVAL:
2610 camerasrc->cap_interval = g_value_get_int(value);
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);
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);
2624 case ARG_SIGNAL_STILLCAPTURE:
2625 camerasrc->signal_still_capture = g_value_get_boolean(value);
2627 case ARG_USE_PAD_ALLOC:
2628 camerasrc->use_pad_alloc = g_value_get_boolean(value);
2630 case ARG_NUM_ALLOC_BUF:
2631 camerasrc->num_alloc_buf = g_value_get_int(value);
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);
2637 case ARG_SENSOR_MODE:
2638 camerasrc->sensor_mode = g_value_get_int(value);
2641 camerasrc->vflip = g_value_get_boolean(value);
2644 camerasrc->hflip = g_value_get_boolean(value);
2647 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
2653 static void gst_camerasrc_get_property(GObject *object, guint prop_id,
2654 GValue *value, GParamSpec *pspec)
2656 GstCameraSrc *camerasrc;
2658 g_return_if_fail(GST_IS_CAMERA_SRC(object));
2659 camerasrc = GST_CAMERA_SRC(object);
2662 case ARG_REQ_NEGOTIATION:
2663 g_value_set_boolean(value, camerasrc->req_negotiation);
2665 case ARG_CAMERA_HIGH_SPEED_FPS:
2666 g_value_set_int(value, camerasrc->high_speed_fps);
2668 case ARG_CAMERA_AUTO_FPS:
2669 g_value_set_boolean(value, camerasrc->fps_auto);
2672 g_value_set_int(value, camerasrc->camera_id);
2674 case ARG_CAMERA_EXT_VIDEO_FD:
2675 g_value_set_int(value, camerasrc->external_videofd);
2677 case ARG_CAMERA_CAPTURE_FOURCC:
2678 g_value_set_uint(value, camerasrc->cap_fourcc);
2680 case ARG_CAMERA_CAPTURE_QUALITY:
2681 g_value_set_enum(value, camerasrc->cap_quality);
2683 case ARG_CAMERA_CAPTURE_WIDTH:
2684 g_value_set_int(value, camerasrc->cap_width);
2686 case ARG_CAMERA_CAPTURE_HEIGHT:
2687 g_value_set_int(value, camerasrc->cap_height);
2689 case ARG_CAMERA_CAPTURE_INTERVAL:
2690 g_value_set_int(value, camerasrc->cap_interval);
2692 case ARG_CAMERA_CAPTURE_COUNT:
2693 g_value_set_int(value, camerasrc->cap_count);
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);
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);
2704 case ARG_SIGNAL_STILLCAPTURE:
2705 g_value_set_boolean(value, camerasrc->signal_still_capture);
2707 case ARG_USE_PAD_ALLOC:
2708 g_value_set_boolean(value, camerasrc->use_pad_alloc);
2710 case ARG_NUM_ALLOC_BUF:
2711 g_value_set_int(value, camerasrc->num_alloc_buf);
2713 case ARG_OPERATION_STATUS:
2714 g_value_set_int(value, 0);
2715 gst_camerasrc_buffer_trace(camerasrc);
2717 case ARG_HOLD_AF_AFTER_CAPTURE:
2718 g_value_set_boolean(value, camerasrc->hold_af_after_capturing);
2720 case ARG_SENSOR_MODE:
2721 g_value_set_int(value, camerasrc->sensor_mode);
2724 g_value_set_boolean(value, camerasrc->vflip);
2727 g_value_set_boolean(value, camerasrc->hflip);
2730 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
2736 static GstStateChangeReturn gst_camerasrc_change_state(GstElement *element, GstStateChange transition)
2738 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2739 GstCameraSrc *camerasrc;
2740 camerasrc = GST_CAMERA_SRC (element);
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;
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;
2755 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2756 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> PLAYING");
2762 ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
2763 if (ret == GST_STATE_CHANGE_FAILURE){
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;
2772 case GST_STATE_CHANGE_PAUSED_TO_READY:
2773 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> READY");
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;
2790 /* subclass must post a meaningfull error message */
2791 GST_ERROR_OBJECT(camerasrc, "state change failed");
2793 return GST_STATE_CHANGE_FAILURE;
2797 static void gst_camerasrc_finalize(GObject *object)
2799 GstCameraSrc *camerasrc = GST_CAMERA_SRC(object);
2801 #if _ENABLE_CAMERASRC_DEBUG
2802 GST_INFO_OBJECT(camerasrc, "total [%u] preview frame(s) outputed.",g_preview_frame_cnt);
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);
2812 if (camerasrc->command_list != NULL) {
2813 g_queue_free(camerasrc->command_list);
2814 camerasrc->command_list = NULL;
2817 G_OBJECT_CLASS(parent_class)->finalize(object);
2821 void gst_camerasrc_set_capture_command(GstCameraSrc *camerasrc, GstCameraControlCaptureCommand cmd)
2823 gboolean is_zsl = FALSE;
2825 if (camerasrc == NULL) {
2826 GST_ERROR_OBJECT(camerasrc, "camerasrc is NULL");
2830 GST_INFO_OBJECT(camerasrc, "ENTERED");
2832 g_mutex_lock(camerasrc->mutex);
2834 /* Do not push command when ZSL mode */
2836 g_queue_push_tail(camerasrc->command_list, (gpointer)cmd);
2837 GST_INFO_OBJECT(camerasrc, "ACTION: Push capture command [%d] finished.", cmd);
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");
2845 g_mutex_unlock(camerasrc->mutex);
2851 static gboolean gst_camerasrc_negotiate (GstBaseSrc * basesrc)
2854 GstCaps *caps = NULL;
2855 GstCaps *peercaps = NULL;
2856 gboolean result = FALSE;
2858 GstCameraSrc *camerasrc = GST_CAMERA_SRC(basesrc);
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);
2865 /* nothing or anything is allowed, we're done */
2866 if (thiscaps == NULL || gst_caps_is_any (thiscaps))
2867 goto no_nego_needed;
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;
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);
2882 icaps = gst_caps_intersect (thiscaps, ipcaps);
2883 gst_caps_unref (ipcaps);
2885 if (!gst_caps_is_empty (icaps))
2888 gst_caps_unref (icaps);
2892 GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, 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);
2899 int twidth, theight;
2900 int width = G_MAXINT, height = G_MAXINT;
2902 if (gst_structure_get_int (s, "width", &twidth)
2903 && gst_structure_get_int (s, "height", &theight)) {
2905 /* Walk the structure backwards to get the first entry of the
2906 * smallest resolution bigger (or equal to) the preferred resolution)
2908 for (i = gst_caps_get_size (icaps) - 1; i >= 0; i--) {
2909 GstStructure *is = gst_caps_get_structure (icaps, i);
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) {
2923 caps = gst_caps_copy_nth (icaps, best);
2924 gst_caps_unref (icaps);
2929 gst_caps_unref (thiscaps);
2930 gst_caps_unref (peercaps);
2932 /* no peer or peer has ANY caps, work with our own caps then */
2936 caps = gst_caps_make_writable (caps);
2937 gst_caps_truncate (caps);
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);
2944 if (gst_caps_is_any (caps)) {
2945 /* hmm, still anything, so element can do anything and
2946 * nego is not needed */
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))
2954 gst_caps_unref (caps);
2960 GST_DEBUG_OBJECT (basesrc, "no negotiation needed");
2962 gst_caps_unref (thiscaps);
2968 static GstCaps *gst_camerasrc_get_caps(GstBaseSrc *src)
2970 GstCameraSrc *camerasrc = GST_CAMERA_SRC(src);
2971 GstCaps *ret = NULL;
2973 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
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");
2979 return gst_caps_copy(gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc)));
2982 /*FIXME: Using "VIDIOC_ENUM_FMT".*/
2983 ret = gst_caps_copy(gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc)));
2985 GST_INFO_OBJECT(camerasrc, "probed caps: %x", ret);
2986 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
2992 static gboolean _gst_camerasrc_get_raw_pixel_info(int fourcc, int *pix_format, int *colorspace)
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;
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;
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;
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;
3019 case GST_MAKE_FOURCC('N','V','1','2'): /* V4L2_PIX_FMT_NV12 */
3020 *pix_format = CAMERASRC_PIX_NV12;
3021 *colorspace = CAMERASRC_COL_RAW;
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;
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;
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;
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 */
3042 *pix_format = CAMERASRC_PIX_NONE;
3043 *colorspace = CAMERASRC_COL_NONE;
3051 static gboolean _gst_camerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize)
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));
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;
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);
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;
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. */
3090 /* unkown format!! */
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)
3102 unsigned char *copy_data = NULL;
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);
3113 case GST_MAKE_FOURCC('I','4','2','0'):
3114 case GST_MAKE_FOURCC('S','4','2','0'):
3116 guint length_Cb = 0;
3117 guint length_Cr = 0;
3118 guint offset_Cb = 0;
3119 guint offset_Cr = 0;
3121 length_Y = width * height;
3122 length_Cb = length_Cr = (width * height) >> 2;
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);
3131 offset_Cb = CAMERASRC_ALIGN(length_Y, ALIGN_SIZE_I420);
3132 offset_Cr = offset_Cb + CAMERASRC_ALIGN(length_Cb, ALIGN_SIZE_I420);
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);
3138 *new_buffer = copy_data;
3139 *new_buffer_length = length_Y + length_Cb + length_Cr;
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);
3145 case GST_MAKE_FOURCC('N','V','1','2'):
3146 case GST_MAKE_FOURCC('S','N','1','2'):
3148 guint length_CbCr = 0;
3149 guint offset_CbCr = 0;
3151 length_Y = width * height;
3152 length_CbCr = (width * height) >> 1;
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);
3161 offset_CbCr = CAMERASRC_ALIGN(length_Y, ALIGN_SIZE_NV12);
3163 memcpy(copy_data, base_buffer, length_Y);
3164 memcpy(copy_data + length_Y, base_buffer + offset_CbCr, length_CbCr);
3166 *new_buffer = copy_data;
3167 *new_buffer_length = length_Y + length_CbCr;
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);
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]);
3179 *new_buffer_length = 0;
3184 GST_DEBUG_OBJECT(camerasrc, "Done.");
3190 static gboolean gst_camerasrc_get_caps_info(GstCameraSrc *camerasrc, GstCaps *caps, guint *size)
3197 gchar *caps_string = NULL;
3198 const gchar *mimetype;
3199 const GValue *framerate;
3200 GstStructure *structure = NULL;
3202 GST_INFO_OBJECT(camerasrc, "ENTERED Collect data for given caps.(caps:%x)", caps);
3204 structure = gst_caps_get_structure(caps, 0);
3206 if (!gst_structure_get_int(structure, "width", &w)) {
3207 goto _caps_info_failed;
3210 if (!gst_structure_get_int(structure, "height", &h)) {
3211 goto _caps_info_failed;
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;
3218 GST_INFO_OBJECT(camerasrc, "Succeed to get rotate[%d] info in caps", rot);
3219 camerasrc->use_rotate_caps = TRUE;
3222 /* set default size if there is no capsfilter */
3224 w = _DEFAULT_WIDTH * 2;
3228 h = _DEFAULT_HEIGHT * 2;
3231 camerasrc->width = w;
3232 camerasrc->height = h;
3233 camerasrc->rotate = rot;
3235 framerate = gst_structure_get_value(structure, "framerate");
3237 GST_INFO("Set FPS as default");
3239 /* set default fps if framerate is not existed in caps */
3240 fps_n = _DEFAULT_FPS;
3243 fps_n = gst_value_get_fraction_numerator(framerate);
3244 fps_d = gst_value_get_fraction_denominator(framerate);
3246 /* numerator and denominator should be bigger than zero */
3248 GST_WARNING("numerator of FPS is %d. make it default(15).", fps_n);
3249 fps_n = _DEFAULT_FPS;
3253 GST_WARNING("denominator of FPS is %d. make it 1.", fps_d);
3258 camerasrc->fps = (int)((float)fps_n / (float)fps_d);
3260 mimetype = gst_structure_get_name (structure);
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;
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")) {
3275 gint endianness = 0;
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);
3283 case 8: /* V4L2_PIX_FMT_RGB332 */
3284 camerasrc->pix_format = CAMERASRC_PIX_RGGB8;
3285 camerasrc->colorspace = CAMERASRC_COL_RAW;
3287 case 15: /* V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB555X */
3288 camerasrc->pix_format = CAMERASRC_PIX_NONE;
3289 camerasrc->colorspace = CAMERASRC_COL_NONE;
3291 case 16: /* V4L2_PIX_FMT_RGB565 : V4L2_PIX_FMT_RGB565X */
3292 camerasrc->pix_format = CAMERASRC_PIX_NONE;
3293 camerasrc->colorspace = CAMERASRC_COL_NONE;
3295 case 24: /* V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24 */
3296 camerasrc->pix_format = CAMERASRC_PIX_NONE;
3297 camerasrc->colorspace = CAMERASRC_COL_NONE;
3299 case 32: /* V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32 */
3300 camerasrc->pix_format = CAMERASRC_PIX_NONE;
3301 camerasrc->colorspace = CAMERASRC_COL_NONE;
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;
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);
3316 g_free(caps_string);
3323 GST_INFO_OBJECT(camerasrc, "Failed to get caps info.");
3324 GST_DEBUG_OBJECT(camerasrc, "LEAVED");
3329 static gboolean gst_camerasrc_set_caps(GstBaseSrc *src, GstCaps *caps)
3332 GstCameraSrc *camerasrc = NULL;
3334 camerasrc = GST_CAMERA_SRC(src);
3336 GST_INFO_OBJECT(camerasrc, "ENTERED");
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.");
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");
3351 GST_INFO_OBJECT(camerasrc, "A mode of avsystem camera is unknown[%d]. Proceed set_caps.", camerasrc->mode);
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);
3360 __ta__(" gst_camerasrc_start",
3361 if (!gst_camerasrc_start(camerasrc)) {
3362 GST_INFO_OBJECT (camerasrc, "Cam sensor start failed.");
3366 GST_INFO_OBJECT (camerasrc, "LEAVED");
3372 static void gst_camerasrc_base_init(gpointer klass)
3374 GstElementClass *element_class = GST_ELEMENT_CLASS(klass);
3376 GST_DEBUG_CATEGORY_INIT(camerasrc_debug, "camerasrc", 0, "camerasrc element");
3378 GST_INFO("ENTERED");
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);
3387 static void gst_camerasrc_class_init(GstCameraSrcClass *klass)
3389 GObjectClass *gobject_class;
3390 GstElementClass *element_class;
3391 GstBaseSrcClass *basesrc_class;
3392 GstPushSrcClass *pushsrc_class;
3394 GST_DEBUG("ENTERED");
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);
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;
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",
3416 G_PARAM_READWRITE));
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));
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",
3428 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
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));
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));
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",
3447 G_PARAM_READWRITE));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
3531 g_object_class_install_property(gobject_class, ARG_VFLIP,
3532 g_param_spec_boolean("vflip", "Flip vertically",
3533 "Flip camera input vertically",
3535 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3537 g_object_class_install_property(gobject_class, ARG_HFLIP,
3538 g_param_spec_boolean("hflip", "Flip horizontally",
3539 "Flip camera input horizontally",
3541 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
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
3550 * This signal gets emitted before sending the buffer.
3552 gst_camerasrc_signals[SIGNAL_STILL_CAPTURE] =
3553 g_signal_new("still-capture",
3554 G_TYPE_FROM_CLASS(klass),
3556 G_STRUCT_OFFSET(GstCameraSrcClass, still_capture),
3559 gst_camerasrc_VOID__OBJECT_OBJECT,
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 */
3567 /* wh01.cho:req-negotiation:+:To notify user of camerasrc, after changing resolution. */
3569 * GstCameraSrc::nego-complete:
3570 * @camerasrc: the camerasrc instance
3571 * @start: when re-negotiation is finished.
3574 gst_camerasrc_signals[SIGNAL_NEGO_COMPLETE] =
3575 g_signal_new("nego-complete",
3576 G_TYPE_FROM_CLASS (klass),
3578 G_STRUCT_OFFSET(GstCameraSrcClass, nego_complete),
3581 gst_marshal_VOID__VOID,
3584 GST_DEBUG("LEAVED");
3588 static void gst_camerasrc_init(GstCameraSrc *camerasrc, GstCameraSrcClass *klass)
3590 GST_DEBUG_OBJECT (camerasrc, "ENTERED");
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 ();
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;
3628 /* Initialize usr buffer to be alloced by sink to NULL */
3631 for(i = 0; i < MAX_USR_BUFFER_NUM; i++) {
3632 camerasrc->usr_buffer[i] = NULL;
3635 camerasrc->use_pad_alloc = FALSE;
3636 camerasrc->num_alloc_buf = 0;
3637 camerasrc->camera_id = _DEFAULT_CAMERA_ID;
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;
3655 #ifdef _SPEED_UP_RAW_CAPTURE
3656 camerasrc->cap_stream_diff = FALSE;
3657 #endif /* _SPEED_UP_RAW_CAPTURE */
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);
3664 GST_DEBUG("LEAVED");
3668 static void GenerateYUV420BlackFrame(unsigned char *buf, int buf_size, int width, int height)
3674 y_len = width * height;
3675 yuv_len = (width * height * 3) >> 1;
3677 if (buf_size < yuv_len) {
3682 for (i = 0 ; i < y_len ; i++) {
3686 for ( ; i < yuv_len ; i++) {
3695 for (i = 0 ; i < y_len / 4 ; i++) {
3696 ibuf[i] = 0x10101010; /* set YYYY */
3699 sbuf = (short*)(&buf[y_len]);
3701 for (i = 0 ; i < (yuv_len - y_len) / 2 ; i++) {
3702 sbuf[i] = 0x8080; /* set UV */
3710 static void GenerateYUV422BlackFrame(unsigned char *buf, int buf_size, int width, int height)
3719 yuv_len = (width * height * 2);
3721 if (buf_size < yuv_len) {
3725 for (i = 0 ; i < yuv_len / 4 ; i++) {
3726 ibuf[i] = 0x80108010; /* YUYV -> 0xVYUY */
3733 static gboolean GenerateST12BlackFrame(GstCameraSrc *camerasrc, unsigned char *buf, int buf_size, int width, int height)
3741 int uvelevation = 0;
3742 gboolean boolret = TRUE;
3743 unsigned char *blkframe = NULL;
3745 /* Calculation of stride. need to be confirmation from driver team */
3746 if ((width % 128) != 0 ) {
3747 ystride = width + (128 - (width % 128));
3754 /* Calculation of elevation. need to be confirmation from driver team */
3756 if ((height % 32) != 0) {
3757 yelevation= height + (32 - (height % 32));
3759 yelevation = height;
3762 if (((height >>1) % 32) != 0) {
3763 uvelevation = (height >> 1) + (32 - ((height >> 1) % 32));
3765 uvelevation = (height >> 1);
3768 GST_DEBUG("ystride = %d and uvstride = %d", ystride, uvstride);
3769 GST_DEBUG("yelevation = %d and uvelevation = %d", yelevation, uvelevation);
3771 y_len = ystride * yelevation;
3772 yuv_len = y_len + uvstride * uvelevation;
3774 /* Generate black frame */
3775 blkframe = (unsigned char*)g_malloc(yuv_len);
3777 if (blkframe == NULL) {
3778 GST_ERROR ("ST12Blk: Failed to allocate memory...");
3783 for (i = 0 ; i < y_len ; i++) {
3784 blkframe [i] = 0x10;
3787 for (; i < yuv_len ; i++) {
3788 blkframe [i] = 0x80;
3793 if (blkframe != NULL) {
3802 static unsigned long gst_get_current_time(void)
3804 struct timeval lc_time;
3806 gettimeofday(&lc_time, NULL);
3808 return ((unsigned long)(lc_time.tv_sec * 1000L) + (unsigned long)(lc_time.tv_usec / 1000L));
3812 #if _ENABLE_CAMERASRC_DEBUG
3814 static int __util_write_file(char *filename, void *data, int size)
3818 fp = fopen(filename, "wb");
3823 fwrite(data, 1, size, fp);
3831 static gboolean plugin_init(GstPlugin *plugin)
3835 error = gst_element_register(plugin, "camerasrc", GST_RANK_PRIMARY + 100, GST_TYPE_CAMERA_SRC);
3841 GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
3844 "Camera source plug-in",
3848 "Samsung Electronics Co",
3849 "http://www.samsung.com")
3851 /* GstURIHandler interface */
3852 static GstURIType gst_camerasrc_uri_get_type (void)
3857 static gchar ** gst_camerasrc_uri_get_protocols (void)
3859 static gchar *protocols[] = { (char *) "camera", NULL };
3863 static const gchar * gst_camerasrc_uri_get_uri (GstURIHandler * handler)
3865 GstCameraSrc *camerasrc = GST_CAMERA_SRC (handler);
3868 g_snprintf (uri, sizeof (uri), "camera://0");
3869 return g_intern_string (uri);
3872 static gboolean gst_camerasrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
3874 GstCameraSrc *camerasrc = GST_CAMERA_SRC (handler);
3875 const gchar *device = "0";
3876 if (strcmp (uri, "camera://") != 0) {
3879 g_object_set (camerasrc, "camera-id", atoi(device), NULL);
3885 static void gst_camerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
3887 GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
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;