4 * Copyright (c) 2018 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
31 #include <gst/gstutils.h>
32 #include <gst/video/video-info.h>
33 #include <glib-object.h>
36 #include <sys/types.h>
40 #include "gsttizencamerasrc.h"
41 #include "gsttizencamerasrccontrol.h"
42 #include "gsttizencamerasrccolorbalance.h"
45 /******************************************************************************
47 *******************************************************************************/
48 GST_DEBUG_CATEGORY (tizencamerasrc_debug);
49 #define GST_CAT_DEFAULT tizencamerasrc_debug
52 #define CAMERASRC_ALIGN(addr,size) (((addr)+((size)-1))&(~((size)-1)))
55 #define CLEAR(x) memset(&(x), 0, sizeof(x))
58 /* Local definitions */
59 #define _DEFAULT_FPS 15
60 #define _DEFAULT_HIGH_SPEED_FPS 0
61 #define _DEFAULT_FPS_AUTO FALSE
62 #define _DEFAULT_EXTRA_PREVIEW FALSE
63 #define _DEFAULT_PIX_FORMAT CAMERA_PIXEL_FORMAT_NV12
64 #define _DEFAULT_PIX_FORMAT_NAME "NV12"
65 #define _DEFAULT_CAPTURE_FORMAT_NAME "JPEG"
66 #define _DEFAULT_CAMERA_ID 0
68 #define _CAMERA_ID_MIN 0
69 #define _CAMERA_ID_MAX 1
71 #define _DEFAULT_CAP_QUALITY 95
72 #define _DEFAULT_CAP_WIDTH 640
73 #define _DEFAULT_CAP_HEIGHT 480
74 #define _DEFAULT_CAP_COUNT 1
75 #define _DEFAULT_CAP_INTERVAL 0
76 #define _DEFAULT_CAP_PROVIDE_EXIF FALSE
77 #define _DEFAULT_BITRATE (1024 * 1024) /* bps, 1 Mbps */
78 #define _DEFAULT_GOP_INTERVAL 1000 /* msec, 1 second */
79 #define _DEFAULT_LIVE_BUFFER_MAX 32
80 #define _DEFAULT_LIVE_BUFFER_MAX_RAW 16
81 #define _BUFFER_WAIT_TIMEOUT 1000000 /* usec */
82 #define _DEFAULT_EMPTY_BUFFER_TIMEOUT 5000 /* msec */
83 #define _DEFAULT_BUFFER_QUARK 0
86 CAMERA_COLOR_BALANCE_BRIGHTNESS = 0,
87 CAMERA_COLOR_BALANCE_CONTRAST,
88 CAMERA_COLOR_BALANCE_WHITE_BALANCE,
89 CAMERA_COLOR_BALANCE_COLOR_TONE,
90 CAMERA_COLOR_BALANCE_SATURATION,
91 CAMERA_COLOR_BALANCE_HUE,
92 CAMERA_COLOR_BALANCE_SHARPNESS,
93 CAMERA_COLOR_BALANCE_NUM
97 CAMERA_CONTROL_PTZ_TYPE = 0,
103 #define SAFE_FREE_GQUEUE(gqueue) \
105 g_queue_free(gqueue); \
109 #define MAKE_FOURCC_FROM_STRING(string) ((guint32)(string[0] | (string[1] << 8) | (string[2] << 16) | (string[3] << 24)))
115 SIGNAL_STILL_CAPTURE,
116 SIGNAL_VIDEO_STREAM_CB,
117 SIGNAL_EXTRA_PREVIEW_STREAM_CB,
119 /*SIGNAL_REGISTER_TROUBLE,*/
139 ARG_LIVE_BUFFER_MAX_RAW,
140 ARG_EMPTY_BUFFER_TIMEOUT,
147 ARG_CAPTURE_INTERVAL,
150 ARG_CAPTURE_PROVIDE_EXIF,
167 VIDEO_IN_MODE_PREVIEW,
169 VIDEO_IN_MODE_CAPTURE,
172 typedef struct _GstTizenCameraSrcCommand {
175 } GstTizenCameraSrcCommand;
178 static void gst_tizencamerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
180 static guint gst_tizencamerasrc_signals[LAST_SIGNAL] = { 0 };
182 /* Element template variables */
183 static GstStaticPadTemplate src_factory =
184 GST_STATIC_PAD_TEMPLATE("src",
187 GST_STATIC_CAPS("video/x-raw,"
188 "format = (string) { NV12, SN12, NV21, SN21, I420, S420, YV12, YUY2, SUYV, UYVY, SYVY }, "
189 "width = (int) [ 1, 8192 ], "
190 "height = (int) [ 1, 8192 ]; "
192 "stream-format = (string) { byte-stream, avc }, "
193 "alignment = (string) au; "
195 "width = (int) [ 1, 8192 ], "
196 "height = (int) [ 1, 8192 ]; "
198 "width = (int) [ 1, 8192 ], "
199 "height = (int) [ 1, 8192 ]; "
201 "width = (int) [ 1, 8192 ], "
202 "height = (int) [ 1, 8192 ]; "
204 "width = (int) [ 1, 8192 ], "
205 "height = (int) [ 1, 8192 ]; "
208 /* Local static functions */
209 static void gst_tizencamerasrc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
210 static void gst_tizencamerasrc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
211 static gboolean gst_tizencamerasrc_negotiate(GstBaseSrc *basesrc);
212 static gboolean gst_tizencamerasrc_src_start(GstBaseSrc *src);
213 static gboolean gst_tizencamerasrc_src_stop(GstBaseSrc *src);
214 static gboolean gst_tizencamerasrc_start(GstTizenCameraSrc *camerasrc);
215 static GstFlowReturn gst_tizencamerasrc_src_create(GstPushSrc *src, GstBuffer **buffer);
216 static GstFlowReturn gst_tizencamerasrc_read_preview(GstTizenCameraSrc *camerasrc, GstBuffer **buffer);
217 static GstStateChangeReturn gst_tizencamerasrc_change_state(GstElement *element, GstStateChange transition);
218 static GstCaps *gst_tizencamerasrc_get_caps(GstBaseSrc *src, GstCaps *filter);
219 static gboolean gst_tizencamerasrc_set_caps(GstBaseSrc *src, GstCaps *caps);
220 static gboolean gst_tizencamerasrc_get_caps_info(GstTizenCameraSrc *camerasrc, GstCaps *caps, guint *size);
221 static gboolean gst_tizencamerasrc_fill_ctrl_list(GstTizenCameraSrc *camerasrc);
222 static gboolean gst_tizencamerasrc_empty_ctrl_list(GstTizenCameraSrc *camerasrc);
223 static void gst_tizencamerasrc_finalize(GObject *object);
224 static gboolean gst_tizencamerasrc_get_timeinfo(GstTizenCameraSrc *camerasrc, GstBuffer *buffer);
225 static gboolean gst_tizencamerasrc_capture_start(GstTizenCameraSrc *camerasrc);
226 static gboolean gst_tizencamerasrc_capture_stop(GstTizenCameraSrc *camerasrc);
227 static void gst_tizencamerasrc_error_handler(GstTizenCameraSrc *camerasrc, int ret);
228 static GstBuffer *gst_tizencamerasrc_buffer_new(GstTizenCameraSrc *camerasrc, camera_buffer_s *buffer,
229 camera_metadata_s *meta, GstTizenCameraBufferType type, BufferControl *control, int stream_id);
230 static void gst_tizencamerasrc_buffer_finalize(GstTizenCameraBuffer *buffer);
231 static void gst_tizencamerasrc_set_video_format(GstTizenCameraSrc *camerasrc);
232 static void gst_tizencamerasrc_set_capture_format(GstTizenCameraSrc *camerasrc);
235 static int __camera_preview_frame_cb(camera_buffer_s *buffer, camera_metadata_s *meta, void *user_data);
236 static int __camera_extra_preview_frame_cb(camera_buffer_s *buffer, camera_metadata_s *meta, int stream_id, void *user_data);
237 static int __camera_video_frame_cb(camera_buffer_s *buffer, camera_metadata_s *meta, void *user_data);
238 static int __camera_hal_message_callback(camera_message_s *message, void *user_data);
241 static gboolean __gst_tizencamerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize);
242 static gboolean __gst_tizencamerasrc_get_raw_pixel_info(int fourcc, camera_pixel_format_e *pix_format);
243 static gboolean __gst_tizencamerasrc_get_tbm_format(int pix_format, guint32 *tbm_format);
244 static GstCaps *__gst_tizencamerasrc_get_caps_from_buffer(camera_buffer_s *buffer);
245 static void __gst_tizencamerasrc_post_message_int(GstTizenCameraSrc *camerasrc, const char *msg_name, const char *field_name, int value);
246 static int __gst_tizencamerasrc_release_buffer(GstTizenCameraSrc *camerasrc, GstTizenCameraBufferType type, int index, int stream_id);
248 GST_IMPLEMENT_TIZENCAMERASRC_COLOR_BALANCE_METHODS(GstTizenCameraSrc, gst_tizencamera_src);
249 GST_IMPLEMENT_TIZENCAMERASRC_CONTROL_METHODS(GstTizenCameraSrc, gst_tizencamera_src);
252 /******************************************************************************
254 *******************************************************************************/
255 static GstBuffer *gst_tizencamerasrc_buffer_new(GstTizenCameraSrc *camerasrc, camera_buffer_s *buffer,
256 camera_metadata_s *meta, GstTizenCameraBufferType type, BufferControl *control, int stream_id)
258 int ret = CAMERA_ERROR_NONE;
260 gboolean is_tbm_used = FALSE;
261 gboolean is_delta_frame = FALSE;
263 GstTizenCameraBuffer *new_buffer = NULL;
264 GstMemory *memory = NULL;
265 GstStructure *structure_metadata = NULL;
267 if (!camerasrc || !buffer) {
268 GST_ERROR("NULL pointer %p %p", camerasrc, buffer);
272 if (!buffer->total_size) {
273 GST_ERROR_OBJECT(camerasrc, "requested buffer size is incorrect");
277 if (buffer->num_bos > 0)
280 GST_DEBUG_OBJECT(camerasrc, "index[%d] is_tbm[%d], is_delta[%d]",
281 buffer->index, is_tbm_used, is_delta_frame);
283 /* allocate new buffer */
284 new_buffer = g_new0(GstTizenCameraBuffer, 1);
286 new_buffer->type = type;
287 new_buffer->index = buffer->index;
288 new_buffer->stream_id = stream_id;
289 new_buffer->control = control;
290 new_buffer->buffer = gst_buffer_new();
291 if (!new_buffer->buffer) {
292 GST_ERROR_OBJECT(camerasrc, "new GstBuffer failed");
293 goto _BUFFER_NEW_FAILED;
297 GST_DEBUG_OBJECT(camerasrc, "meta: is_delta[%d]", meta->is_delta_frame);
298 GST_DEBUG_OBJECT(camerasrc, "meta: focus_state[%d]", meta->focus_state);
299 GST_DEBUG_OBJECT(camerasrc, "meta: facing_direction[%d]", meta->facing_direction);
300 GST_DEBUG_OBJECT(camerasrc, "meta: flip[%d]", meta->flip);
301 GST_DEBUG_OBJECT(camerasrc, "meta: rotation[%d]", meta->rotation);
302 GST_DEBUG_OBJECT(camerasrc, "meta: rotation[%d]", meta->rotation);
303 GST_DEBUG_OBJECT(camerasrc, "meta: status_ae[%d]", meta->status_ae);
304 GST_DEBUG_OBJECT(camerasrc, "meta: status_awb[%d]", meta->status_awb);
306 is_delta_frame = (gboolean)meta->is_delta_frame;
308 if (camerasrc->buffer_quark != _DEFAULT_BUFFER_QUARK) {
309 structure_metadata = gst_structure_new("metadata",
310 "focus-state", G_TYPE_INT, meta->focus_state,
311 "facing-direction", G_TYPE_INT, meta->facing_direction,
312 "flip", G_TYPE_INT, meta->flip,
313 "rotation", G_TYPE_INT, meta->rotation,
314 "status-ae", G_TYPE_INT, meta->status_ae,
315 "status-awb", G_TYPE_INT, meta->status_awb,
317 if (structure_metadata) {
318 GST_LOG_OBJECT(camerasrc, "new structure [%p]", structure_metadata);
319 gst_mini_object_set_qdata(GST_MINI_OBJECT_CAST(new_buffer->buffer),
320 camerasrc->buffer_quark, structure_metadata, (GDestroyNotify)gst_structure_free);
322 GST_WARNING_OBJECT(camerasrc, "failed to create structure for metadata");
328 GST_BUFFER_FLAG_SET(new_buffer->buffer, GST_BUFFER_FLAG_DELTA_UNIT);
330 GST_BUFFER_FLAG_UNSET(new_buffer->buffer, GST_BUFFER_FLAG_DELTA_UNIT);
332 /* set timestamp info */
333 gst_tizencamerasrc_get_timeinfo(camerasrc, new_buffer->buffer);
336 GST_DEBUG_OBJECT(camerasrc, "TBM -> Tizen allocator");
338 if (camerasrc->is_encoded_format) {
339 /* create tizen memory for gst buffer with tbm bo */
340 memory = gst_tizen_allocator_alloc_bo(camerasrc->allocator,
341 &camerasrc->video_info,
343 (buffer->planes[0].bytesused > 0 ? buffer->planes[0].bytesused : buffer->planes[0].size),
344 (gpointer)new_buffer,
345 (GDestroyNotify)gst_tizencamerasrc_buffer_finalize);
347 /* create tbm surface from buffer */
348 new_buffer->t_surface = tbm_surface_internal_create_with_bos(&camerasrc->ts_info,
349 (tbm_bo *)buffer->bos, buffer->num_bos);
350 if (!new_buffer->t_surface) {
351 GST_ERROR_OBJECT(camerasrc, "tbm surface create failed");
352 goto _BUFFER_NEW_FAILED;
355 /* create tizen memory for gst buffer with tbm surface */
356 memory = gst_tizen_allocator_alloc_surface(camerasrc->allocator,
357 &camerasrc->video_info,
358 new_buffer->t_surface,
359 (gpointer)new_buffer,
360 (GDestroyNotify)gst_tizencamerasrc_buffer_finalize);
363 GST_DEBUG_OBJECT(camerasrc, "NOT TBM - size %u", buffer->total_size);
365 if (camerasrc->pix_format == CAMERA_PIXEL_FORMAT_H264 ||
366 camerasrc->pix_format == CAMERA_PIXEL_FORMAT_MJPEG ||
367 camerasrc->pix_format == CAMERA_PIXEL_FORMAT_VP8 ||
368 camerasrc->pix_format == CAMERA_PIXEL_FORMAT_VP9) {
369 /* memory copy for h264/mjpeg/vp8/vp9 stream */
371 uint32_t total_size = 0;
372 new_buffer->copied_data = g_malloc(buffer->total_size);
373 for (i = 0 ; i < buffer->num_planes ; i++) {
374 memcpy(new_buffer->copied_data + total_size, buffer->planes[i].data, buffer->planes[i].size);
375 total_size += buffer->planes[i].size;
378 new_buffer->copied_data = g_memdup2(buffer->planes[0].data, buffer->total_size);
381 ret = __gst_tizencamerasrc_release_buffer(camerasrc, type, buffer->index, stream_id);
382 if (ret != CAMERA_ERROR_NONE) {
383 GST_ERROR_OBJECT(camerasrc, "release buffer failed[0x%x]", ret);
384 goto _BUFFER_NEW_FAILED;
387 memory = gst_memory_new_wrapped(0,
388 new_buffer->copied_data,
392 (gpointer)new_buffer,
393 (GDestroyNotify)gst_tizencamerasrc_buffer_finalize);
397 GST_ERROR_OBJECT(camerasrc, "GstMemory failed");
398 goto _BUFFER_NEW_FAILED;
401 new_buffer->camerasrc = gst_object_ref(GST_OBJECT(camerasrc));
402 gst_buffer_append_memory(new_buffer->buffer, memory);
404 GST_DEBUG_OBJECT(camerasrc, "memory[%p][%"G_GSIZE_FORMAT"], buffer[%p,%p][%"G_GSIZE_FORMAT"], buffer max[%"G_GSIZE_FORMAT"]",
405 memory, gst_memory_get_sizes(memory, NULL, NULL),
406 new_buffer, new_buffer->buffer,
407 gst_buffer_get_sizes(new_buffer->buffer, NULL, &maxsize),
410 return new_buffer->buffer;
414 if (new_buffer->t_surface)
415 tbm_surface_destroy(new_buffer->t_surface);
416 if (new_buffer->buffer)
417 gst_buffer_unref(new_buffer->buffer);
425 static void gst_tizencamerasrc_buffer_finalize(GstTizenCameraBuffer *buffer)
427 int ret = CAMERA_ERROR_NONE;
428 GstTizenCameraSrc *camerasrc = NULL;
431 GST_ERROR("NULL buffer");
435 GST_DEBUG("type[%d], index[%d], stream_id[%d], copied_data[%p]",
436 buffer->type, buffer->index, buffer->stream_id, buffer->copied_data);
438 camerasrc = buffer->camerasrc;
440 /* "copied_data != NULL" means that TBM is not used for buffer
441 and no need to call function to release buffer to HAL. */
442 if (buffer->copied_data) {
443 g_free(buffer->copied_data);
444 buffer->copied_data = NULL;
446 ret = __gst_tizencamerasrc_release_buffer(camerasrc, buffer->type, buffer->index, buffer->stream_id);
447 if (ret != CAMERA_ERROR_NONE)
448 GST_WARNING_OBJECT(camerasrc, "release buffer failed[0x%x]", ret);
451 g_mutex_lock(&buffer->control->lock);
453 buffer->control->live_buffers--;
454 GST_LOG_OBJECT(camerasrc, "type[%d] live buffers %d", buffer->type, buffer->control->live_buffers);
455 g_cond_broadcast(&buffer->control->cond);
457 g_mutex_unlock(&buffer->control->lock);
459 if (buffer->t_surface) {
460 tbm_surface_destroy(buffer->t_surface);
461 buffer->t_surface = NULL;
464 gst_object_unref(camerasrc);
473 static void gst_tizencamerasrc_set_video_format(GstTizenCameraSrc *camerasrc)
475 int ret = CAMERA_ERROR_NONE;
476 camera_format_s set_format;
479 GST_ERROR("NULL handle");
485 set_format.stream_format = camerasrc->pix_format;
486 set_format.stream_resolution.width = camerasrc->video_width;
487 set_format.stream_resolution.height = camerasrc->video_height;
488 set_format.stream_fps = camerasrc->video_fps;
490 switch (camerasrc->rotate) {
492 set_format.stream_rotation = CAMERA_ROTATION_90;
495 set_format.stream_rotation = CAMERA_ROTATION_180;
498 set_format.stream_rotation = CAMERA_ROTATION_270;
502 set_format.stream_rotation = CAMERA_ROTATION_0;
506 if (!__gst_tizencamerasrc_get_raw_pixel_info(camerasrc->cap_fourcc, &set_format.capture_format)) {
507 GST_WARNING_OBJECT(camerasrc, "__gst_tizencamerasrc_get_raw_pixel_info failed, set default JPEG");
508 set_format.capture_format = CAMERA_PIXEL_FORMAT_JPEG;
510 set_format.capture_resolution.width = camerasrc->cap_width;
511 set_format.capture_resolution.height = camerasrc->cap_height;
512 set_format.capture_quality = (uint32_t)camerasrc->cap_quality;
514 GST_INFO_OBJECT(camerasrc, "video resolution %dx%d, fps %d, format %d, rotation %d",
515 set_format.stream_resolution.width, set_format.stream_resolution.height,
516 set_format.stream_fps, set_format.stream_format, set_format.stream_rotation);
518 ret = hal_camera_set_video_stream_format(camerasrc->hal_handle, &set_format);
519 if (ret != CAMERA_ERROR_NONE)
520 GST_ERROR_OBJECT(camerasrc, "set video stream failed 0x%x", ret);
522 GST_INFO_OBJECT(camerasrc, "done");
528 static void gst_tizencamerasrc_set_capture_format(GstTizenCameraSrc *camerasrc)
530 int ret = CAMERA_ERROR_NONE;
531 GstState state = GST_STATE_NULL;
532 GstStateChangeReturn gst_ret;
533 camera_format_s stream_format;
536 GST_ERROR("NULL handle");
540 gst_ret = gst_element_get_state((GstElement *)camerasrc, &state, NULL, GST_CLOCK_TIME_NONE);
541 if (gst_ret == GST_STATE_CHANGE_FAILURE || gst_ret == GST_STATE_CHANGE_ASYNC) {
542 GST_WARNING_OBJECT(camerasrc, "failed to get state : %d", gst_ret);
546 GST_INFO_OBJECT(camerasrc, "Set capture resolution %dx%d - state %d",
547 camerasrc->cap_width_tmp, camerasrc->cap_height_tmp, state);
550 if (state <= GST_STATE_READY) {
551 GST_INFO_OBJECT(camerasrc, "[state %d] it will be set later", state);
555 /* preview capture resolution */
556 ret = hal_camera_get_preview_stream_format(camerasrc->hal_handle, &stream_format);
557 if (ret != CAMERA_ERROR_NONE) {
558 GST_ERROR_OBJECT(camerasrc, "failed to get stream format for preview");
562 if (!__gst_tizencamerasrc_get_raw_pixel_info(camerasrc->cap_fourcc, &stream_format.capture_format)) {
563 GST_WARNING_OBJECT(camerasrc, "_gst_tizencamerasrc_get_raw_pixel_info failed, set default JPEG");
564 stream_format.capture_format = CAMERA_PIXEL_FORMAT_JPEG;
566 stream_format.capture_resolution.width = camerasrc->cap_width_tmp;
567 stream_format.capture_resolution.height = camerasrc->cap_height_tmp;
569 ret = hal_camera_set_preview_stream_format(camerasrc->hal_handle, &stream_format);
570 if (ret != CAMERA_ERROR_NONE) {
571 GST_ERROR_OBJECT(camerasrc, "failed to set stream format for preview 0x%x", ret);
575 /* video capture resolution */
576 if (camerasrc->recording_hint) {
577 ret = hal_camera_get_video_stream_format(camerasrc->hal_handle, &stream_format);
578 if (ret != CAMERA_ERROR_NONE) {
579 GST_ERROR_OBJECT(camerasrc, "failed to get stream format for video");
583 stream_format.capture_resolution.width = camerasrc->cap_width_tmp;
584 stream_format.capture_resolution.height = camerasrc->cap_height_tmp;
586 ret = hal_camera_set_video_stream_format(camerasrc->hal_handle, &stream_format);
587 if (ret != CAMERA_ERROR_NONE) {
588 GST_ERROR_OBJECT(camerasrc, "failed to set stream format for video 0x%x", ret);
594 if (ret == CAMERA_ERROR_NONE) {
595 camerasrc->cap_width = camerasrc->cap_width_tmp;
596 camerasrc->cap_height = camerasrc->cap_height_tmp;
599 GST_INFO_OBJECT(camerasrc, "done");
605 static void gst_tizencamerasrc_error_handler(GstTizenCameraSrc *camerasrc, int ret)
608 GST_ERROR_OBJECT(camerasrc, "NULL camerasrc");
613 case CAMERA_ERROR_NONE:
614 GST_WARNING_OBJECT(camerasrc, "NO ERROR");
616 case CAMERA_ERROR_INTERNAL:
617 GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("IO control error"), GST_ERROR_SYSTEM);
619 case CAMERA_ERROR_DEVICE_OPEN:
620 GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ_WRITE, ("camera open failed"), GST_ERROR_SYSTEM);
622 case CAMERA_ERROR_DEVICE_BUSY:
623 GST_ELEMENT_ERROR(camerasrc, RESOURCE, BUSY, ("camera device busy"), GST_ERROR_SYSTEM);
625 case CAMERA_ERROR_DEVICE_NOT_FOUND:
626 GST_ELEMENT_ERROR(camerasrc, RESOURCE, NOT_FOUND, ("camera device not found"), GST_ERROR_SYSTEM);
628 case CAMERA_ERROR_DEVICE_UNAVAILABLE:
629 GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ, ("camera device unavailable"), GST_ERROR_SYSTEM);
631 case CAMERA_ERROR_DEVICE_TIME_OUT:
632 GST_ELEMENT_ERROR(camerasrc, RESOURCE, TOO_LAZY, ("Time Out"), GST_ERROR_SYSTEM);
634 case CAMERA_ERROR_DEVICE_NOT_SUPPORTED:
635 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("Not supported"), GST_ERROR_SYSTEM);
637 case CAMERA_ERROR_OUT_OF_MEMORY:
638 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("memory allocation failed"), GST_ERROR_SYSTEM);
640 case CAMERA_ERROR_PERMISSION_DENIED:
641 GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("Security service failed"), GST_ERROR_SYSTEM);
643 case CAMERA_ERROR_DEVICE_READ:
644 GST_ELEMENT_ERROR(camerasrc, RESOURCE, READ, ("camera read failed"), GST_ERROR_SYSTEM);
646 case CAMERA_ERROR_DEVICE_WRITE:
647 GST_ELEMENT_ERROR(camerasrc, RESOURCE, WRITE, ("camera write failed"), GST_ERROR_SYSTEM);
650 GST_ELEMENT_ERROR(camerasrc, RESOURCE, SEEK, (("General video device error[ret=%x]"), ret), GST_ERROR_SYSTEM);
658 /* VOID:OBJECT,OBJECT,OBJECT (generated by 'glib-genmarshal') */
659 #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
661 gst_tizencamerasrc_VOID__OBJECT_OBJECT_OBJECT(GClosure *closure,
662 GValue *return_value G_GNUC_UNUSED,
663 guint n_param_values,
664 const GValue *param_values,
665 gpointer invocation_hint G_GNUC_UNUSED,
666 gpointer marshal_data)
668 typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT_OBJECT)(gpointer data1,
674 register GMarshalFunc_VOID__OBJECT_OBJECT_OBJECT callback;
675 register GCClosure *cc = (GCClosure *)closure;
676 register gpointer data1;
677 register gpointer data2;
679 g_return_if_fail(n_param_values == 4);
681 if (G_CCLOSURE_SWAP_DATA(closure)) {
682 data1 = closure->data;
683 data2 = g_value_peek_pointer(param_values + 0);
685 data1 = g_value_peek_pointer(param_values + 0);
686 data2 = closure->data;
689 callback = (GMarshalFunc_VOID__OBJECT_OBJECT_OBJECT)(marshal_data ? marshal_data : cc->callback);
692 g_marshal_value_peek_object(param_values + 1),
693 g_marshal_value_peek_object(param_values + 2),
694 g_marshal_value_peek_object(param_values + 3),
701 gst_tizencamerasrc_VOID__OBJECT_VIDEO_STREAM(GClosure *closure,
702 GValue *return_value,
703 guint n_param_values,
704 const GValue *param_values,
705 gpointer invocation_hint,
706 gpointer marshal_data)
708 typedef void (*GMarshalFunc_VOID__OBJECT_VIDEO_STREAM)(gpointer data1,
711 register GMarshalFunc_VOID__OBJECT_VIDEO_STREAM callback;
712 register GCClosure *cc = (GCClosure *) closure;
713 register gpointer data1, data2;
715 g_return_if_fail (n_param_values == 2);
717 if (G_CCLOSURE_SWAP_DATA(closure)) {
718 data1 = closure->data;
719 data2 = g_value_peek_pointer(param_values + 0);
721 data1 = g_value_peek_pointer(param_values + 0);
722 data2 = closure->data;
725 callback = (GMarshalFunc_VOID__OBJECT_VIDEO_STREAM)(marshal_data ? marshal_data : cc->callback);
728 g_marshal_value_peek_object(param_values + 1),
733 gst_tizencamerasrc_VOID__OBJECT_EXTRA_PREVIEW_STREAM(GClosure *closure,
734 GValue *return_value G_GNUC_UNUSED,
735 guint n_param_values,
736 const GValue *param_values,
737 gpointer invocation_hint G_GNUC_UNUSED,
738 gpointer marshal_data)
740 typedef void (*GMarshalFunc_VOID__OBJECT_EXTRA_PREVIEW_STREAM)(gpointer data1,
745 register GMarshalFunc_VOID__OBJECT_EXTRA_PREVIEW_STREAM callback;
746 register GCClosure *cc = (GCClosure *)closure;
747 register gpointer data1;
748 register gpointer data2;
750 g_return_if_fail(n_param_values == 3);
752 if (G_CCLOSURE_SWAP_DATA(closure)) {
753 data1 = closure->data;
754 data2 = g_value_peek_pointer(param_values + 0);
756 data1 = g_value_peek_pointer(param_values + 0);
757 data2 = closure->data;
760 callback = (GMarshalFunc_VOID__OBJECT_EXTRA_PREVIEW_STREAM)(marshal_data ? marshal_data : cc->callback);
763 g_marshal_value_peek_object(param_values + 1),
764 g_marshal_value_peek_object(param_values + 2),
770 /* use following BOILERPLATE MACRO as _get_type entry */
771 G_DEFINE_TYPE_WITH_CODE(GstTizenCameraSrc, gst_tizencamerasrc, GST_TYPE_PUSH_SRC,
772 G_IMPLEMENT_INTERFACE(GST_TYPE_URI_HANDLER, gst_tizencamerasrc_uri_handler_init)
773 G_IMPLEMENT_INTERFACE(GST_TYPE_CAMERA_CONTROL, gst_tizencamera_src_control_interface_init)
774 G_IMPLEMENT_INTERFACE(GST_TYPE_COLOR_BALANCE, gst_tizencamera_src_color_balance_interface_init));
776 static int __camera_hal_message_callback(camera_message_s *message, void *user_data)
778 GstTizenCameraSrc *camerasrc = NULL;
780 if (message == NULL || user_data == NULL) {
781 GST_ERROR("message callback error %p %p", message, user_data);
785 camerasrc = (GstTizenCameraSrc *)user_data;
787 switch (message->type) {
788 case CAMERA_MESSAGE_TYPE_FOCUS_CHANGED:
789 GST_INFO_OBJECT(camerasrc, "focus state %d", message->focus_state);
790 __gst_tizencamerasrc_post_message_int(camerasrc, "camerasrc-AF", "focus-state", message->focus_state);
792 case CAMERA_MESSAGE_TYPE_CAPTURED:
793 GST_INFO_OBJECT(camerasrc, "CAPTURED");
795 case CAMERA_MESSAGE_TYPE_HDR_PROGRESS:
796 GST_INFO_OBJECT(camerasrc, "HDR progress %d", message->hdr_progress);
798 case CAMERA_MESSAGE_TYPE_ERROR:
799 GST_ERROR_OBJECT(camerasrc, "error from camera HAL 0x%x", message->error_code);
800 camerasrc->hal_error_code = message->error_code;
801 gst_tizencamerasrc_error_handler(camerasrc, camerasrc->hal_error_code);
802 g_cond_broadcast(&camerasrc->preview_control.cond);
805 GST_ERROR_OBJECT(camerasrc, "unknown type message %d", message->type);
813 static int __camera_preview_frame_cb(camera_buffer_s *buffer, camera_metadata_s *meta, void *user_data)
815 GstTizenCameraSrc *camerasrc = NULL;
816 GstBuffer *gst_buffer = NULL;
818 if (!buffer || !user_data) {
819 GST_ERROR("preview callback error %p %p", buffer, user_data);
823 camerasrc = (GstTizenCameraSrc *)user_data;
825 g_mutex_lock(&camerasrc->preview_control.lock);
827 if (camerasrc->preview_control.running == FALSE ||
828 camerasrc->live_buffer_check < camerasrc->preview_control.live_buffers) {
829 hal_camera_release_preview_buffer(camerasrc->hal_handle, buffer->index);
830 GST_WARNING_OBJECT(camerasrc, "Skip buffer[%d] running %d, Live buffer[%d/%d]",
831 buffer->index, camerasrc->preview_control.running,
832 camerasrc->preview_control.live_buffers, camerasrc->live_buffer_check);
833 goto _PREVIEW_FRAME_CB_DONE;
836 /* create new buffer */
837 gst_buffer = gst_tizencamerasrc_buffer_new(camerasrc, buffer, meta,
838 BUFFER_TYPE_PREVIEW, &camerasrc->preview_control, -1);
840 GST_ERROR_OBJECT(camerasrc, "new buffer allocation failed. size %u", buffer->total_size);
841 hal_camera_release_preview_buffer(camerasrc->hal_handle, buffer->index);
842 goto _PREVIEW_FRAME_CB_DONE;
845 if (camerasrc->preview_control.is_first_frame) {
846 camerasrc->preview_control.is_first_frame = FALSE;
847 camerasrc->preview_control.is_tbm_used = (buffer->num_bos > 0);
848 GST_WARNING_OBJECT(camerasrc, "TBM in buffer[%d] (num_bos[%u])",
849 camerasrc->preview_control.is_tbm_used, buffer->num_bos);
852 camerasrc->preview_control.live_buffers++;
853 GST_DEBUG_OBJECT(camerasrc, "%p [size %u][preview_live_buffers %d]",
854 gst_buffer, buffer->total_size, camerasrc->preview_control.live_buffers);
856 /* add new buffer to preview buffer list */
857 g_queue_push_tail(camerasrc->preview_buffer_list, gst_buffer);
858 g_cond_broadcast(&camerasrc->preview_control.cond);
860 _PREVIEW_FRAME_CB_DONE:
861 g_mutex_unlock(&camerasrc->preview_control.lock);
863 GST_DEBUG_OBJECT(camerasrc, "done");
869 static int __camera_extra_preview_frame_cb(camera_buffer_s *buffer, camera_metadata_s *meta, int stream_id, void *user_data)
871 GstTizenCameraSrc *camerasrc = NULL;
872 GstSample *gst_sample = NULL;
873 GstBuffer *gst_buffer = NULL;
875 if (!buffer || !user_data || stream_id < 0 || stream_id >= EXTRA_PREVIEW_STREAM_MAX) {
876 GST_ERROR("invalid param[%p,%p,%d]", buffer, user_data, stream_id);
880 camerasrc = (GstTizenCameraSrc *)user_data;
882 g_mutex_lock(&camerasrc->extra_preview_control.lock);
884 if (camerasrc->preview_control.running == FALSE) {
885 GST_WARNING("Skip buffer[stream_id:%d,i:%d]", stream_id, buffer->index);
886 goto _EXTRA_PREVIEW_FRAME_CB_DONE;
889 if (!camerasrc->extra_caps[stream_id])
890 camerasrc->extra_caps[stream_id] = __gst_tizencamerasrc_get_caps_from_buffer(buffer);
892 if (!camerasrc->extra_caps[stream_id]) {
893 GST_ERROR("extra caps failed for stream id[%d]", stream_id);
894 goto _EXTRA_PREVIEW_FRAME_CB_DONE;
897 /* create new buffer and sample */
898 gst_buffer = gst_tizencamerasrc_buffer_new(camerasrc, buffer, meta,
899 BUFFER_TYPE_EXTRA_PREVIEW, &camerasrc->extra_preview_control, stream_id);
901 GST_ERROR("new buffer allocation failed. size %u", buffer->total_size);
902 goto _EXTRA_PREVIEW_FRAME_CB_DONE;
905 gst_sample = gst_sample_new(gst_buffer, camerasrc->extra_caps[stream_id], NULL, NULL);
907 GST_ERROR("new sample failed for stream_id[%d]", stream_id);
908 goto _EXTRA_PREVIEW_FRAME_CB_DONE;
911 camerasrc->extra_preview_control.live_buffers++;
913 _EXTRA_PREVIEW_FRAME_CB_DONE:
914 g_mutex_unlock(&camerasrc->extra_preview_control.lock);
917 g_signal_emit(G_OBJECT(camerasrc),
918 gst_tizencamerasrc_signals[SIGNAL_EXTRA_PREVIEW_STREAM_CB],
923 hal_camera_release_extra_preview_buffer(camerasrc->hal_handle, stream_id, buffer->index);
927 gst_buffer_unref(gst_buffer);
935 static int __camera_video_frame_cb(camera_buffer_s *buffer, camera_metadata_s *meta, void *user_data)
937 GstTizenCameraSrc *camerasrc = NULL;
938 GstBuffer *gst_buffer = NULL;
939 GstSample *gst_sample = NULL;
941 if (!buffer || !user_data) {
942 GST_ERROR("video callback error %p %p", buffer, user_data);
946 camerasrc = (GstTizenCameraSrc *)user_data;
948 g_mutex_lock(&camerasrc->video_control.lock);
950 if (camerasrc->video_control.running == FALSE ||
951 camerasrc->live_buffer_check < camerasrc->video_control.live_buffers) {
952 GST_WARNING("Skip buffer[%d] running %d, Live buffer[%d/%d]",
953 buffer->index, camerasrc->video_control.running,
954 camerasrc->video_control.live_buffers, camerasrc->live_buffer_check);
955 goto _VIDEO_FRAME_CB_DONE;
958 /* create new buffer and sample */
959 gst_buffer = gst_tizencamerasrc_buffer_new(camerasrc, buffer, meta,
960 BUFFER_TYPE_VIDEO, &camerasrc->video_control, -1);
962 GST_ERROR("new buffer allocation failed. size %u", buffer->total_size);
963 goto _VIDEO_FRAME_CB_DONE;
966 if (!camerasrc->video_caps)
967 camerasrc->video_caps = __gst_tizencamerasrc_get_caps_from_buffer(buffer);
969 if (!camerasrc->video_caps) {
970 GST_ERROR("video caps failed");
971 goto _VIDEO_FRAME_CB_DONE;
974 gst_sample = gst_sample_new(gst_buffer, camerasrc->video_caps, NULL, NULL);
976 GST_ERROR("new sample failed for buffer index[%d]", buffer->index);
977 goto _VIDEO_FRAME_CB_DONE;
980 camerasrc->video_control.live_buffers++;
982 GST_DEBUG_OBJECT(camerasrc, "index %d, %p, %p [size total %u][video_live_buffers %d]",
983 buffer->index, gst_sample, gst_buffer, buffer->total_size, camerasrc->video_control.live_buffers);
985 _VIDEO_FRAME_CB_DONE:
986 g_mutex_unlock(&camerasrc->video_control.lock);
989 g_signal_emit(G_OBJECT(camerasrc),
990 gst_tizencamerasrc_signals[SIGNAL_VIDEO_STREAM_CB],
994 hal_camera_release_video_buffer(camerasrc->hal_handle, buffer->index);
998 gst_buffer_unref(gst_buffer);
1000 GST_DEBUG_OBJECT(camerasrc, "done");
1006 static GstVideoFormat __get_gst_video_format(camera_pixel_format_e pixel_format)
1008 switch (pixel_format) {
1009 case CAMERA_PIXEL_FORMAT_NV12:
1010 return GST_VIDEO_FORMAT_NV12;
1011 case CAMERA_PIXEL_FORMAT_NV21:
1012 return GST_VIDEO_FORMAT_NV21;
1013 case CAMERA_PIXEL_FORMAT_I420:
1014 return GST_VIDEO_FORMAT_I420;
1015 case CAMERA_PIXEL_FORMAT_YV12:
1016 return GST_VIDEO_FORMAT_YV12;
1017 case CAMERA_PIXEL_FORMAT_YUYV:
1018 return GST_VIDEO_FORMAT_YUY2;
1019 case CAMERA_PIXEL_FORMAT_UYVY:
1020 return GST_VIDEO_FORMAT_UYVY;
1021 case CAMERA_PIXEL_FORMAT_H264:
1023 case CAMERA_PIXEL_FORMAT_MJPEG:
1025 case CAMERA_PIXEL_FORMAT_VP8:
1027 case CAMERA_PIXEL_FORMAT_VP9:
1028 return GST_VIDEO_FORMAT_ENCODED;
1030 GST_ERROR("unknown pixel format %d", pixel_format);
1035 static GstSample *__create_buffer_sample(GstTizenCameraSrc *camerasrc, camera_buffer_s *cam_buffer)
1037 GstBuffer *gst_buffer = NULL;
1038 GstCaps *caps = NULL;
1039 GstSample *sample = NULL;
1040 const gchar *string_fourcc = NULL;
1041 const gchar *media_type = NULL;
1044 GST_ERROR("NULL handle");
1049 GST_ERROR_OBJECT(camerasrc, "NULL buffer");
1053 gst_buffer = gst_buffer_new_wrapped_full(0,
1054 cam_buffer->planes[0].data,
1055 cam_buffer->planes[0].size,
1057 cam_buffer->planes[0].bytesused,
1060 GST_ERROR_OBJECT(camerasrc, "failed to allocate gst buffer for %p", cam_buffer);
1064 switch (cam_buffer->format) {
1065 case CAMERA_PIXEL_FORMAT_JPEG:
1067 case CAMERA_PIXEL_FORMAT_MJPEG:
1068 media_type = "image/jpeg";
1070 case CAMERA_PIXEL_FORMAT_H264:
1071 media_type = "video/x-h264";
1073 case CAMERA_PIXEL_FORMAT_VP8:
1074 media_type = "video/x-vp8";
1076 case CAMERA_PIXEL_FORMAT_VP9:
1077 media_type = "video/x-vp9";
1080 media_type = "video/x-raw";
1081 string_fourcc = gst_video_format_to_string(__get_gst_video_format(cam_buffer->format));
1082 if (!string_fourcc) {
1083 GST_WARNING_OBJECT(camerasrc, "failed to get string_fourcc[%d]", cam_buffer->format);
1084 goto _CREATE_BUFFER_SAMPLE_DONE;
1089 caps = gst_caps_new_simple(media_type,
1090 "width", G_TYPE_INT, cam_buffer->resolution.width,
1091 "height", G_TYPE_INT, cam_buffer->resolution.height,
1094 GST_ERROR_OBJECT(camerasrc, "sample caps creation failed for[%s]", media_type);
1095 goto _CREATE_BUFFER_SAMPLE_DONE;
1098 if (string_fourcc) {
1099 gst_caps_set_simple(caps,
1100 "format", G_TYPE_STRING, string_fourcc,
1104 sample = gst_sample_new(gst_buffer, caps, NULL, NULL);
1106 GST_ERROR_OBJECT(camerasrc, "buffer sample1 creation failed");
1107 goto _CREATE_BUFFER_SAMPLE_DONE;
1110 _CREATE_BUFFER_SAMPLE_DONE:
1112 gst_buffer_unref(gst_buffer);
1114 gst_caps_unref(caps);
1116 GST_INFO_OBJECT(camerasrc, "sample %p - format %d, %dx%d",
1117 sample, cam_buffer->format, cam_buffer->resolution.width, cam_buffer->resolution.height);
1123 static int _camera_capture_cb(camera_buffer_s *main, camera_buffer_s *postview, camera_buffer_s *thumbnail, void *user_data)
1125 GstTizenCameraSrc *camerasrc = NULL;
1126 GstSample *buf_sample1 = NULL;
1127 GstSample *buf_sample2 = NULL;
1128 GstSample *buf_sample3 = NULL;
1130 if (!main || !user_data) {
1131 GST_ERROR("capture callback error %p %p", main, user_data);
1135 camerasrc = (GstTizenCameraSrc *)user_data;
1137 buf_sample1 = __create_buffer_sample(camerasrc, main);
1139 GST_ERROR_OBJECT(camerasrc, "buffer sample1 creation failed");
1143 buf_sample2 = __create_buffer_sample(camerasrc, postview);
1145 GST_WARNING_OBJECT(camerasrc, "No sample for postview");
1147 buf_sample3 = __create_buffer_sample(camerasrc, thumbnail);
1149 GST_WARNING_OBJECT(camerasrc, "No sample for thumbnail");
1151 GST_INFO_OBJECT(camerasrc, "CALL: capture callback");
1153 g_signal_emit(G_OBJECT(camerasrc),
1154 gst_tizencamerasrc_signals[SIGNAL_STILL_CAPTURE],
1160 GST_INFO_OBJECT(camerasrc, "RETURN: capture callback");
1166 static gboolean gst_tizencamerasrc_create(GstTizenCameraSrc *camerasrc)
1170 if (!camerasrc->hal_handle) {
1171 GST_ERROR_OBJECT(camerasrc, "no camera HAL interface handle");
1172 gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_DEVICE_NOT_FOUND);
1176 if (camerasrc->device_name) {
1177 GST_INFO_OBJECT(camerasrc, "open device - device name [%s]", camerasrc->device_name);
1178 ret = hal_camera_open_device_ext(camerasrc->hal_handle, camerasrc->device_name);
1180 GST_INFO_OBJECT(camerasrc, "open device - camera id [%d]", camerasrc->camera_id);
1181 ret = hal_camera_open_device(camerasrc->hal_handle, camerasrc->camera_id);
1184 if (ret != CAMERA_ERROR_NONE) {
1185 GST_ERROR_OBJECT(camerasrc, "device open failed 0x%08X", ret);
1186 gst_tizencamerasrc_error_handler(camerasrc, ret);
1190 if (!gst_tizencamerasrc_fill_ctrl_list(camerasrc))
1191 GST_WARNING_OBJECT(camerasrc, "Can't fill v4l2 control list.");
1193 GST_INFO_OBJECT(camerasrc, "DONE");
1199 static gboolean gst_tizencamerasrc_destroy(GstTizenCameraSrc *camerasrc)
1201 int ret = CAMERA_ERROR_NONE;
1203 GST_INFO_OBJECT(camerasrc, "ENTERED");
1205 if (camerasrc->hal_handle == NULL) {
1206 GST_ERROR_OBJECT(camerasrc, "not initialized");
1210 /* camera hal interface close device */
1211 GST_INFO_OBJECT(camerasrc, "ENTERED");
1213 ret = hal_camera_close_device(camerasrc->hal_handle);
1214 if (ret != CAMERA_ERROR_NONE) {
1215 GST_ERROR_OBJECT(camerasrc, "hal_camera_close_device failed 0x%x", ret);
1219 /* Empty control list */
1220 gst_tizencamerasrc_empty_ctrl_list(camerasrc);
1222 GST_INFO_OBJECT(camerasrc, "LEAVE");
1228 static gboolean gst_tizencamerasrc_fill_ctrl_list(GstTizenCameraSrc *camerasrc)
1231 GstTizenCameraSrcCommand color_balance[] = {
1232 {"brightness", CAMERA_COMMAND_BRIGHTNESS},
1233 {"contrast", CAMERA_COMMAND_CONTRAST},
1234 {"white balance", CAMERA_COMMAND_WHITE_BALANCE},
1235 {"color tone", CAMERA_COMMAND_EFFECT},
1236 {"saturation", CAMERA_COMMAND_SATURATION},
1237 {"hue", CAMERA_COMMAND_HUE},
1238 {"sharpness", CAMERA_COMMAND_SHARPNESS}
1240 GstTizenCameraSrcCommand camera_control[] = {
1241 {"ptz_type", CAMERA_COMMAND_PTZ_TYPE},
1242 {"pan", CAMERA_COMMAND_PAN},
1243 {"tilt", CAMERA_COMMAND_TILT}
1246 g_return_val_if_fail(camerasrc, FALSE);
1248 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
1250 for (n = 0 ; n < G_N_ELEMENTS(color_balance) ; n++) {
1251 GstTizenCameraSrcColorBalanceChannel *camerasrc_color_channel = NULL;
1252 GstColorBalanceChannel *color_channel = NULL;
1254 camerasrc_color_channel = g_object_new(GST_TYPE_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL, NULL);
1255 color_channel = GST_COLOR_BALANCE_CHANNEL(camerasrc_color_channel);
1257 color_channel->label = g_strdup(color_balance[n].label);
1258 camerasrc_color_channel->id = color_balance[n].cmd;
1259 color_channel->min_value = 0;
1260 color_channel->max_value = 0;
1262 camerasrc->colors = g_list_append(camerasrc->colors, (gpointer)color_channel);
1263 GST_INFO_OBJECT(camerasrc, "Adding Color Balance Channel %s [%"PRIx64"]",
1264 color_channel->label, camerasrc_color_channel->id);
1267 for (n = 0 ; n < G_N_ELEMENTS(camera_control) ; n++) {
1268 GstTizenCamerasrcControlChannel *camerasrc_control_channel = NULL;
1269 GstCameraControlChannel *control_channel = NULL;
1271 camerasrc_control_channel = g_object_new(GST_TYPE_TIZENCAMERASRC_CONTROL_CHANNEL, NULL);
1272 control_channel = GST_CAMERA_CONTROL_CHANNEL(camerasrc_control_channel);
1274 control_channel->label = g_strdup(camera_control[n].label);
1275 camerasrc_control_channel->id = camera_control[n].cmd;
1276 control_channel->min_value = 0;
1277 control_channel->max_value = 0;
1279 camerasrc->camera_controls = g_list_append(camerasrc->camera_controls, (gpointer)control_channel);
1280 GST_INFO_OBJECT(camerasrc, "Adding Camera Control Channel %s [%"PRIx64"]",
1281 control_channel->label, camerasrc_control_channel->id);
1284 GST_DEBUG_OBJECT(camerasrc, "LEAVE");
1290 static gboolean gst_tizencamerasrc_empty_ctrl_list(GstTizenCameraSrc *camerasrc)
1292 g_return_val_if_fail(camerasrc, FALSE);
1294 GST_DEBUG_OBJECT (camerasrc, "ENTERED");
1296 g_list_foreach(camerasrc->colors, (GFunc)g_object_unref, NULL);
1297 g_list_free(camerasrc->colors);
1298 camerasrc->colors = NULL;
1300 g_list_foreach(camerasrc->camera_controls, (GFunc)g_object_unref, NULL);
1301 g_list_free(camerasrc->camera_controls);
1302 camerasrc->camera_controls = NULL;
1304 GST_DEBUG_OBJECT(camerasrc, "LEAVE");
1310 static gboolean gst_tizencamerasrc_start(GstTizenCameraSrc *camerasrc)
1315 camera_flip_e set_flip;
1316 camera_format_s set_format;
1318 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
1322 /* set preview stream format */
1323 set_format.stream_format = camerasrc->pix_format;
1324 set_format.stream_resolution.width = camerasrc->width;
1325 set_format.stream_resolution.height = camerasrc->height;
1326 switch (camerasrc->rotate) {
1328 set_format.stream_rotation = CAMERA_ROTATION_90;
1331 set_format.stream_rotation = CAMERA_ROTATION_180;
1334 set_format.stream_rotation = CAMERA_ROTATION_270;
1338 set_format.stream_rotation = CAMERA_ROTATION_0;
1341 if (camerasrc->fps_auto) {
1342 /*if fps is zero, auto fps mode*/
1343 set_format.stream_fps = 0;
1345 GST_INFO_OBJECT (camerasrc, "AUTO FPS mode");
1346 } else if (camerasrc->high_speed_fps <= 0) {
1347 if (camerasrc->fps <= 0) {
1348 /*if fps is zero, auto fps mode*/
1349 set_format.stream_fps = 0;
1351 set_format.stream_fps = camerasrc->fps;
1354 GST_INFO_OBJECT(camerasrc, "high speed fps %d", camerasrc->high_speed_fps);
1355 set_format.stream_fps = camerasrc->high_speed_fps;
1358 if (!__gst_tizencamerasrc_get_raw_pixel_info(camerasrc->cap_fourcc, &set_format.capture_format)) {
1359 GST_WARNING_OBJECT(camerasrc, "_gst_tizencamerasrc_get_raw_pixel_info failed, set default JPEG");
1360 set_format.capture_format = CAMERA_PIXEL_FORMAT_JPEG;
1362 set_format.capture_resolution.width = camerasrc->cap_width;
1363 set_format.capture_resolution.height = camerasrc->cap_height;
1364 set_format.capture_quality = (uint32_t)camerasrc->cap_quality;
1366 GST_WARNING_OBJECT(camerasrc, "resolution[%dx%d] fps[%d], format[%d], rotation[%d]",
1367 camerasrc->width, camerasrc->height, set_format.stream_fps,
1368 camerasrc->pix_format, camerasrc->rotate);
1370 ret = hal_camera_set_preview_stream_format(camerasrc->hal_handle, &set_format);
1371 if (ret != CAMERA_ERROR_NONE) {
1372 GST_ERROR_OBJECT(camerasrc, "hal_camera_set_preview_stream_format() failed 0x%x", ret);
1377 if (camerasrc->vflip) {
1378 if (camerasrc->hflip)
1379 set_flip = CAMERA_FLIP_BOTH;
1381 set_flip = CAMERA_FLIP_VERTICAL;
1383 if (camerasrc->hflip)
1384 set_flip = CAMERA_FLIP_HORIZONTAL;
1386 set_flip = CAMERA_FLIP_NONE;
1389 for (i = 0 ; i < EXTRA_PREVIEW_STREAM_MAX ; i++) {
1390 if (camerasrc->extra_caps[i]) {
1391 gst_caps_unref(camerasrc->extra_caps[i]);
1392 camerasrc->extra_caps[i] = NULL;
1396 ret = hal_camera_set_command(camerasrc->hal_handle, CAMERA_COMMAND_FLIP, (void *)&set_flip);
1397 if (ret != CAMERA_ERROR_NONE) {
1398 GST_ERROR_OBJECT(camerasrc, "hal_camera_set_command() failed 0x%x", ret);
1402 GST_INFO_OBJECT(camerasrc, "VFLIP : %d, HFLIP : %d", camerasrc->vflip, camerasrc->hflip);
1404 if (camerasrc->preview_control.live_buffers != 0)
1405 GST_WARNING_OBJECT(camerasrc, "CURRENT LIVE BUFFER COUNT[%d]", camerasrc->preview_control.live_buffers);
1407 camerasrc->preview_control.live_buffers = 0;
1408 camerasrc->preview_control.is_first_frame = TRUE;
1409 camerasrc->extra_preview_control.live_buffers = 0;
1410 camerasrc->extra_preview_control.is_first_frame = TRUE;
1412 if (!camerasrc->is_encoded_format && camerasrc->live_buffer_max_raw > 0)
1413 camerasrc->live_buffer_check = camerasrc->live_buffer_max_raw;
1415 camerasrc->live_buffer_check = camerasrc->live_buffer_max;
1417 GST_WARNING_OBJECT(camerasrc, "live buffer check[%d], max[%d,%d]",
1418 camerasrc->live_buffer_check, camerasrc->live_buffer_max, camerasrc->live_buffer_max_raw);
1420 /* start preview stream */
1421 ret = hal_camera_start_preview(camerasrc->hal_handle, __camera_preview_frame_cb, camerasrc);
1422 if (ret != CAMERA_ERROR_NONE) {
1423 GST_ERROR_OBJECT(camerasrc, "hal_camera_start_preview() failed 0x%x", ret);
1424 camerasrc->preview_control.running = FALSE;
1428 GST_INFO_OBJECT(camerasrc, "camerasrc_start_preview_stream() done");
1430 camerasrc->mode = VIDEO_IN_MODE_PREVIEW;
1431 camerasrc->preview_control.running = TRUE;
1432 camerasrc->hal_error_code = CAMERA_ERROR_NONE;
1434 GST_INFO_OBJECT(camerasrc, "LEAVE");
1439 gst_tizencamerasrc_error_handler(camerasrc, ret);
1440 GST_ERROR_OBJECT(camerasrc, "LEAVE 0x%x", ret);
1446 static gboolean gst_tizencamerasrc_stop(GstTizenCameraSrc *camerasrc)
1448 int ret = CAMERA_ERROR_NONE;
1450 GstBuffer *buffer = NULL;
1452 GST_INFO_OBJECT (camerasrc, "ENTERED");
1454 if (camerasrc->hal_handle) {
1455 g_mutex_lock(&camerasrc->preview_control.lock);
1457 if (camerasrc->preview_control.running) {
1458 camerasrc->preview_control.running = FALSE;
1460 GST_ERROR_OBJECT(camerasrc, "buffer NOT running");
1461 g_mutex_unlock(&camerasrc->preview_control.lock);
1465 g_mutex_unlock(&camerasrc->preview_control.lock);
1467 /* remove all cached buffers */
1468 while (!g_queue_is_empty(camerasrc->preview_buffer_list)) {
1469 buffer = g_queue_pop_head(camerasrc->preview_buffer_list);
1470 GST_INFO_OBJECT(camerasrc, "unref queued buffer %p", buffer);
1471 gst_buffer_unref(buffer);
1474 g_mutex_lock(&camerasrc->preview_control.lock);
1476 GST_INFO_OBJECT(camerasrc, "live buffer count %d", camerasrc->preview_control.live_buffers);
1478 /* wait until all buffers are returned */
1479 while (camerasrc->preview_control.live_buffers > 0) {
1480 end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
1481 if (!g_cond_wait_until(&camerasrc->preview_control.cond, &camerasrc->preview_control.lock, end_time)) {
1482 GST_ERROR_OBJECT(camerasrc, "buffer wait failed");
1485 GST_INFO_OBJECT(camerasrc, "signal received. check again [num %d]", camerasrc->preview_control.live_buffers);
1489 g_mutex_unlock(&camerasrc->preview_control.lock);
1491 GST_INFO_OBJECT(camerasrc, "stop preview stream");
1493 /* stop preview stream */
1494 ret = hal_camera_stop_preview(camerasrc->hal_handle);
1495 if (ret != CAMERA_ERROR_NONE) {
1496 GST_ERROR_OBJECT(camerasrc, "hal_camera_stop_preview failed 0x%x", ret);
1497 camerasrc->preview_control.running = TRUE;
1501 camerasrc->mode = VIDEO_IN_MODE_NONE;
1504 GST_INFO_OBJECT(camerasrc, "LEAVE");
1510 static gboolean gst_tizencamerasrc_capture_start(GstTizenCameraSrc *camerasrc)
1512 int ret = CAMERA_ERROR_NONE;
1514 GST_INFO_OBJECT(camerasrc, "ENTERED - mode %d", camerasrc->mode);
1516 if (camerasrc->mode != VIDEO_IN_MODE_PREVIEW) {
1517 GST_WARNING_OBJECT(camerasrc, "Wrong state[%d]!", camerasrc->mode);
1521 GST_INFO_OBJECT(camerasrc, "start capture - count %d, interval %d",
1522 camerasrc->cap_count, camerasrc->cap_interval);
1524 ret = hal_camera_set_command(camerasrc->hal_handle,
1525 CAMERA_COMMAND_CAPTURE_COUNT, (void *)&camerasrc->cap_count);
1526 if (ret != CAMERA_ERROR_NONE)
1527 GST_WARNING_OBJECT(camerasrc, "set capture count failed 0x%x", ret);
1529 if (camerasrc->cap_count > 1) {
1530 ret = hal_camera_set_command(camerasrc->hal_handle,
1531 CAMERA_COMMAND_CAPTURE_INTERVAL, (void *)&camerasrc->cap_interval);
1532 if (ret != CAMERA_ERROR_NONE)
1533 GST_WARNING_OBJECT(camerasrc, "set capture interval failed 0x%x", ret);
1536 ret = hal_camera_start_capture(camerasrc->hal_handle, _camera_capture_cb, camerasrc);
1537 if (ret != CAMERA_ERROR_NONE) {
1538 GST_ERROR_OBJECT(camerasrc, "start capture failed 0x%x", ret);
1542 camerasrc->mode = VIDEO_IN_MODE_CAPTURE;
1544 GST_INFO_OBJECT(camerasrc, "CAPTURE STARTED!");
1550 static gboolean gst_tizencamerasrc_capture_stop(GstTizenCameraSrc *camerasrc)
1552 int ret = CAMERA_ERROR_NONE;
1554 GST_INFO_OBJECT(camerasrc, "ENTERED - mode %d", camerasrc->mode);
1556 if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) {
1557 ret = hal_camera_stop_capture(camerasrc->hal_handle);
1558 if (ret != CAMERA_ERROR_NONE) {
1559 GST_ERROR_OBJECT(camerasrc, "hal_camera_stop_capture failed 0x%x", ret);
1563 g_mutex_lock(&camerasrc->preview_control.lock);
1564 camerasrc->mode = VIDEO_IN_MODE_PREVIEW;
1565 g_cond_signal(&camerasrc->preview_control.cond);
1566 g_mutex_unlock(&camerasrc->preview_control.lock);
1568 GST_INFO_OBJECT(camerasrc, "CAPTURE STOPPED!");
1572 GST_WARNING_OBJECT(camerasrc, "Wrong state[%d]!", camerasrc->mode);
1578 static GstFlowReturn gst_tizencamerasrc_read_preview(GstTizenCameraSrc *camerasrc, GstBuffer **buffer)
1580 int preview_check_count = 0;
1582 BufferControl *control = &camerasrc->preview_control;
1584 GST_DEBUG_OBJECT(camerasrc, "check preview buffer list");
1586 g_mutex_lock(&control->lock);
1588 while (g_queue_is_empty(camerasrc->preview_buffer_list)) {
1589 GST_DEBUG_OBJECT(camerasrc, "buffer list is empty. waiting...");
1591 end_time = g_get_monotonic_time () + _BUFFER_WAIT_TIMEOUT;
1592 if (g_cond_wait_until(&control->cond, &control->lock, end_time)) {
1593 GST_DEBUG_OBJECT(camerasrc, "Signal received. Retry...");
1597 if (camerasrc->hal_error_code != CAMERA_ERROR_NONE) {
1598 GST_WARNING_OBJECT(camerasrc, "buffer timeout and error[0x%x]", camerasrc->hal_error_code);
1602 if (camerasrc->is_flushing) {
1603 g_mutex_unlock(&control->lock);
1604 GST_WARNING_OBJECT(camerasrc, "FLUSHING now");
1608 if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE)
1609 GST_WARNING_OBJECT(camerasrc, "capture mode now.");
1611 preview_check_count++;
1613 if (camerasrc->empty_buffer_timeout > 0 &&
1614 preview_check_count * _BUFFER_WAIT_TIMEOUT >= camerasrc->empty_buffer_timeout * 1000) {
1615 GST_ERROR_OBJECT(camerasrc, "wait buffer failed for [%d]ms", camerasrc->empty_buffer_timeout);
1619 GST_WARNING_OBJECT(camerasrc, "preview buffer timeout[%d]usec, retry[%d]",
1620 _BUFFER_WAIT_TIMEOUT, preview_check_count);
1623 *buffer = g_queue_pop_head(camerasrc->preview_buffer_list);
1625 g_mutex_unlock(&control->lock);
1627 if (*buffer == NULL) {
1628 GST_ERROR_OBJECT(camerasrc, "buffer is NULL (HAL error 0x%x)", camerasrc->hal_error_code);
1630 if (camerasrc->hal_error_code == CAMERA_ERROR_NONE)
1631 gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_DEVICE_READ);
1633 return GST_FLOW_ERROR;
1636 if (camerasrc->is_flushing)
1639 if (camerasrc->firsttime)
1640 camerasrc->firsttime = FALSE;
1642 GST_DEBUG_OBJECT(camerasrc, "preview buffer %p", *buffer);
1648 gst_buffer_unref(*buffer);
1652 GST_WARNING_OBJECT(camerasrc, "return GST_FLOW_FLUSHING");
1654 return GST_FLOW_FLUSHING;
1658 static GstFlowReturn gst_tizencamerasrc_read(GstTizenCameraSrc *camerasrc, GstBuffer **buffer)
1660 GstFlowReturn ret = GST_FLOW_OK;
1662 switch (camerasrc->mode) {
1663 case VIDEO_IN_MODE_PREVIEW:
1664 case VIDEO_IN_MODE_CAPTURE:
1665 case VIDEO_IN_MODE_VIDEO:
1666 GST_DEBUG_OBJECT(camerasrc, "gst_tizencamerasrc_read_preview");
1667 ret = gst_tizencamerasrc_read_preview(camerasrc, buffer);
1669 case VIDEO_IN_MODE_NONE:
1671 ret = GST_FLOW_ERROR;
1672 GST_ERROR_OBJECT (camerasrc, "can't reach statement.[camerasrc->mode=%d]", camerasrc->mode);
1676 if (buffer && (!(*buffer) || !GST_IS_BUFFER(*buffer))) {
1677 /* To avoid seg fault, make dummy buffer. */
1678 GST_WARNING_OBJECT (camerasrc, "Make a dummy buffer");
1679 *buffer = gst_buffer_new();
1686 static gboolean gst_tizencamerasrc_get_timeinfo(GstTizenCameraSrc *camerasrc, GstBuffer *buffer)
1690 GstClock *clock = NULL;
1691 GstClockTime timestamp = GST_CLOCK_TIME_NONE;
1692 GstClockTime duration = GST_CLOCK_TIME_NONE;
1694 if (!camerasrc || !buffer) {
1695 GST_WARNING_OBJECT (camerasrc, "Invalid pointer [hadle:%p, buffer:%p]", camerasrc, buffer);
1699 /* timestamps, LOCK to get clock and base time. */
1700 clock = GST_ELEMENT_CLOCK(camerasrc);
1702 /* the time now is the time of the clock minus the base time */
1703 gst_object_ref(clock);
1704 timestamp = gst_clock_get_time(clock) - GST_ELEMENT(camerasrc)->base_time;
1705 gst_object_unref(clock);
1707 /* if we have a framerate adjust timestamp for frame latency */
1708 if (camerasrc->fps_auto) {
1710 duration = GST_CLOCK_TIME_NONE;
1712 if (camerasrc->fps <= 0) {
1713 /*if fps is zero, auto fps mode*/
1718 fps_de = camerasrc->fps;
1721 if (fps_nu > 0 && fps_de > 0) {
1722 duration = gst_util_uint64_scale_int(GST_SECOND, fps_nu, fps_de);
1726 /* set default duration if duration is NONE : 30 fps */
1727 if (duration == GST_CLOCK_TIME_NONE) {
1728 duration = gst_util_uint64_scale_int(GST_SECOND, 1, 30);
1731 /* no clock, can't set timestamps */
1732 timestamp = GST_CLOCK_TIME_NONE;
1735 GST_BUFFER_TIMESTAMP(buffer) = timestamp;
1736 GST_BUFFER_DURATION(buffer) = duration;
1738 GST_LOG_OBJECT(camerasrc, "timestamp [%"GST_TIME_FORMAT" dur %" GST_TIME_FORMAT "]",
1739 GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
1740 GST_TIME_ARGS(GST_BUFFER_DURATION(buffer)));
1746 /* Gstreamer general functions */
1747 static gboolean gst_tizencamerasrc_src_start(GstBaseSrc *src)
1750 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC (src);
1752 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
1754 camerasrc->firsttime = TRUE;
1755 /* 'gst_tizencamerasrc_set_caps' will call gst_tizencamerasrc_start(). So skip to call it. */
1756 /*ret = gst_tizencamerasrc_start(camerasrc);*/
1758 GST_DEBUG_OBJECT(camerasrc, "LEAVE");
1764 static gboolean gst_tizencamerasrc_src_stop(GstBaseSrc *src)
1767 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(src);
1769 GST_DEBUG_OBJECT (camerasrc, "ENTERED");
1771 ret = gst_tizencamerasrc_stop(camerasrc);
1773 GST_DEBUG_OBJECT(camerasrc, "LEAVE");
1779 static GstFlowReturn gst_tizencamerasrc_src_create(GstPushSrc *src, GstBuffer **buffer)
1781 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC (src);
1784 GST_LOG_OBJECT(camerasrc, "ENTERED");
1786 ret = gst_tizencamerasrc_read(camerasrc, buffer);
1788 GST_LOG_OBJECT (camerasrc, "LEAVE");
1794 static void gst_tizencamerasrc_set_property(GObject *object, guint prop_id,
1795 const GValue *value, GParamSpec *pspec)
1799 GstTizenCameraSrc *camerasrc = NULL;
1801 g_return_if_fail(GST_IS_TIZENCAMERA_SRC(object));
1802 camerasrc = GST_TIZENCAMERA_SRC(object);
1806 camerasrc->camera_id = g_value_get_int(value);
1808 case ARG_DEVICE_NAME:
1809 g_free(camerasrc->device_name);
1810 camerasrc->device_name = g_value_dup_string(value);
1811 GST_INFO_OBJECT(camerasrc, "Set device name: %s", camerasrc->device_name);
1813 case ARG_DEVICE_BUS:
1814 camerasrc->device_bus = g_value_get_int(value);
1815 GST_INFO_OBJECT(camerasrc, "Set device bus: %d", camerasrc->device_bus);
1816 ret = hal_camera_set_command(camerasrc->hal_handle, CAMERA_COMMAND_DEVICE_BUS, (void *)&camerasrc->device_bus);
1818 case ARG_DEVICE_PORT:
1819 g_free(camerasrc->device_port);
1820 camerasrc->device_port = g_value_dup_string(value);
1821 GST_INFO_OBJECT(camerasrc, "Set device port: %s", camerasrc->device_port);
1822 ret = hal_camera_set_command(camerasrc->hal_handle, CAMERA_COMMAND_DEVICE_PORT, (void *)camerasrc->device_port);
1825 g_free(camerasrc->hal_name);
1826 camerasrc->hal_name = g_value_dup_string(value);
1828 /* reset camera hal interface handle */
1829 if (camerasrc->hal_handle) {
1830 GST_INFO_OBJECT(camerasrc, "Reset HAL intf: %p", camerasrc->hal_handle);
1831 hal_camera_deinit(camerasrc->hal_handle);
1832 camerasrc->hal_handle = NULL;
1835 if (camerasrc->hal_name && strlen(camerasrc->hal_name) == 0) {
1836 GST_WARNING_OBJECT(camerasrc, "The empty string for HAL name");
1837 g_free(camerasrc->hal_name);
1838 camerasrc->hal_name = NULL;
1841 GST_WARNING_OBJECT(camerasrc, "Set HAL name: %s", camerasrc->hal_name);
1843 ret = hal_camera_init(camerasrc->hal_name, &camerasrc->hal_handle);
1844 if (ret == CAMERA_ERROR_NONE) {
1845 ret = hal_camera_get_device_info_list(camerasrc->hal_handle, camerasrc->device_info);
1846 GST_WARNING_OBJECT(camerasrc, "HAL device info: 0x%x, count: %d", ret, camerasrc->device_info->count);
1848 ret = hal_camera_add_message_callback(camerasrc->hal_handle, __camera_hal_message_callback, camerasrc, &camerasrc->msg_cb_id);
1849 GST_WARNING_OBJECT(camerasrc, "HAL message cb: 0x%x, id: %d", ret, camerasrc->msg_cb_id);
1851 GST_ERROR_OBJECT(camerasrc, "hal_camera_init failed: 0x%x", ret);
1855 camerasrc->vflip = g_value_get_boolean(value);
1856 GST_INFO_OBJECT(camerasrc, "Set VFLIP : %d", camerasrc->vflip);
1859 camerasrc->hflip = g_value_get_boolean(value);
1860 GST_INFO_OBJECT(camerasrc, "Set HFLIP : %d", camerasrc->hflip);
1862 case ARG_HIGH_SPEED_FPS:
1863 camerasrc->high_speed_fps = g_value_get_int(value);
1864 GST_INFO_OBJECT(camerasrc, "Set HIGH SPEED FPS: %d", camerasrc->high_speed_fps);
1867 camerasrc->fps_auto = g_value_get_boolean(value);
1868 GST_INFO_OBJECT(camerasrc, "Set AUTO_FPS: %d", camerasrc->fps_auto);
1870 case ARG_EXTRA_PREVIEW:
1871 camerasrc->extra_preview = g_value_get_boolean(value);
1872 GST_INFO_OBJECT(camerasrc, "Enable extra preview: %d", camerasrc->extra_preview);
1873 if (camerasrc->extra_preview)
1874 ret = hal_camera_set_extra_preview_frame_cb(camerasrc->hal_handle, __camera_extra_preview_frame_cb, camerasrc);
1876 ret = hal_camera_unset_extra_preview_frame_cb(camerasrc->hal_handle);
1877 GST_INFO_OBJECT(camerasrc, "extra preview %s result: 0x%x",
1878 camerasrc->extra_preview ? "set" : "unset", ret);
1880 case ARG_LIVE_BUFFER_MAX:
1881 camerasrc->live_buffer_max = g_value_get_int(value);
1882 GST_WARNING_OBJECT(camerasrc, "live buffer max %d", camerasrc->live_buffer_max);
1884 case ARG_LIVE_BUFFER_MAX_RAW:
1885 camerasrc->live_buffer_max_raw = g_value_get_int(value);
1886 GST_WARNING_OBJECT(camerasrc, "live buffer max for raw format %d", camerasrc->live_buffer_max_raw);
1888 case ARG_EMPTY_BUFFER_TIMEOUT:
1889 camerasrc->empty_buffer_timeout = g_value_get_int(value);
1890 GST_INFO_OBJECT(camerasrc, "empty buffer timeout %dms", camerasrc->empty_buffer_timeout);
1892 case ARG_CAPTURE_FOURCC:
1893 camerasrc->cap_fourcc = g_value_get_uint(value);
1894 gst_tizencamerasrc_set_capture_format(camerasrc);
1896 case ARG_CAPTURE_WIDTH:
1897 camerasrc->cap_width_tmp = g_value_get_int(value);
1899 case ARG_CAPTURE_HEIGHT:
1900 camerasrc->cap_height_tmp = g_value_get_int(value);
1901 gst_tizencamerasrc_set_capture_format(camerasrc);
1903 case ARG_CAPTURE_INTERVAL:
1904 camerasrc->cap_interval = g_value_get_int(value);
1905 GST_INFO_OBJECT(camerasrc, "Set capture interval: %d", camerasrc->cap_interval);
1907 case ARG_CAPTURE_COUNT:
1908 tmp = g_value_get_int(value);
1909 camerasrc->cap_count = tmp;
1910 camerasrc->cap_count_reverse = tmp;
1911 GST_INFO_OBJECT(camerasrc, "Set capture count: %d", camerasrc->cap_count_reverse);
1913 case ARG_CAPTURE_QUALITY:
1914 camerasrc->cap_quality = g_value_get_int(value);
1915 GST_INFO_OBJECT(camerasrc, "Set capture quality : %d", camerasrc->cap_quality);
1917 case ARG_VIDEO_WIDTH:
1918 camerasrc->video_width = g_value_get_int(value);
1919 GST_INFO_OBJECT(camerasrc, "video width %d", camerasrc->video_width);
1921 case ARG_VIDEO_HEIGHT:
1922 camerasrc->video_height = g_value_get_int(value);
1923 GST_INFO_OBJECT(camerasrc, "video height %d", camerasrc->video_height);
1926 camerasrc->video_fps = g_value_get_int(value);
1927 GST_INFO_OBJECT(camerasrc, "video fps %d", camerasrc->video_fps);
1929 case ARG_RECORDING_HINT:
1930 camerasrc->recording_hint = g_value_get_boolean(value);
1932 GST_INFO_OBJECT(camerasrc, "recording-hint %d", camerasrc->recording_hint);
1934 if (camerasrc->recording_hint)
1935 gst_tizencamerasrc_set_video_format(camerasrc);
1938 camerasrc->bitrate = g_value_get_int(value);
1939 ret = hal_camera_set_command(camerasrc->hal_handle, CAMERA_COMMAND_BITRATE, (void *)&camerasrc->bitrate);
1940 GST_INFO_OBJECT(camerasrc, "Set bitrate : %d, ret 0x%x", camerasrc->bitrate, ret);
1942 case ARG_GOP_INTERVAL:
1943 camerasrc->gop_interval = g_value_get_int(value);
1944 ret = hal_camera_set_command(camerasrc->hal_handle, CAMERA_COMMAND_GOP_INTERVAL, (void *)&camerasrc->gop_interval);
1945 GST_INFO_OBJECT(camerasrc, "Set GOP interval : %d, ret 0x%x", camerasrc->gop_interval, ret);
1948 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1956 static void gst_tizencamerasrc_get_property(GObject *object, guint prop_id,
1957 GValue *value, GParamSpec *pspec)
1959 GstTizenCameraSrc *camerasrc;
1961 g_return_if_fail(GST_IS_TIZENCAMERA_SRC(object));
1962 camerasrc = GST_TIZENCAMERA_SRC(object);
1966 g_value_set_int(value, camerasrc->camera_id);
1968 case ARG_DEVICE_NAME:
1969 g_value_set_string(value, camerasrc->device_name);
1971 case ARG_DEVICE_BUS:
1972 g_value_set_int(value, camerasrc->device_bus);
1974 case ARG_DEVICE_PORT:
1975 g_value_set_string(value, camerasrc->device_port);
1978 g_value_set_string(value, camerasrc->hal_name);
1981 g_value_set_boolean(value, camerasrc->vflip);
1984 g_value_set_boolean(value, camerasrc->hflip);
1986 case ARG_HIGH_SPEED_FPS:
1987 g_value_set_int(value, camerasrc->high_speed_fps);
1990 g_value_set_boolean(value, camerasrc->fps_auto);
1992 case ARG_EXTRA_PREVIEW:
1993 g_value_set_boolean(value, camerasrc->extra_preview);
1995 case ARG_LIVE_BUFFER_MAX:
1996 g_value_set_int(value, camerasrc->live_buffer_max);
1998 case ARG_LIVE_BUFFER_MAX_RAW:
1999 g_value_set_int(value, camerasrc->live_buffer_max_raw);
2001 case ARG_EMPTY_BUFFER_TIMEOUT:
2002 g_value_set_int(value, camerasrc->empty_buffer_timeout);
2004 case ARG_BUFFER_QUARK:
2005 if (camerasrc->buffer_quark == _DEFAULT_BUFFER_QUARK) {
2006 camerasrc->buffer_quark = g_quark_from_static_string("tizencamerabuffer");
2007 GST_INFO_OBJECT(camerasrc, "quark for buffer [%u]", camerasrc->buffer_quark);
2009 g_value_set_uint(value, camerasrc->buffer_quark);
2011 case ARG_CAPTURE_FOURCC:
2012 g_value_set_uint(value, camerasrc->cap_fourcc);
2014 case ARG_CAPTURE_WIDTH:
2015 g_value_set_int(value, camerasrc->cap_width);
2017 case ARG_CAPTURE_HEIGHT:
2018 g_value_set_int(value, camerasrc->cap_height);
2020 case ARG_CAPTURE_INTERVAL:
2021 g_value_set_int(value, camerasrc->cap_interval);
2023 case ARG_CAPTURE_COUNT:
2024 g_value_set_int(value, camerasrc->cap_count);
2026 case ARG_CAPTURE_QUALITY:
2027 g_value_set_int(value, camerasrc->cap_quality);
2028 GST_INFO("GET capture quality : %d", camerasrc->cap_quality);
2030 case ARG_CAPTURE_PROVIDE_EXIF:
2031 g_value_set_boolean(value, camerasrc->cap_provide_exif);
2032 GST_INFO("Is Exif provided? : %d", camerasrc->cap_provide_exif);
2034 case ARG_VIDEO_WIDTH:
2035 g_value_set_int(value, camerasrc->video_width);
2037 case ARG_VIDEO_HEIGHT:
2038 g_value_set_int(value, camerasrc->video_height);
2041 g_value_set_int(value, camerasrc->video_fps);
2043 case ARG_RECORDING_HINT:
2044 g_value_set_boolean(value, camerasrc->recording_hint);
2047 g_value_set_int(value, camerasrc->bitrate);
2049 case ARG_GOP_INTERVAL:
2050 g_value_set_int(value, camerasrc->gop_interval);
2053 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
2061 static GstStateChangeReturn gst_tizencamerasrc_change_state(GstElement *element, GstStateChange transition)
2063 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2064 GstTizenCameraSrc *camerasrc;
2065 camerasrc = GST_TIZENCAMERA_SRC (element);
2067 switch (transition) {
2068 case GST_STATE_CHANGE_NULL_TO_READY:
2069 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: NULL -> READY");
2070 GST_INFO(" gst_tizencamerasrc_create");
2071 if (!gst_tizencamerasrc_create(camerasrc)){
2072 goto statechange_failed;
2075 case GST_STATE_CHANGE_READY_TO_PAUSED:
2076 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: READY -> PAUSED");
2077 ret = GST_STATE_CHANGE_NO_PREROLL;
2079 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2080 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> PLAYING");
2086 ret = GST_ELEMENT_CLASS(gst_tizencamerasrc_parent_class)->change_state(element, transition);
2087 if (ret == GST_STATE_CHANGE_FAILURE){
2091 switch (transition) {
2092 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2093 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PLAYING -> PAUSED");
2094 ret = GST_STATE_CHANGE_NO_PREROLL;
2096 case GST_STATE_CHANGE_PAUSED_TO_READY:
2097 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> READY");
2099 case GST_STATE_CHANGE_READY_TO_NULL:
2100 GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: READY -> NULL");
2101 GST_INFO(" gst_tizencamerasrc_destroy");
2102 if (!gst_tizencamerasrc_destroy(camerasrc)){
2103 goto statechange_failed;
2113 /* subclass must post a meaningful error message */
2114 GST_ERROR_OBJECT(camerasrc, "state change failed");
2116 return GST_STATE_CHANGE_FAILURE;
2120 static void gst_tizencamerasrc_finalize(GObject *object)
2124 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(object);
2126 GST_INFO_OBJECT(camerasrc, "ENTERED");
2128 ret = hal_camera_deinit(camerasrc->hal_handle);
2129 if (ret != CAMERA_ERROR_NONE)
2130 GST_ERROR_OBJECT(camerasrc, "hal_camera_deinit failed 0x%x", ret);
2132 camerasrc->hal_handle = NULL;
2134 g_cond_clear(&camerasrc->preview_control.cond);
2135 g_mutex_clear(&camerasrc->preview_control.lock);
2136 g_cond_clear(&camerasrc->extra_preview_control.cond);
2137 g_mutex_clear(&camerasrc->extra_preview_control.lock);
2138 SAFE_FREE_GQUEUE(camerasrc->preview_buffer_list);
2139 g_cond_clear(&camerasrc->video_control.cond);
2140 g_mutex_clear(&camerasrc->video_control.lock);
2142 if (camerasrc->allocator) {
2143 gst_object_unref(camerasrc->allocator);
2144 camerasrc->allocator = NULL;
2147 if (camerasrc->video_caps) {
2148 gst_caps_unref(camerasrc->video_caps);
2149 camerasrc->video_caps = NULL;
2152 for (i = 0 ; i < EXTRA_PREVIEW_STREAM_MAX ; i++) {
2153 if (camerasrc->extra_caps[i]) {
2154 gst_caps_unref(camerasrc->extra_caps[i]);
2155 camerasrc->extra_caps[i] = NULL;
2159 g_free(camerasrc->hal_name);
2160 g_free(camerasrc->device_info);
2161 g_free(camerasrc->device_name);
2162 g_free(camerasrc->device_port);
2164 GST_INFO_OBJECT(camerasrc, "LEAVE");
2166 if (G_OBJECT_CLASS (gst_tizencamerasrc_parent_class)->finalize)
2167 G_OBJECT_CLASS(gst_tizencamerasrc_parent_class)->finalize(object);
2173 void gst_tizencamerasrc_set_capture_command(GstTizenCameraSrc *camerasrc, GstCameraControlCaptureCommand cmd)
2175 if (camerasrc == NULL) {
2176 GST_ERROR_OBJECT(camerasrc, "camerasrc is NULL");
2180 GST_INFO_OBJECT(camerasrc, "ENTERED");
2182 if (cmd == GST_CAMERA_CONTROL_CAPTURE_COMMAND_START)
2183 gst_tizencamerasrc_capture_start(camerasrc);
2184 else if (cmd == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP)
2185 gst_tizencamerasrc_capture_stop(camerasrc);
2187 GST_WARNING_OBJECT(camerasrc, "not supported command %d", cmd);
2189 GST_INFO_OBJECT(camerasrc, "LEAVE");
2195 void gst_tizencamerasrc_set_record_command(GstTizenCameraSrc *camerasrc, GstCameraControlRecordCommand cmd)
2197 int ret = CAMERA_ERROR_NONE;
2199 if (camerasrc == NULL) {
2200 GST_ERROR_OBJECT(camerasrc, "camerasrc is NULL");
2204 GST_INFO_OBJECT(camerasrc, "ENTERED - cmd %d", cmd);
2206 if (cmd == GST_CAMERA_CONTROL_RECORD_COMMAND_START) {
2207 camerasrc->video_control.live_buffers = 0;
2208 camerasrc->video_control.is_first_frame = TRUE;
2209 if (camerasrc->video_caps) {
2210 gst_caps_unref(camerasrc->video_caps);
2211 camerasrc->video_caps = NULL;
2213 ret = hal_camera_start_record(camerasrc->hal_handle, __camera_video_frame_cb, camerasrc);
2214 } else if (cmd == GST_CAMERA_CONTROL_RECORD_COMMAND_STOP) {
2215 ret = hal_camera_stop_record(camerasrc->hal_handle);
2217 GST_WARNING_OBJECT(camerasrc, "not supported command %d", cmd);
2220 GST_INFO_OBJECT(camerasrc, "LEAVE - ret[0x%x]", ret);
2226 gboolean gst_tizencamerasrc_set_user_buffer_fd(GstTizenCameraSrc *camerasrc, int *fds, int number)
2228 int ret = CAMERA_ERROR_NONE;
2230 if (camerasrc == NULL) {
2231 GST_ERROR_OBJECT(camerasrc, "camerasrc is NULL");
2235 GST_INFO_OBJECT(camerasrc, "ENTERED - number %d", number);
2237 ret = hal_camera_set_user_buffer_fd(camerasrc->hal_handle, fds, number);
2239 GST_INFO_OBJECT(camerasrc, "LEAVE - ret 0x%x", ret);
2241 return (ret == CAMERA_ERROR_NONE ? TRUE : FALSE);
2246 gst_tizencamerasrc_negotiate (GstBaseSrc * basesrc)
2249 GstCaps *caps = NULL;
2250 GstCaps *peercaps = NULL;
2251 gboolean result = FALSE;
2253 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(basesrc);
2255 GST_INFO_OBJECT(camerasrc, "ENTERED");
2256 /* first see what is possible on our source pad */
2257 thiscaps = gst_pad_query_caps (GST_BASE_SRC_PAD (basesrc), NULL);
2258 GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps);
2260 /* nothing or anything is allowed, we're done */
2261 if (thiscaps == NULL || gst_caps_is_any (thiscaps))
2262 goto no_nego_needed;
2264 /* get the peer caps */
2265 peercaps = gst_pad_peer_query_caps (GST_BASE_SRC_PAD (basesrc), NULL);
2266 GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps);
2267 //LOG_CAPS (basesrc, peercaps);
2268 if (peercaps && !gst_caps_is_any (peercaps)) {
2269 GstCaps *icaps = NULL;
2272 /* Prefer the first caps we are compatible with that the peer proposed */
2273 for (i = 0; i < gst_caps_get_size (peercaps); i++) {
2274 /* get intersection */
2275 GstCaps *ipcaps = gst_caps_copy_nth (peercaps, i);
2277 GST_DEBUG_OBJECT (basesrc, "peer: %" GST_PTR_FORMAT, ipcaps);
2278 icaps = gst_caps_intersect (thiscaps, ipcaps);
2279 gst_caps_unref (ipcaps);
2281 /*s = gst_caps_get_structure (icaps, 0);
2282 gst_structure_get_fourcc(s, "format", &camerasrc->fourcc);
2283 if ((camerasrc->fourcc == GST_MAKE_FOURCC('S','N','1','2')) ||
2284 (camerasrc->fourcc == GST_MAKE_FOURCC('S','T','1','2'))) {
2287 if (!gst_caps_is_empty (icaps))
2290 gst_caps_unref (icaps);
2294 GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, icaps);
2296 /* If there are multiple intersections pick the one with the smallest
2297 * resolution strictly bigger then the first peer caps */
2298 if (gst_caps_get_size (icaps) > 1) {
2299 s = gst_caps_get_structure (peercaps, 0);
2301 int twidth, theight;
2302 int width = G_MAXINT, height = G_MAXINT;
2304 if (gst_structure_get_int (s, "width", &twidth)
2305 && gst_structure_get_int (s, "height", &theight)) {
2307 /* Walk the structure backwards to get the first entry of the
2308 * smallest resolution bigger (or equal to) the preferred resolution)
2310 for (i = gst_caps_get_size (icaps) - 1; i >= 0; i--) {
2311 GstStructure *is = gst_caps_get_structure (icaps, i);
2314 if (gst_structure_get_int (is, "width", &w)
2315 && gst_structure_get_int (is, "height", &h)) {
2316 if (w >= twidth && w <= width && h >= theight && h <= height) {
2325 caps = gst_caps_copy_nth (icaps, best);
2326 gst_caps_unref (icaps);
2331 gst_caps_unref (thiscaps);
2332 gst_caps_unref (peercaps);
2334 /* no peer or peer have ANY caps, work with our own caps then */
2338 caps = gst_caps_fixate(caps);
2341 if (!gst_caps_is_empty (caps)) {
2342 GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
2344 if (gst_caps_is_any (caps)) {
2345 /* hmm, still anything, so element can do anything and
2346 * nego is not needed */
2348 } else if (gst_caps_is_fixed (caps)) {
2349 /* yay, fixed caps, use those then */
2350 result = gst_tizencamerasrc_set_caps(basesrc, caps);
2353 gst_caps_unref (caps);
2359 GST_DEBUG_OBJECT (basesrc, "no negotiation needed");
2361 gst_caps_unref (thiscaps);
2367 static GstCaps *gst_tizencamerasrc_get_caps(GstBaseSrc *src, GstCaps *filter)
2369 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(src);
2370 GstCaps *ret = NULL;
2372 GST_DEBUG_OBJECT(camerasrc, "ENTERED");
2374 if (camerasrc->mode == VIDEO_IN_MODE_NONE) {
2375 GST_INFO_OBJECT(camerasrc, "Just return template caps.");
2376 GST_DEBUG_OBJECT(camerasrc, "LEAVE");
2378 ret = gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc));
2379 return filter ? gst_caps_intersect(ret, filter) : gst_caps_copy(ret);
2382 /*FIXME: Using "VIDIOC_ENUM_FMT".*/
2383 ret = gst_caps_copy(gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc)));
2385 if (filter != NULL) {
2386 gst_caps_take(&ret, gst_caps_intersect(ret, filter));
2389 GST_INFO_OBJECT(camerasrc, "probed caps: %p", ret);
2390 GST_DEBUG_OBJECT(camerasrc, "LEAVE");
2396 static gboolean __gst_tizencamerasrc_get_raw_pixel_info(int fourcc, camera_pixel_format_e *pix_format)
2398 if (pix_format == NULL) {
2399 GST_ERROR("NULL pointer");
2404 case GST_MAKE_FOURCC('I','4','2','0'):
2405 case GST_MAKE_FOURCC('S','4','2','0'):
2406 *pix_format = CAMERA_PIXEL_FORMAT_I420;;
2408 case GST_MAKE_FOURCC('Y','V','1','2'):
2409 *pix_format = CAMERA_PIXEL_FORMAT_YV12;
2411 case GST_MAKE_FOURCC('Y','U','Y','V'):
2412 case GST_MAKE_FOURCC('Y','U','Y','2'):
2413 case GST_MAKE_FOURCC('S','U','Y','V'):
2414 case GST_MAKE_FOURCC('S','U','Y','2'):
2415 *pix_format = CAMERA_PIXEL_FORMAT_YUYV;
2417 case GST_MAKE_FOURCC('U','Y','V','Y'):
2418 case GST_MAKE_FOURCC('S','Y','V','Y'):
2419 *pix_format = CAMERA_PIXEL_FORMAT_UYVY;
2421 case GST_MAKE_FOURCC('N','V','1','2'):
2422 case GST_MAKE_FOURCC('S','N','1','2'):
2423 *pix_format = CAMERA_PIXEL_FORMAT_NV12;
2425 case GST_MAKE_FOURCC('N','V','2','1'):
2426 case GST_MAKE_FOURCC('S','N','2','1'):
2427 *pix_format = CAMERA_PIXEL_FORMAT_NV21;
2429 case GST_MAKE_FOURCC('J','P','E','G'):
2430 *pix_format = CAMERA_PIXEL_FORMAT_JPEG;
2432 case GST_MAKE_FOURCC('M','J','P','G'):
2433 *pix_format = CAMERA_PIXEL_FORMAT_MJPEG;
2436 GST_ERROR("unknown fourcc %c%c%c%c",
2437 fourcc, fourcc >> 8, fourcc >> 16, fourcc >> 24);
2441 GST_INFO("pixel format[%c%c%c%c] -> [%d]",
2442 fourcc, fourcc >> 8, fourcc >> 16, fourcc >> 24,
2449 static gboolean __gst_tizencamerasrc_get_tbm_format(int pix_format, guint32 *tbm_format)
2451 if (tbm_format == NULL) {
2452 GST_ERROR("NULL pointer");
2456 switch (pix_format) {
2457 case CAMERA_PIXEL_FORMAT_I420:
2458 *tbm_format = TBM_FORMAT_YUV420;
2460 case CAMERA_PIXEL_FORMAT_YV12:
2461 *tbm_format = TBM_FORMAT_YVU420;
2463 case CAMERA_PIXEL_FORMAT_YUYV:
2464 *tbm_format = TBM_FORMAT_YUYV;
2466 case CAMERA_PIXEL_FORMAT_UYVY:
2467 *tbm_format = TBM_FORMAT_UYVY;
2469 case CAMERA_PIXEL_FORMAT_NV12:
2470 *tbm_format = TBM_FORMAT_NV12;
2472 case CAMERA_PIXEL_FORMAT_NV21:
2473 *tbm_format = TBM_FORMAT_NV21;
2476 GST_WARNING("unsupported pixel format[%d] for tbm", pix_format);
2484 static gboolean __gst_tizencamerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize)
2487 case GST_MAKE_FOURCC('I','4','2','0'): /* V4L2_PIX_FMT_YUV420 */
2488 case GST_MAKE_FOURCC('I','Y','U','V'):
2489 case GST_MAKE_FOURCC('Y','U','1','2'):
2490 case GST_MAKE_FOURCC('Y','V','1','2'):
2491 case GST_MAKE_FOURCC('S','4','2','0'): /* V4L2_PIX_FMT_NV12 tiled non-linear */
2492 *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
2493 *outsize += 2 * ((GST_ROUND_UP_8 (width) / 2) * (GST_ROUND_UP_2 (height) / 2));
2495 case GST_MAKE_FOURCC('Y','U','Y','V'): /* V4L2_PIX_FMT_YUYV */
2496 case GST_MAKE_FOURCC('Y','U','Y','2'): /* V4L2_PIX_FMT_YUYV */
2497 case GST_MAKE_FOURCC('S','U','Y','V'):
2498 case GST_MAKE_FOURCC('S','U','Y','2'):
2499 case GST_MAKE_FOURCC('U','Y','V','Y'): /* V4L2_PIX_FMT_UYVY */
2500 case GST_MAKE_FOURCC('S','Y','V','Y'): /* V4L2_PIX_FMT_UYVY */
2501 case GST_MAKE_FOURCC('4','2','2','P'): /* V4L2_PIX_FMT_YUV422P */
2502 case GST_MAKE_FOURCC('Y','4','2','B'): /* V4L2_PIX_FMT_YUV422P */
2503 case GST_MAKE_FOURCC('Y','4','1','P'): /* V4L2_PIX_FMT_Y41P */
2504 *outsize = (GST_ROUND_UP_2 (width) * 2) * height;
2506 case GST_MAKE_FOURCC('Y','4','1','B'): /* V4L2_PIX_FMT_YUV411P */
2507 *outsize = GST_ROUND_UP_4 (width) * height;
2508 *outsize += 2 * ((GST_ROUND_UP_8 (width) / 4) * height);
2510 case GST_MAKE_FOURCC('N','V','1','2'): /* V4L2_PIX_FMT_NV12 */
2511 case GST_MAKE_FOURCC('N','V','2','1'): /* V4L2_PIX_FMT_NV21 */
2512 case GST_MAKE_FOURCC('S','N','1','2'): /* V4L2_PIX_FMT_NV12 non-linear */
2513 case GST_MAKE_FOURCC('S','N','2','1'): /* V4L2_PIX_FMT_NV21 non-linear */
2514 *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
2515 *outsize += (GST_ROUND_UP_4 (width) * height) / 2;
2517 case GST_MAKE_FOURCC('J','P','E','G'):
2518 case GST_MAKE_FOURCC('M','J','P','G'):
2519 /* jpeg size can't be calculated here. */
2523 /* unknown format!! */
2532 static GstCaps *__gst_tizencamerasrc_get_caps_from_buffer(camera_buffer_s *buffer)
2534 char *format_string = NULL;
2536 GstCaps *caps = NULL;
2539 GST_ERROR("NULL buffer");
2543 switch (buffer->format) {
2544 case CAMERA_PIXEL_FORMAT_NV12:
2545 snprintf(mimetype, sizeof(mimetype), "video/x-raw");
2546 format_string = "NV12";
2548 case CAMERA_PIXEL_FORMAT_NV21:
2549 snprintf(mimetype, sizeof(mimetype), "video/x-raw");
2550 format_string = "NV21";
2552 case CAMERA_PIXEL_FORMAT_I420:
2553 snprintf(mimetype, sizeof(mimetype), "video/x-raw");
2554 format_string = "I420";
2556 case CAMERA_PIXEL_FORMAT_YV12:
2557 snprintf(mimetype, sizeof(mimetype), "video/x-raw");
2558 format_string = "YV12";
2560 case CAMERA_PIXEL_FORMAT_YUYV:
2561 snprintf(mimetype, sizeof(mimetype), "video/x-raw");
2562 format_string = "YUY2";
2564 case CAMERA_PIXEL_FORMAT_UYVY:
2565 snprintf(mimetype, sizeof(mimetype), "video/x-raw");
2566 format_string = "UYVY";
2568 case CAMERA_PIXEL_FORMAT_H264:
2569 snprintf(mimetype, sizeof(mimetype), "video/x-h264");
2571 case CAMERA_PIXEL_FORMAT_JPEG:
2572 snprintf(mimetype, sizeof(mimetype), "image/jpeg");
2574 case CAMERA_PIXEL_FORMAT_MJPEG:
2575 snprintf(mimetype, sizeof(mimetype), "video/x-jpeg");
2577 case CAMERA_PIXEL_FORMAT_VP8:
2578 snprintf(mimetype, sizeof(mimetype), "video/x-vp8");
2580 case CAMERA_PIXEL_FORMAT_VP9:
2581 snprintf(mimetype, sizeof(mimetype), "video/x-vp9");
2584 GST_ERROR("unsupported format[%d]", buffer->format);
2588 caps = gst_caps_new_simple(mimetype,
2589 "width", G_TYPE_INT, buffer->resolution.width,
2590 "height", G_TYPE_INT, buffer->resolution.height,
2593 GST_ERROR("caps failed for [%s][%s]", mimetype, format_string);
2598 gst_caps_set_simple(caps, "format", G_TYPE_STRING, format_string, NULL);
2600 GST_INFO("new caps [%"GST_PTR_FORMAT"]", caps);
2606 static gboolean gst_tizencamerasrc_get_caps_info(GstTizenCameraSrc *camerasrc, GstCaps *caps, guint *size)
2613 const gchar *mimetype;
2614 GstVideoInfo video_info;
2615 const gchar *caps_format_name = NULL;
2616 guint32 caps_fourcc = 0;
2617 const GValue *framerate;
2618 GstStructure *structure = NULL;
2620 GST_WARNING_OBJECT(camerasrc, "caps[%"GST_PTR_FORMAT"]", caps);
2622 structure = gst_caps_get_structure(caps, 0);
2624 if (!gst_structure_get_int(structure, "width", &width)) {
2625 GST_ERROR_OBJECT(camerasrc, "width failed");
2629 if (!gst_structure_get_int(structure, "height", &height)) {
2630 GST_ERROR_OBJECT(camerasrc, "height failed");
2634 if (!gst_structure_get_int(structure, "rotate", &rotate))
2635 GST_WARNING_OBJECT(camerasrc, "Failed to get rotate info in caps. set default 0.");
2637 GST_INFO_OBJECT(camerasrc, "Succeed to get rotate [%d] info in caps", rotate);
2639 if (!gst_video_info_from_caps(&camerasrc->video_info, caps)) {
2640 GST_ERROR_OBJECT(camerasrc, "failed to get video info from caps");
2644 camerasrc->width = width;
2645 camerasrc->height = height;
2646 camerasrc->rotate = rotate;
2648 framerate = gst_structure_get_value(structure, "framerate");
2650 GST_INFO("Set FPS as default(30/1)");
2652 /* set default fps if framerate is not existed in caps */
2653 fps_n = _DEFAULT_FPS;
2656 fps_n = gst_value_get_fraction_numerator(framerate);
2657 fps_d = gst_value_get_fraction_denominator(framerate);
2659 /* numerator and denominator should be bigger than zero */
2661 GST_WARNING("numerator of FPS is %d. make it default(15).", fps_n);
2662 fps_n = _DEFAULT_FPS;
2666 GST_WARNING("denominator of FPS is %d. make it 1.", fps_d);
2671 camerasrc->fps = (int)((float)fps_n / (float)fps_d);
2673 if (!gst_video_info_from_caps(&video_info, caps)) {
2674 GST_ERROR_OBJECT(camerasrc, "get video info from caps[%"GST_PTR_FORMAT"]", caps);
2678 if (GST_VIDEO_INFO_IS_YUV(&video_info)) {
2679 caps_format_name = gst_structure_get_string(structure, "format");
2680 if (!caps_format_name) {
2681 GST_ERROR_OBJECT(camerasrc, "NULL format name from caps[%"GST_PTR_FORMAT"]", caps);
2685 g_strlcpy(camerasrc->format_name, caps_format_name, sizeof(camerasrc->format_name));
2686 caps_fourcc = MAKE_FOURCC_FROM_STRING(camerasrc->format_name);
2688 __gst_tizencamerasrc_get_frame_size(caps_fourcc, width, height, size);
2689 __gst_tizencamerasrc_get_raw_pixel_info(caps_fourcc, &camerasrc->pix_format);
2691 camerasrc->is_encoded_format = FALSE;
2694 mimetype = gst_structure_get_name(structure);
2697 if (!strcmp(mimetype, "video/x-h264")) {
2698 g_strlcpy(camerasrc->format_name, GST_VIDEO_INFO_NAME(&video_info), sizeof(camerasrc->format_name));
2699 camerasrc->pix_format = CAMERA_PIXEL_FORMAT_H264;
2700 } else if (!strcmp(mimetype, "image/jpeg") || !strcmp(mimetype, "video/x-jpeg")) {
2701 g_strlcpy(camerasrc->format_name, GST_VIDEO_INFO_NAME(&video_info), sizeof(camerasrc->format_name));
2702 camerasrc->pix_format = CAMERA_PIXEL_FORMAT_MJPEG;
2703 } else if (!strcmp(mimetype, "video/x-vp8")) {
2704 g_strlcpy(camerasrc->format_name, GST_VIDEO_INFO_NAME(&video_info), sizeof(camerasrc->format_name));
2705 camerasrc->pix_format = CAMERA_PIXEL_FORMAT_VP8;
2706 } else if (!strcmp(mimetype, "video/x-vp9")) {
2707 g_strlcpy(camerasrc->format_name, GST_VIDEO_INFO_NAME(&video_info), sizeof(camerasrc->format_name));
2708 camerasrc->pix_format = CAMERA_PIXEL_FORMAT_VP9;
2710 GST_ERROR_OBJECT(camerasrc, "unsupported caps[%"GST_PTR_FORMAT"]", caps);
2714 camerasrc->is_encoded_format = TRUE;
2717 GST_INFO_OBJECT(camerasrc, "pixformat[%d], size[%u] from [%"GST_PTR_FORMAT"]",
2718 camerasrc->pix_format, *size, caps);
2724 static void __gst_tizencamerasrc_post_message_int(GstTizenCameraSrc *camerasrc, const char *msg_name, const char *field_name, int value)
2726 GstMessage *m = NULL;
2727 GstStructure *s = NULL;
2729 if (!camerasrc || !msg_name || !field_name) {
2730 GST_ERROR("pointer is NULL %p, %p, %p", camerasrc, msg_name, field_name);
2734 GST_INFO("post message [%s] %s %d", msg_name, field_name, value);
2736 s = gst_structure_new(msg_name, field_name, G_TYPE_INT, value, NULL);
2738 GST_ERROR("gst_structure_new failed");
2739 gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_OUT_OF_MEMORY);
2743 m = gst_message_new_element(GST_OBJECT(camerasrc), s);
2745 GST_ERROR("gst_message_new_element failed");
2746 gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_OUT_OF_MEMORY);
2750 gst_element_post_message(GST_ELEMENT(camerasrc), m);
2756 static int __gst_tizencamerasrc_release_buffer(GstTizenCameraSrc *camerasrc, GstTizenCameraBufferType type, int index, int stream_id)
2759 GST_ERROR("NULL handle");
2760 return CAMERA_ERROR_INVALID_PARAMETER;
2764 case BUFFER_TYPE_PREVIEW:
2765 return hal_camera_release_preview_buffer(camerasrc->hal_handle, index);
2766 case BUFFER_TYPE_VIDEO:
2767 return hal_camera_release_video_buffer(camerasrc->hal_handle, index);
2768 case BUFFER_TYPE_EXTRA_PREVIEW:
2769 return hal_camera_release_extra_preview_buffer(camerasrc->hal_handle, stream_id, index);
2771 GST_ERROR_OBJECT(camerasrc, "unknown type[%d], [%d,%d]", type, index, stream_id);
2772 return CAMERA_ERROR_INVALID_PARAMETER;
2777 static gboolean gst_tizencamerasrc_set_caps(GstBaseSrc *src, GstCaps *caps)
2780 GstTizenCameraSrc *camerasrc = NULL;
2781 gboolean res = FALSE;
2784 tbm_surface_h t_surface = NULL;
2786 camerasrc = GST_TIZENCAMERA_SRC(src);
2788 GST_INFO_OBJECT(camerasrc, "ENTERED");
2790 if (camerasrc->mode == VIDEO_IN_MODE_PREVIEW ||
2791 camerasrc->mode == VIDEO_IN_MODE_VIDEO) {
2792 GST_INFO_OBJECT(camerasrc, "Proceed set_caps");
2793 GST_INFO(" gst_tizencamerasrc_stop");
2794 if (!gst_tizencamerasrc_stop(camerasrc)) {
2795 GST_INFO_OBJECT(camerasrc, "Cam sensor stop failed.");
2797 } else if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) {
2798 GST_ERROR_OBJECT(camerasrc, "A mode of avsystem camera is capture. Not to proceed set_caps.");
2799 GST_DEBUG_OBJECT(camerasrc, "LEAVE");
2802 GST_INFO_OBJECT(camerasrc, "A mode of avsystem camera is unknown[%d]. Proceed set_caps.", camerasrc->mode);
2805 /* we want our own v4l2 type of fourcc codes */
2806 if (!gst_tizencamerasrc_get_caps_info(camerasrc, caps, &size)) {
2807 GST_INFO_OBJECT(camerasrc, "can't get capture information from caps %p", caps);
2811 /* get tbm surface info */
2812 if (__gst_tizencamerasrc_get_tbm_format(camerasrc->pix_format, &camerasrc->tbm_format)) {
2814 t_surface = tbm_surface_create(camerasrc->width, camerasrc->height, camerasrc->tbm_format);
2816 GST_ERROR_OBJECT(camerasrc, "tbm surface create failed");
2820 memset(&camerasrc->ts_info, 0x0, sizeof(tbm_surface_info_s));
2822 tbm_ret = tbm_surface_get_info(t_surface, &camerasrc->ts_info);
2824 GST_WARNING_OBJECT(camerasrc, "TBM info: res[%ux%u], stride[%u], size[%u]",
2825 camerasrc->ts_info.width, camerasrc->ts_info.height,
2826 camerasrc->ts_info.planes[0].stride, camerasrc->ts_info.size);
2828 tbm_surface_destroy(t_surface);
2831 if (tbm_ret != TBM_SURFACE_ERROR_NONE) {
2832 GST_ERROR_OBJECT(camerasrc, "tbm surface info get failed");
2835 } else if (camerasrc->pix_format != CAMERA_PIXEL_FORMAT_H264 &&
2836 camerasrc->pix_format != CAMERA_PIXEL_FORMAT_MJPEG &&
2837 camerasrc->pix_format != CAMERA_PIXEL_FORMAT_VP8 &&
2838 camerasrc->pix_format != CAMERA_PIXEL_FORMAT_VP9) {
2839 GST_ERROR_OBJECT(camerasrc, "unsupported pixel format %d",camerasrc->pix_format);
2843 GST_INFO(" gst_tizencamerasrc_start");
2844 if (!gst_tizencamerasrc_start(camerasrc)) {
2845 GST_INFO_OBJECT (camerasrc, "Cam sensor start failed.");
2848 res = gst_pad_push_event (GST_BASE_SRC_PAD (src), gst_event_new_caps (caps));
2850 GST_INFO_OBJECT (camerasrc, "LEAVE");
2856 static gboolean gst_tizencamerasrc_unlock(GstBaseSrc *basesrc)
2858 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(basesrc);
2861 GST_ERROR("NULL handle");
2865 GST_INFO_OBJECT(camerasrc, "flush start");
2867 camerasrc->is_flushing = TRUE;
2872 static gboolean gst_tizencamerasrc_unlock_stop(GstBaseSrc *basesrc)
2874 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(basesrc);
2877 GST_ERROR("NULL handle");
2881 GST_INFO_OBJECT(camerasrc, "flush stop");
2883 camerasrc->is_flushing = FALSE;
2888 static void gst_tizencamerasrc_class_init(GstTizenCameraSrcClass *klass)
2890 GST_DEBUG_CATEGORY_INIT(tizencamerasrc_debug, "tizencamerasrc", 0, "tizencamerasrc element");
2892 GObjectClass *gobject_class;
2893 GstElementClass *element_class;
2894 GstBaseSrcClass *basesrc_class;
2895 GstPushSrcClass *pushsrc_class;
2897 GST_DEBUG("ENTERED");
2899 gobject_class = G_OBJECT_CLASS(klass);
2900 element_class = GST_ELEMENT_CLASS(klass);
2901 basesrc_class = GST_BASE_SRC_CLASS(klass);
2902 pushsrc_class = GST_PUSH_SRC_CLASS(klass);
2904 gobject_class->set_property = gst_tizencamerasrc_set_property;
2905 gobject_class->get_property = gst_tizencamerasrc_get_property;
2906 gobject_class->finalize = gst_tizencamerasrc_finalize;
2907 element_class->change_state = gst_tizencamerasrc_change_state;
2908 gst_element_class_add_pad_template(element_class, gst_static_pad_template_get (&src_factory));
2909 gst_element_class_set_static_metadata(element_class,
2910 "Camera Source GStreamer Plug-in",
2912 "camera src for videosrc based GStreamer Plug-in",
2913 "Jeongmo Yang <jm80.yang@samsung.com>");
2914 basesrc_class->start = gst_tizencamerasrc_src_start;
2915 basesrc_class->stop = gst_tizencamerasrc_src_stop;
2916 basesrc_class->get_caps = gst_tizencamerasrc_get_caps;
2917 basesrc_class->set_caps = gst_tizencamerasrc_set_caps;
2918 basesrc_class->negotiate = gst_tizencamerasrc_negotiate;
2919 basesrc_class->unlock = GST_DEBUG_FUNCPTR(gst_tizencamerasrc_unlock);
2920 basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR(gst_tizencamerasrc_unlock_stop);
2921 pushsrc_class->create = gst_tizencamerasrc_src_create;
2923 g_object_class_install_property(gobject_class, ARG_CAMERA_ID,
2924 g_param_spec_int("camera-id", "index number of camera to activate",
2925 "index number of camera to activate",
2926 _CAMERA_ID_MIN, _CAMERA_ID_MAX, 0,
2927 G_PARAM_READWRITE));
2929 g_object_class_install_property(gobject_class, ARG_DEVICE_NAME,
2930 g_param_spec_string("device-name", "Device name",
2931 "Name of the device, camera-id will be ignored if this is set",
2933 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2935 g_object_class_install_property(gobject_class, ARG_DEVICE_BUS,
2936 g_param_spec_int("device-bus", "The device bus number",
2937 "The device bus number",
2939 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2941 g_object_class_install_property(gobject_class, ARG_DEVICE_PORT,
2942 g_param_spec_string("device-port", "The device port number",
2943 "The device port number",
2945 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2947 g_object_class_install_property(gobject_class, ARG_HAL_NAME,
2948 g_param_spec_string("hal-name", "HAL name",
2949 "The name of the HAL library, and setting \"NULL\" or empty string will load the default HAL. "
2950 "It should be set at least once after creating the element, "
2951 "otherwise it will fail when set something or change state.",
2953 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2955 g_object_class_install_property(gobject_class, ARG_VFLIP,
2956 g_param_spec_boolean("vflip", "Flip vertically",
2957 "Flip camera input vertically",
2959 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2961 g_object_class_install_property(gobject_class, ARG_HFLIP,
2962 g_param_spec_boolean("hflip", "Flip horizontally",
2963 "Flip camera input horizontally",
2965 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2967 g_object_class_install_property(gobject_class, ARG_HIGH_SPEED_FPS,
2968 g_param_spec_int("high-speed-fps", "Fps for high speed recording",
2969 "If this value is 0, the element doesn't activate high speed recording.",
2970 0, G_MAXINT, _DEFAULT_HIGH_SPEED_FPS,
2971 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2973 g_object_class_install_property(gobject_class, ARG_AUTO_FPS,
2974 g_param_spec_boolean("fps-auto", "FPS Auto",
2975 "Field for auto fps setting",
2977 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2979 g_object_class_install_property(gobject_class, ARG_EXTRA_PREVIEW,
2980 g_param_spec_boolean("extra-preview", "Extra preview",
2981 "Flag for extra preview",
2982 _DEFAULT_EXTRA_PREVIEW,
2983 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2985 g_object_class_install_property(gobject_class, ARG_LIVE_BUFFER_MAX,
2986 g_param_spec_int("live-buffer-max", "Live buffer max",
2987 "Maximum number of live buffers",
2988 1, G_MAXINT, _DEFAULT_LIVE_BUFFER_MAX,
2989 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2991 g_object_class_install_property(gobject_class, ARG_LIVE_BUFFER_MAX_RAW,
2992 g_param_spec_int("live-buffer-max-raw", "Live buffer max for RAW format",
2993 "Maximum number of live buffers for RAW format",
2994 1, G_MAXINT, _DEFAULT_LIVE_BUFFER_MAX_RAW,
2995 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2997 g_object_class_install_property(gobject_class, ARG_EMPTY_BUFFER_TIMEOUT,
2998 g_param_spec_int("empty-buffer-timeout", "Timeout for empty buffer",
2999 "Timeout to wait for buffer to be available. (ms, 0 = unlimited)",
3000 0, G_MAXINT, _DEFAULT_EMPTY_BUFFER_TIMEOUT,
3001 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3003 g_object_class_install_property(gobject_class, ARG_BUFFER_QUARK,
3004 g_param_spec_uint("buffer-quark", "Buffer quark",
3005 "GQuark for buffer.",
3006 0, G_MAXUINT, _DEFAULT_BUFFER_QUARK,
3007 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
3009 g_object_class_install_property(gobject_class, ARG_CAPTURE_FOURCC,
3010 g_param_spec_uint("capture-fourcc", "Capture format",
3011 "Fourcc value for capture format",
3013 G_PARAM_READWRITE));
3015 g_object_class_install_property(gobject_class, ARG_CAPTURE_WIDTH,
3016 g_param_spec_int("capture-width", "Capture width",
3017 "Width for camera size to capture, it should be set before Height",
3018 0, G_MAXINT, _DEFAULT_CAP_WIDTH,
3019 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3021 g_object_class_install_property(gobject_class, ARG_CAPTURE_HEIGHT,
3022 g_param_spec_int("capture-height", "Capture height",
3023 "Height for camera size to capture, it should be set after width",
3024 0, G_MAXINT, _DEFAULT_CAP_HEIGHT,
3025 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3027 g_object_class_install_property(gobject_class, ARG_CAPTURE_INTERVAL,
3028 g_param_spec_int("capture-interval", "Capture interval",
3029 "Interval time to capture (millisecond)",
3030 0, G_MAXINT, _DEFAULT_CAP_INTERVAL,
3031 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3033 g_object_class_install_property(gobject_class, ARG_CAPTURE_COUNT,
3034 g_param_spec_int("capture-count", "Capture count",
3035 "Capture count for multishot",
3036 1, G_MAXINT, _DEFAULT_CAP_COUNT,
3037 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3039 g_object_class_install_property(gobject_class, ARG_CAPTURE_QUALITY,
3040 g_param_spec_int("capture-quality", "Capture quality",
3041 "Quality of capture image",
3042 1, 100, _DEFAULT_CAP_QUALITY,
3043 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3045 g_object_class_install_property(gobject_class, ARG_CAPTURE_PROVIDE_EXIF,
3046 g_param_spec_boolean("provide-exif", "Whether EXIF is provided",
3047 "Does capture provide EXIF?",
3048 _DEFAULT_CAP_PROVIDE_EXIF,
3049 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
3051 g_object_class_install_property(gobject_class, ARG_BITRATE,
3052 g_param_spec_int("bitrate", "Bitrate of encoded stream",
3053 "Bitrate of encoded stream like H.264",
3054 1, G_MAXINT, _DEFAULT_BITRATE,
3055 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3057 g_object_class_install_property(gobject_class, ARG_GOP_INTERVAL,
3058 g_param_spec_int("gop-interval", "GOP interval of encoded stream",
3059 "GOP(Group Of Pictures) interval of encoded stream like H.264",
3060 1, G_MAXINT, _DEFAULT_GOP_INTERVAL,
3061 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
3064 * GstTizenCameraSrc::still-capture:
3065 * @camerasrc: the camerasrc instance
3066 * @buffer: the buffer that will be pushed - Main
3067 * @buffer: the buffer that will be pushed - Thumbnail
3068 * @buffer: the buffer that will be pushed - Screennail
3070 gst_tizencamerasrc_signals[SIGNAL_STILL_CAPTURE] =
3071 g_signal_new("still-capture",
3072 G_TYPE_FROM_CLASS(klass),
3074 G_STRUCT_OFFSET(GstTizenCameraSrcClass, still_capture),
3077 gst_tizencamerasrc_VOID__OBJECT_OBJECT_OBJECT,
3079 3, /* Number of parameter */
3080 GST_TYPE_SAMPLE, /* Main image buffer */
3081 GST_TYPE_SAMPLE, /* Thumbnail image buffer */
3082 GST_TYPE_SAMPLE); /* Screennail image buffer */
3085 * GstCameraSrc::video-stream-cb:
3086 * @camerasrc: the camerasrc instance
3087 * @buffer: the buffer that will be pushed
3089 gst_tizencamerasrc_signals[SIGNAL_VIDEO_STREAM_CB] =
3090 g_signal_new("video-stream-cb",
3091 G_TYPE_FROM_CLASS(klass),
3093 G_STRUCT_OFFSET(GstTizenCameraSrcClass, video_stream_cb),
3096 gst_tizencamerasrc_VOID__OBJECT_VIDEO_STREAM,
3098 1, /* Number of parameter */
3099 GST_TYPE_SAMPLE); /* record buffer */
3102 * GstCameraSrc::extra-preview-stream-cb:
3103 * @camerasrc: the camerasrc instance
3104 * @stream_id: the id of extra stream
3105 * @buffer: the buffer that will be pushed
3107 gst_tizencamerasrc_signals[SIGNAL_EXTRA_PREVIEW_STREAM_CB] =
3108 g_signal_new("extra-preview-stream-cb",
3109 G_TYPE_FROM_CLASS(klass),
3111 G_STRUCT_OFFSET(GstTizenCameraSrcClass, extra_preview_stream_cb),
3114 gst_tizencamerasrc_VOID__OBJECT_EXTRA_PREVIEW_STREAM,
3116 2, /* Number of parameter */
3117 G_TYPE_INT, /* stream id */
3118 GST_TYPE_SAMPLE); /* extra preview buffer */
3126 static void gst_tizencamerasrc_init(GstTizenCameraSrc *camerasrc)
3128 GST_INFO_OBJECT(camerasrc, "ENTERED");
3130 camerasrc->hal_handle = NULL;
3131 camerasrc->mode = VIDEO_IN_MODE_NONE;
3132 camerasrc->firsttime = TRUE;
3133 camerasrc->cap_count_current = -1;
3134 camerasrc->cap_count_reverse = _DEFAULT_CAP_COUNT;
3137 camerasrc->device_info = g_new0(camera_device_info_list_s, 1);
3138 camerasrc->fps = _DEFAULT_FPS;
3139 camerasrc->rotate = 0;
3140 camerasrc->high_speed_fps = _DEFAULT_HIGH_SPEED_FPS;
3141 camerasrc->fps_auto = _DEFAULT_FPS_AUTO;
3142 camerasrc->pix_format = _DEFAULT_PIX_FORMAT;
3143 g_strlcpy(camerasrc->format_name, _DEFAULT_PIX_FORMAT_NAME, sizeof(camerasrc->format_name));
3144 camerasrc->preview_control.running = FALSE;
3145 camerasrc->vflip = FALSE;
3146 camerasrc->hflip = FALSE;
3147 camerasrc->camera_id = _DEFAULT_CAMERA_ID;
3148 camerasrc->device_name = NULL;
3149 camerasrc->device_port = NULL;
3150 camerasrc->preview_buffer_list = g_queue_new ();
3151 camerasrc->live_buffer_max = _DEFAULT_LIVE_BUFFER_MAX;
3152 camerasrc->live_buffer_max_raw = _DEFAULT_LIVE_BUFFER_MAX_RAW;
3153 camerasrc->empty_buffer_timeout = _DEFAULT_EMPTY_BUFFER_TIMEOUT;
3156 camerasrc->cap_fourcc = MAKE_FOURCC_FROM_STRING(_DEFAULT_CAPTURE_FORMAT_NAME);
3157 camerasrc->cap_width = _DEFAULT_CAP_WIDTH;
3158 camerasrc->cap_height = _DEFAULT_CAP_HEIGHT;
3159 camerasrc->cap_interval = _DEFAULT_CAP_INTERVAL;
3160 camerasrc->cap_count = _DEFAULT_CAP_COUNT;
3161 camerasrc->cap_quality = _DEFAULT_CAP_QUALITY;
3162 camerasrc->cap_provide_exif = _DEFAULT_CAP_PROVIDE_EXIF;
3164 /* encoded stream */
3165 camerasrc->bitrate = _DEFAULT_BITRATE;
3166 camerasrc->gop_interval = _DEFAULT_GOP_INTERVAL;
3168 g_mutex_init(&camerasrc->preview_control.lock);
3169 g_cond_init(&camerasrc->preview_control.cond);
3170 g_mutex_init(&camerasrc->extra_preview_control.lock);
3171 g_cond_init(&camerasrc->extra_preview_control.cond);
3172 g_mutex_init(&camerasrc->video_control.lock);
3173 g_cond_init(&camerasrc->video_control.cond);
3175 /* tizen allocator */
3176 camerasrc->allocator = gst_tizen_allocator_new();
3178 camerasrc->buffer_quark = _DEFAULT_BUFFER_QUARK;
3180 /* we operate in time */
3181 gst_base_src_set_format(GST_BASE_SRC(camerasrc), GST_FORMAT_TIME);
3182 gst_base_src_set_live(GST_BASE_SRC(camerasrc), TRUE);
3183 gst_base_src_set_do_timestamp(GST_BASE_SRC(camerasrc), TRUE);
3185 GST_INFO_OBJECT(camerasrc, "LEAVE");
3191 static gboolean plugin_init(GstPlugin *plugin)
3195 error = gst_element_register(plugin, "tizencamerasrc", GST_RANK_PRIMARY + 100, GST_TYPE_TIZENCAMERA_SRC);
3201 GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
3204 "Tizen reference camera source plug-in",
3208 "Samsung Electronics Co",
3209 "http://www.samsung.com")
3211 /* GstURIHandler interface */
3213 gst_tizencamerasrc_uri_get_type (GType type)
3218 static const gchar * const*
3219 gst_tizencamerasrc_uri_get_protocols (GType type)
3221 static const gchar *protocols[] = { "camera", NULL };
3226 gst_tizencamerasrc_uri_get_uri (GstURIHandler * handler)
3228 return strdup("camera://0");
3232 gst_tizencamerasrc_uri_set_uri (GstURIHandler * handler, const gchar * uri, GError **error)
3234 GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC (handler);
3235 const gchar *device = "0";
3236 if (strcmp (uri, "camera://") != 0) {
3239 g_object_set (camerasrc, "camera-id", atoi(device), NULL);
3246 gst_tizencamerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
3248 GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
3250 iface->get_type = gst_tizencamerasrc_uri_get_type;
3251 iface->get_protocols = gst_tizencamerasrc_uri_get_protocols;
3252 iface->get_uri = gst_tizencamerasrc_uri_get_uri;
3253 iface->set_uri = gst_tizencamerasrc_uri_set_uri;