From 002b616e1bcb9d50619d755c8b9f6cee384675c1 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Mon, 8 Jan 2018 09:48:39 +0900 Subject: [PATCH 01/16] tizenwlsink : Check instance of object_type Change-Id: I4ab2944d8a9432a370279e2bd9fef9ce974fa17e Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 8 ++++++-- tizenwlsink/src/wldisplay.c | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 51fad82..594d63a 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -725,7 +725,7 @@ gst_tizen_wl_sink_make_flush_buffer (GstWlDisplay * display, if (dst.ptr) tbm_bo_unmap (bo); g_free (flush_buffer); - return FALSE; + return FALSE; } /* copy */ memcpy (dst.ptr, src.ptr, bo_size); @@ -1469,8 +1469,12 @@ gst_tizen_wl_sink_find_display (GstTizenWlSink * sink) ret = FALSE; } #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT - if (G_LIKELY (sink->display)) + if (G_LIKELY (sink->display)) { sink->display->USE_TBM = sink->USE_TBM; + } else { + GST_ERROR ("Failed to create GstWlDisplay"); + ret = FALSE; + } #endif } } diff --git a/tizenwlsink/src/wldisplay.c b/tizenwlsink/src/wldisplay.c index cb5b7b3..b1c8e27 100644 --- a/tizenwlsink/src/wldisplay.c +++ b/tizenwlsink/src/wldisplay.c @@ -371,6 +371,12 @@ gst_wl_display_new_existing (struct wl_display * display, g_return_val_if_fail (display != NULL, NULL); self = g_object_new (GST_TYPE_WL_DISPLAY, NULL); +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT + if (self == NULL) { + GST_ERROR ("g_object_new return value is null"); + return NULL; + } +#endif self->display = display; self->own_display = take_ownership; -- 2.7.4 From cd44bdfb0aead8128089b767f4f9fe832a8902e2 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 9 Jan 2018 14:57:27 +0900 Subject: [PATCH 02/16] fixed svace issues Change-Id: I4e8f1f3c4bb55dc65c22c80308a89b12f4f0c754 --- packaging/gst-plugins-tizen.spec | 2 +- video360/src/gstvideo360.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 20ee3d2..1903cb8 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,7 +9,7 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 51 +Release: 52 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ diff --git a/video360/src/gstvideo360.c b/video360/src/gstvideo360.c index 0edc77f..cde73eb 100644 --- a/video360/src/gstvideo360.c +++ b/video360/src/gstvideo360.c @@ -830,13 +830,20 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) GstMemory *out_mem; #endif GstMemory *in_mem; + GstEvent *event; int ret; - if (gst_pad_check_reconfigure (pad)) - if (!gst_video360_sink_event (pad, parent, - gst_pad_get_sticky_event (pad, GST_EVENT_CAPS, 0))) + if (gst_pad_check_reconfigure (pad)) { + event = gst_pad_get_sticky_event (pad, GST_EVENT_CAPS, 0); + if (!event) return GST_FLOW_NOT_NEGOTIATED; + if (!gst_video360_sink_event (pad, parent, event)) { + gst_event_unref (event); + return GST_FLOW_NOT_NEGOTIATED; + } + } + if (this->passthrough) return gst_pad_push (this->srcpad, in_buf); -- 2.7.4 From 8cab2eb123263db085db7549716575e3027996d3 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Thu, 25 Jan 2018 13:13:22 +0900 Subject: [PATCH 03/16] tizenwlsink : Check non top-level window created by App for tbm memory allocation Change-Id: I8375dfb37774782e9cc9ebfcbfdc9c242c0dd2c2 Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 594d63a..3ac5f31 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -1915,7 +1915,9 @@ gst_tizen_wl_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) if (sink->display->is_native_format == TRUE) return FALSE; - if (!gst_wl_window_is_toplevel (sink->window)) + /* in case of using gst-launch, top level window is maded after propose allocation, + * so we can avoid allocating tbm memory of wayland when use app's window with normal video format */ + if (G_UNLIKELY (sink->window)) return FALSE; gst_query_parse_allocation (query, &caps, &need_pool); -- 2.7.4 From 1ee15f63d2f50a18cbbc94fcf77dc4de0fc0c6b2 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Wed, 7 Feb 2018 11:26:34 +0900 Subject: [PATCH 04/16] tizenwlsink : GST_TYPE_WL_DISPLAY type init for camera TCT Change-Id: I59ed41e3465da4fd52e176cff1f9e9ca5d6ec2a8 Signed-off-by: Hyunil --- tizenwlsink/src/wldisplay.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tizenwlsink/src/wldisplay.c b/tizenwlsink/src/wldisplay.c index b1c8e27..738a759 100644 --- a/tizenwlsink/src/wldisplay.c +++ b/tizenwlsink/src/wldisplay.c @@ -365,11 +365,20 @@ gst_wl_display_new_existing (struct wl_display * display, { GstWlDisplay *self; GError *err = NULL; +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT + GObject *temp = NULL; +#endif gint i; FUNCTION; g_return_val_if_fail (display != NULL, NULL); - +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT + temp = g_type_class_ref (GST_TYPE_WL_DISPLAY); + if (temp) { + g_type_class_unref(temp); + GST_WARNING ("GST_TYPE_WL_DISPLAY type init for Camera TCT"); + } +#endif self = g_object_new (GST_TYPE_WL_DISPLAY, NULL); #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT if (self == NULL) { -- 2.7.4 From 101bfd48248003e818a879b0613a6078c4a454de Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 19 Feb 2018 14:14:44 +0900 Subject: [PATCH 05/16] fixed issue when setting/getting properties Change-Id: I00dac338dd68a19438bb2ac6377d7811cda17b94 --- packaging/gst-plugins-tizen.spec | 2 +- video360/src/gstvideo360.c | 19 +++++++------------ video360/src/gstvideo360.h | 7 ------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 1903cb8..4439c5d 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,7 +9,7 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 52 +Release: 53 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ diff --git a/video360/src/gstvideo360.c b/video360/src/gstvideo360.c index cde73eb..edc6d66 100644 --- a/video360/src/gstvideo360.c +++ b/video360/src/gstvideo360.c @@ -338,11 +338,9 @@ gst_video360_init (GstVideo360 * this) this->projection_bounds_bottom = 0; this->projection_bounds_left = 0; this->projection_bounds_right = 0; - this->requested_horizontal_fov_degree = - this->horizontal_fov_degree = HORIZONTAL_FOV_DEGREE; - this->requested_vertical_fov_degree = - this->vertical_fov_degree = VERTICAL_FOV_DEGREE; - this->requested_passthrough = this->passthrough = FALSE; + this->horizontal_fov_degree = HORIZONTAL_FOV_DEGREE; + this->vertical_fov_degree = VERTICAL_FOV_DEGREE; + this->passthrough = FALSE; this->zoom = 1.0; #ifdef GST_TIZEN_GL_PLATFORM_EGL @@ -427,11 +425,11 @@ gst_video360_set_property (GObject * object, guint prop_id, gst_video360_set_crops_gl (this); break; case PROP_HFOV: - this->requested_horizontal_fov_degree = g_value_get_uint (value); + this->horizontal_fov_degree = g_value_get_uint (value); gst_pad_mark_reconfigure (this->sinkpad); break; case PROP_VFOV: - this->requested_vertical_fov_degree = g_value_get_uint (value); + this->vertical_fov_degree = g_value_get_uint (value); gst_pad_mark_reconfigure (this->sinkpad); break; case PROP_ZOOM: @@ -439,7 +437,7 @@ gst_video360_set_property (GObject * object, guint prop_id, gst_video360_set_zoom_gl (this); break; case PROP_PASSTHROUGH: - this->requested_passthrough = g_value_get_boolean (value); + this->passthrough = g_value_get_boolean (value); gst_pad_mark_reconfigure (this->sinkpad); break; default: @@ -541,7 +539,7 @@ gst_video360_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) gst_caps_ref (caps); gst_event_unref (event); - if (!(this->passthrough = this->requested_passthrough)) { + if (!(this->passthrough)) { structure = gst_caps_get_structure (caps, 0); ret = gst_structure_get_int (structure, "width", @@ -594,9 +592,6 @@ gst_video360_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) this->panorama_width = this->input_frame_width + this->projection_bounds_left + this->projection_bounds_right; - this->horizontal_fov_degree = this->requested_horizontal_fov_degree; - this->vertical_fov_degree = this->requested_vertical_fov_degree; - /* Select FOV frame size in pixels based on equator length and given * horizontal/vertical FOV in degrees. */ diff --git a/video360/src/gstvideo360.h b/video360/src/gstvideo360.h index 18333af..ff49671 100644 --- a/video360/src/gstvideo360.h +++ b/video360/src/gstvideo360.h @@ -274,13 +274,6 @@ struct _GstVideo360 gboolean passthrough; float zoom; - /* Below fields contain requested values (set via properties) until they are - * applied at CAPS negotiation. - * */ - unsigned int requested_horizontal_fov_degree; - unsigned int requested_vertical_fov_degree; - gboolean requested_passthrough; - /***************************************************************************** * Element's internal variables * **************************************************************************/ -- 2.7.4 From eb3be53d27532c91e5ac1393a2333c6141756da4 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Tue, 13 Mar 2018 15:26:24 +0900 Subject: [PATCH 06/16] tizenwlsink : Remove code about camera TCT which check g_objcet_new return value Change-Id: Ibdab93543d89f3bdb8b70d64acf6681f3bcdbe18 Signed-off-by: Hyunil --- tizenwlsink/src/wldisplay.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/tizenwlsink/src/wldisplay.c b/tizenwlsink/src/wldisplay.c index 738a759..cb5b7b3 100644 --- a/tizenwlsink/src/wldisplay.c +++ b/tizenwlsink/src/wldisplay.c @@ -365,27 +365,12 @@ gst_wl_display_new_existing (struct wl_display * display, { GstWlDisplay *self; GError *err = NULL; -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT - GObject *temp = NULL; -#endif gint i; FUNCTION; g_return_val_if_fail (display != NULL, NULL); -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT - temp = g_type_class_ref (GST_TYPE_WL_DISPLAY); - if (temp) { - g_type_class_unref(temp); - GST_WARNING ("GST_TYPE_WL_DISPLAY type init for Camera TCT"); - } -#endif + self = g_object_new (GST_TYPE_WL_DISPLAY, NULL); -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT - if (self == NULL) { - GST_ERROR ("g_object_new return value is null"); - return NULL; - } -#endif self->display = display; self->own_display = take_ownership; -- 2.7.4 From 753ef7c39088e71f49aed5f35544661d5114dd2f Mon Sep 17 00:00:00 2001 From: Hyunil Date: Wed, 21 Mar 2018 17:06:43 +0900 Subject: [PATCH 07/16] tizenwlsink: Add necessary new code from upgraded gstreamer 1.12 Replace render_frame() to show_frame() Add GstVideoMeta, gst_video_frame_map(), gst_tizen_wl_sink_create_pool(), gst_wl_display_check_format_for_shm(), gst_wl_display_check_format_for_tbm() and some minor change Change-Id: Id593fc9c1faf46096053ea28361a42c9baefe9e6 Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 341 +++++++++++++++++++-------------------- tizenwlsink/src/wldisplay.c | 49 +++++- tizenwlsink/src/wldisplay.h | 9 +- tizenwlsink/src/wlvideoformat.c | 16 +- tizenwlsink/src/wlwindow.c | 19 ++- tizenwlsink/src/wlwindow.h | 12 +- 6 files changed, 250 insertions(+), 196 deletions(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 3ac5f31..b334296 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -208,7 +208,7 @@ static gboolean gst_tizen_wl_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer); static gboolean gst_tizen_wl_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query); -static gboolean gst_tizen_wl_sink_render (GstBaseSink * bsink, +static gboolean gst_tizen_wl_sink_show_frame (GstVideoSink * bsink, GstBuffer * buffer); /* VideoOverlay interface */ @@ -258,18 +258,19 @@ gst_tizen_wl_sink_class_init (GstTizenWlSinkClass * klass) GObjectClass *gobject_class; GstElementClass *gstelement_class; GstBaseSinkClass *gstbasesink_class; + GstVideoSinkClass *gstvideosink_class; FUNCTION; gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; gstbasesink_class = (GstBaseSinkClass *) klass; + gstvideosink_class = (GstVideoSinkClass *) klass; gobject_class->set_property = gst_tizen_wl_sink_set_property; gobject_class->get_property = gst_tizen_wl_sink_get_property; gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_tizen_wl_sink_finalize); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sink_template)); + gst_element_class_add_static_pad_template (gstelement_class, &sink_template); gst_element_class_set_static_metadata (gstelement_class, "wayland video sink", "Sink/Video", @@ -289,7 +290,8 @@ gst_tizen_wl_sink_class_init (GstTizenWlSinkClass * klass) gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_tizen_wl_sink_preroll); gstbasesink_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_tizen_wl_sink_propose_allocation); - gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_tizen_wl_sink_render); + gstvideosink_class->show_frame = + GST_DEBUG_FUNCPTR (gst_tizen_wl_sink_show_frame); #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_tizen_wl_sink_event); gstbasesink_class->get_times = @@ -901,7 +903,7 @@ gst_tizen_wl_sink_render_flush_buffer (GstBaseSink * bsink) g_return_if_fail (sink != NULL); g_return_if_fail (sink->last_buffer != NULL); - gst_tizen_wl_sink_render (bsink, sink->last_buffer); + gst_tizen_wl_sink_show_frame (GST_VIDEO_SINK_CAST (bsink), sink->last_buffer); } static void @@ -909,6 +911,7 @@ gst_tizen_wl_sink_render_last_sample (GstTizenWlSink * sink) { GstSample *last_sample = NULL; GstBuffer *last_buffer = NULL; + GstBaseSink *bsink = GST_BASE_SINK (sink); FUNCTION; g_return_if_fail (sink != NULL); @@ -918,7 +921,7 @@ gst_tizen_wl_sink_render_last_sample (GstTizenWlSink * sink) if (last_buffer) { GST_LOG ("PAUSED state : last buffer %p", last_buffer); gst_buffer_ref (last_buffer); - gst_tizen_wl_sink_render (GST_BASE_SINK (sink), last_buffer); + gst_tizen_wl_sink_show_frame (GST_VIDEO_SINK_CAST (bsink), last_buffer); gst_buffer_unref (last_buffer); last_buffer = NULL; } @@ -1562,6 +1565,9 @@ gst_tizen_wl_sink_change_state (GstElement * element, GstStateChange transition) */ if (sink->display && !sink->window) { /* -> the window was toplevel */ g_clear_object (&sink->display); + g_mutex_lock (&sink->render_lock); + sink->redraw_pending = FALSE; + g_mutex_unlock (&sink->render_lock); } g_mutex_unlock (&sink->display_lock); g_clear_object (&sink->pool); @@ -1609,6 +1615,7 @@ gst_tizen_wl_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) sink = GST_TIZEN_WL_SINK (bsink); caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink)); + caps = gst_caps_make_writable (caps); #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT /* To Do : When caps negotiation is newly needed by such as gapless, waylandsink may have to make display when disable-overlay is TRUE in here */ @@ -1620,10 +1627,7 @@ gst_tizen_wl_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) GValue value = G_VALUE_INIT; GArray *formats; gint i; -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT - uint32_t tbm_fmt; -#endif - enum wl_shm_format fmt; + guint fmt; g_value_init (&list, GST_TYPE_LIST); g_value_init (&value, G_TYPE_STRING); @@ -1632,34 +1636,34 @@ gst_tizen_wl_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) formats = sink->display->tbm_formats; else /* SHM */ #endif - formats = sink->display->formats; + formats = sink->display->shm_formats; for (i = 0; i < formats->len; i++) { #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT if (sink->USE_TBM) { - tbm_fmt = g_array_index (formats, uint32_t, i); - g_value_set_string (&value, gst_wl_tbm_format_to_string (tbm_fmt)); + fmt = g_array_index (formats, uint32_t, i); + g_value_set_string (&value, gst_wl_tbm_format_to_string (fmt)); gst_value_list_append_value (&list, &value); /* TBM doesn't support Native formats(SN12, ST12, SN21, SR32 and S420), So we add Native formats manually as supported format. */ - if (tbm_fmt == TBM_FORMAT_NV12) { + if (fmt == TBM_FORMAT_NV12) { g_value_set_string (&value, gst_video_format_to_string (GST_VIDEO_FORMAT_SN12)); gst_value_list_append_value (&list, &value); - } else if (tbm_fmt == TBM_FORMAT_NV12MT) { + } else if (fmt == TBM_FORMAT_NV12MT) { g_value_set_string (&value, gst_video_format_to_string (GST_VIDEO_FORMAT_ST12)); gst_value_list_append_value (&list, &value); - } else if (tbm_fmt == TBM_FORMAT_NV21) { + } else if (fmt == TBM_FORMAT_NV21) { g_value_set_string (&value, gst_video_format_to_string (GST_VIDEO_FORMAT_SN21)); gst_value_list_append_value (&list, &value); - } else if (tbm_fmt == TBM_FORMAT_ARGB8888) { + } else if (fmt == TBM_FORMAT_ARGB8888) { g_value_set_string (&value, gst_video_format_to_string (GST_VIDEO_FORMAT_SR32)); gst_value_list_append_value (&list, &value); - } else if (tbm_fmt == TBM_FORMAT_YUV420) { + } else if (fmt == TBM_FORMAT_YUV420) { g_value_set_string (&value, gst_video_format_to_string (GST_VIDEO_FORMAT_S420)); gst_value_list_append_value (&list, &value); @@ -1676,13 +1680,12 @@ gst_tizen_wl_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) #endif } - caps = gst_caps_make_writable (caps); - gst_structure_set_value (gst_caps_get_structure (caps, 0), "format", &list); + gst_structure_take_value (gst_caps_get_structure (caps, 0), "format", + &list); GST_DEBUG_OBJECT (sink, "display caps: %" GST_PTR_FORMAT, caps); g_value_unset (&value); g_value_unset (&list); - } g_mutex_unlock (&sink->display_lock); @@ -1699,20 +1702,34 @@ gst_tizen_wl_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) return caps; } +static GstBufferPool * +gst_tizen_wl_sink_create_pool (GstTizenWlSink * sink, GstCaps * caps) +{ + GstBufferPool *pool = NULL; + GstStructure *structure; + gsize size = sink->video_info.size; + + pool = gst_video_buffer_pool_new (); + + structure = gst_buffer_pool_get_config (pool); + /* the minimum amount of buffers to allocate is 6, it same with number of H/W codec buffer */ + gst_buffer_pool_config_set_params (structure, caps, size, 6, 0); + gst_buffer_pool_config_set_allocator (structure, + gst_tizen_wl_shm_allocator_get (), NULL); + + if (!gst_buffer_pool_set_config (pool, structure)) { + g_object_unref (pool); + pool = NULL; + } + + return pool; +} + static gboolean gst_tizen_wl_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) { GstTizenWlSink *sink; - GstBufferPool *newpool; - GstVideoInfo info; -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT - uint32_t tbm_format = -1; -#endif - enum wl_shm_format format = -1; - - GArray *formats; - gint i; - GstStructure *structure; + GstVideoFormat format; GstTizenWlShmAllocator *self = NULL; FUNCTION; @@ -1722,118 +1739,59 @@ gst_tizen_wl_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) GST_WARNING_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps); /* extract info from caps */ - if (!gst_video_info_from_caps (&info, caps)) + if (!gst_video_info_from_caps (&sink->video_info, caps)) goto invalid_format; -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT - if (sink->USE_TBM) { - tbm_format = - gst_video_format_to_wl_tbm_format (GST_VIDEO_INFO_FORMAT (&info)); - if ((gint) tbm_format == -1) - goto invalid_format; - } else { - format = gst_video_format_to_wl_shm_format (GST_VIDEO_INFO_FORMAT (&info)); - if ((gint) format == -1) - goto invalid_format; - } -#else /* open source */ - format = gst_video_format_to_wl_shm_format (GST_VIDEO_INFO_FORMAT (&info)); - if ((gint) format == -1) - goto invalid_format; -#endif + format = GST_VIDEO_INFO_FORMAT (&sink->video_info); + sink->video_info_changed = TRUE; - /* verify we support the requested format */ -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT + /* get idea + use_dmabuf = gst_caps_features_contains (gst_caps_get_features (caps, 0), + GST_CAPS_FEATURE_MEMORY_DMABUF); */ + + /* validate the format base on the memory type. */ if (sink->USE_TBM) { - GST_WARNING ("USE TBM FORMAT"); - formats = sink->display->tbm_formats; - for (i = 0; i < formats->len; i++) { - if (g_array_index (formats, uint32_t, i) == tbm_format) - break; - } - } else { /* USE SHM */ - GST_LOG ("USE SHM FORMAT"); - formats = sink->display->formats; - for (i = 0; i < formats->len; i++) { - if (g_array_index (formats, uint32_t, i) == format) - break; - } + if (!gst_wl_display_check_format_for_tbm (sink->display, format)) + goto unsupported_format; + } else if (!gst_wl_display_check_format_for_shm (sink->display, format)) { + goto unsupported_format; } -#else /* open source */ + + /* verify we support the requested format */ +#ifndef TIZEN_FEATURE_WLSINK_ENHANCEMENT + /* open source */ formats = sink->display->formats; for (i = 0; i < formats->len; i++) { if (g_array_index (formats, uint32_t, i) == format) break; } #endif - if (i >= formats->len) - goto unsupported_format; #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT /* init frame rate for baseink */ - sink->fps_n = info.fps_n; - sink->fps_d = info.fps_d; + sink->fps_n = sink->video_info.fps_n; + sink->fps_d = sink->video_info.fps_d; /* init value for set source */ sink->crop_x = sink->crop_y = sink->crop_w = sink->crop_h = 0; - if (sink->USE_TBM) { - if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_SN12 || - GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ST12 || - GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_SN21 || - GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_SR32 || - GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_S420) { - sink->display->is_native_format = TRUE; - - /* store the video info */ - sink->video_info = info; - sink->video_info_changed = TRUE; - } else { - sink->display->is_native_format = FALSE; - self = GST_TIZEN_WL_SHM_ALLOCATOR (gst_tizen_wl_shm_allocator_get ()); - self->display = sink->display; - /* create a new pool for the new configuration */ - newpool = gst_video_buffer_pool_new (); - if (!newpool) - goto pool_failed; - - structure = gst_buffer_pool_get_config (newpool); - gst_buffer_pool_config_set_params (structure, caps, info.size, 6, 0); - gst_buffer_pool_config_set_allocator (structure, - gst_tizen_wl_shm_allocator_get (), NULL); - if (!gst_buffer_pool_set_config (newpool, structure)) - goto config_failed; - - /* store the video info */ - sink->video_info = info; - sink->video_info_changed = TRUE; - - gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); - gst_object_unref (newpool); - } - } else { /* USE SHM */ - + if (GST_VIDEO_INFO_FORMAT (&sink->video_info) == GST_VIDEO_FORMAT_SN12 || + GST_VIDEO_INFO_FORMAT (&sink->video_info) == GST_VIDEO_FORMAT_ST12 || + GST_VIDEO_INFO_FORMAT (&sink->video_info) == GST_VIDEO_FORMAT_SN21 || + GST_VIDEO_INFO_FORMAT (&sink->video_info) == GST_VIDEO_FORMAT_SR32 || + GST_VIDEO_INFO_FORMAT (&sink->video_info) == GST_VIDEO_FORMAT_S420) { + /* USE TBM with native format */ + sink->display->is_native_format = TRUE; + } else { + sink->display->is_native_format = FALSE; + /* USE SHM or USE TBM with non native format */ self = GST_TIZEN_WL_SHM_ALLOCATOR (gst_tizen_wl_shm_allocator_get ()); self->display = sink->display; - /* create a new pool for the new configuration */ - newpool = gst_video_buffer_pool_new (); - if (!newpool) - goto pool_failed; - - structure = gst_buffer_pool_get_config (newpool); - gst_buffer_pool_config_set_params (structure, caps, info.size, 6, 0); - gst_buffer_pool_config_set_allocator (structure, - gst_tizen_wl_shm_allocator_get (), NULL); - if (!gst_buffer_pool_set_config (newpool, structure)) - goto config_failed; - - /* store the video info */ - sink->video_info = info; - sink->video_info_changed = TRUE; - - gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); - gst_object_unref (newpool); + /* create a new pool for the new caps */ + if (sink->pool) + gst_object_unref (sink->pool); + sink->pool = gst_tizen_wl_sink_create_pool (sink, caps); } sink->is_native_format = sink->display->is_native_format; @@ -1841,7 +1799,6 @@ gst_tizen_wl_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) if (sink->window) gst_tizen_wl_sink_update_window_geometry (sink); - #else /*open source */ /* create a new pool for the new configuration */ newpool = gst_video_buffer_pool_new (); @@ -1876,7 +1833,7 @@ unsupported_format: #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT if (sink->USE_TBM) GST_DEBUG_OBJECT (sink, "Format %s is not available on the display", - gst_wl_tbm_format_to_string (tbm_format)); + gst_wl_tbm_format_to_string (format)); else /*USE SHM */ GST_DEBUG_OBJECT (sink, "Format %s is not available on the display", gst_wl_shm_format_to_string (format)); @@ -1886,48 +1843,33 @@ unsupported_format: #endif return FALSE; } -pool_failed: - { - GST_DEBUG_OBJECT (sink, "Failed to create new pool"); - return FALSE; - } -config_failed: - { - GST_DEBUG_OBJECT (bsink, "failed setting config"); - gst_object_unref (newpool); - return FALSE; - } } static gboolean gst_tizen_wl_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) { GstTizenWlSink *sink = GST_TIZEN_WL_SINK (bsink); + GstCaps *caps; GstStructure *config; guint size, min_bufs, max_bufs; - -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT gboolean need_pool; - GstCaps *caps; - FUNCTION; - - if (sink->USE_TBM) { - if (sink->display->is_native_format == TRUE) - return FALSE; - /* in case of using gst-launch, top level window is maded after propose allocation, - * so we can avoid allocating tbm memory of wayland when use app's window with normal video format */ - if (G_UNLIKELY (sink->window)) - return FALSE; +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT + if (sink->USE_TBM && sink->display->is_native_format) + return FALSE; +#endif - gst_query_parse_allocation (query, &caps, &need_pool); + gst_query_parse_allocation (query, &caps, &need_pool); - if (caps == NULL) { - GST_DEBUG_OBJECT (bsink, "no caps specified"); - return FALSE; - } +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT + if (!caps) { + GST_DEBUG_OBJECT (bsink, "no caps specified"); + return FALSE; } #endif + if (!need_pool) + return FALSE; + config = gst_buffer_pool_get_config (sink->pool); gst_buffer_pool_config_get_params (config, NULL, &size, &min_bufs, &max_bufs); @@ -1936,9 +1878,11 @@ gst_tizen_wl_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) gst_query_add_allocation_pool (query, sink->pool, size, min_bufs, max_bufs); gst_query_add_allocation_param (query, gst_tizen_wl_shm_allocator_get (), NULL); + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); gst_structure_free (config); GST_WARNING ("set propose allocation"); + return TRUE; } @@ -1960,7 +1904,7 @@ gst_tizen_wl_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer) return GST_FLOW_OK; } #endif - return gst_tizen_wl_sink_render (bsink, buffer); + return gst_tizen_wl_sink_show_frame (GST_VIDEO_SINK_CAST (bsink), buffer); } static void @@ -1971,7 +1915,10 @@ frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time) GST_LOG ("frame_redraw_cb"); - g_atomic_int_set (&sink->redraw_pending, FALSE); + g_mutex_lock (&sink->render_lock); + sink->redraw_pending = FALSE; + g_mutex_unlock (&sink->render_lock); + GST_INFO ("wl_callback_destroy (wl_callback@%p)", callback); wl_callback_destroy (callback); } @@ -2031,7 +1978,7 @@ render_last_buffer (GstTizenWlSink * sink) wlbuffer = gst_buffer_get_wl_buffer (sink->last_buffer); surface = gst_wl_window_get_wl_surface (sink->window); - g_atomic_int_set (&sink->redraw_pending, TRUE); + sink->redraw_pending = TRUE; callback = wl_surface_frame (surface); GST_INFO ("wl_callback@%p = wl_surface_frame (video_surface@%p)", callback, surface); @@ -2052,7 +1999,6 @@ render_last_buffer (GstTizenWlSink * sink) gst_wl_window_render (sink->window, wlbuffer, info); } - static gboolean gst_tizen_wl_sink_has_wlbuffer (GstTizenWlSink * sink, GstBuffer * buffer) { @@ -2092,6 +2038,7 @@ gst_tizen_wl_sink_no_create_wlbuffer (GstTizenWlSink * sink, GstBuffer * buffer) GST_LOG ("buffer(%p) is created by waylandsink has a wl_buffer, " "writing directly", buffer); } else { + /* check mm_video_buf by log */ GST_LOG ("buffer(%p) is created by previous plugins with BufferPool has a wl_buffer, " "writing directly", buffer); @@ -2188,20 +2135,30 @@ static GstFlowReturn GstWlBuffer *wlbuffer; GstMemory *mem; GstTizenWlShmMemory *shm_mem; - GstMapInfo src; struct wl_buffer *wbuf = NULL; GstFlowReturn ret = GST_FLOW_OK; + GstStructure *config; + GstCaps *caps; + GstVideoFrame src, dst; + GstVideoInfo src_info = sink->video_info; FUNCTION; + g_return_val_if_fail (sink != NULL, GST_FLOW_ERROR); g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR); GST_LOG ("Use normal format with wayland TBM or SHM"); /* sink->pool always exists (created in set_caps), but it may not * be active if upstream is not using it */ - if (!gst_buffer_pool_is_active (sink->pool) && - !gst_buffer_pool_set_active (sink->pool, TRUE)) { - GST_ERROR ("failed to activate bufferpool."); - return GST_FLOW_ERROR; + if (!gst_buffer_pool_is_active (sink->pool)) { + config = gst_buffer_pool_get_config (sink->pool); + gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL); + gst_buffer_pool_config_set_params (config, caps, sink->video_info.size, 6, + 0); + + /* This is a video pool, it should not fail with basic setings */ + if (!gst_buffer_pool_set_config (sink->pool, config) || + !gst_buffer_pool_set_active (sink->pool, TRUE)) + return GST_FLOW_ERROR; } ret = gst_buffer_pool_acquire_buffer (sink->pool, &sink->to_render, NULL); @@ -2214,8 +2171,11 @@ static GstFlowReturn wlbuffer = gst_buffer_get_wl_buffer (buffer); if (G_UNLIKELY (!wlbuffer)) { mem = gst_buffer_peek_memory (sink->to_render, 0); + + /* for log */ shm_mem = (GstTizenWlShmMemory *) mem; GST_LOG ("to_render(%p), shm_mem->fd(%d)", sink->to_render, shm_mem->fd); + wbuf = gst_tizen_wl_shm_memory_construct_wl_buffer (mem, sink->display, &sink->video_info); @@ -2226,9 +2186,22 @@ static GstFlowReturn wlbuffer = gst_buffer_add_wl_buffer (sink->to_render, wbuf, sink->display); } - gst_buffer_map (buffer, &src, GST_MAP_READ); - gst_buffer_fill (sink->to_render, 0, src.data, src.size); - gst_buffer_unmap (buffer, &src); + if (!gst_video_frame_map (&dst, &sink->video_info, sink->to_render, + GST_MAP_WRITE)) { + GST_ERROR ("Video memory can not be written from userspace."); + return GST_FLOW_ERROR; + } + + if (!gst_video_frame_map (&src, &src_info, buffer, GST_MAP_READ)) { + gst_video_frame_unmap (&dst); + GST_ERROR ("Video memory can not be read from userspace."); + return GST_FLOW_ERROR; + } + + gst_video_frame_copy (&dst, &src); + + gst_video_frame_unmap (&src); + gst_video_frame_unmap (&dst); return ret; } @@ -2238,12 +2211,28 @@ gst_tizen_wl_sink_create_wlbuffer (GstTizenWlSink * sink, GstBuffer * buffer) { GstMemory *mem; GstFlowReturn ret = GST_FLOW_OK; + GstVideoMeta *vmeta; + gint i; FUNCTION; + g_return_val_if_fail (sink != NULL, GST_FLOW_ERROR); g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR); sink->to_render = NULL; + /* update video info from video meta */ + mem = gst_buffer_peek_memory (buffer, 0); + + vmeta = gst_buffer_get_video_meta (buffer); + if (vmeta) { + GST_DEBUG ("get video meta"); + for (i = 0; i < vmeta->n_planes; i++) { + sink->video_info.offset[i] = vmeta->offset[i]; + sink->video_info.stride[i] = vmeta->stride[i]; + } + sink->video_info.size = mem->size; + } + if (gst_tizen_wl_sink_has_wlbuffer (sink, buffer)) { ret = gst_tizen_wl_sink_no_create_wlbuffer (sink, buffer); } else { @@ -2314,17 +2303,18 @@ gst_tizen_wl_sink_get_window (GstTizenWlSink * sink) if (!sink->window) { /* if we were not provided a window, create one ourselves */ sink->window = - gst_wl_window_new_toplevel (sink->display, &sink->video_info); + gst_wl_window_new_toplevel (sink->display, &sink->video_info, + &sink->render_lock); } gst_tizen_wl_sink_update_window_geometry (sink); } static GstFlowReturn -gst_tizen_wl_sink_render (GstBaseSink * bsink, GstBuffer * buffer) +gst_tizen_wl_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) { #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT - GstTizenWlSink *sink = GST_TIZEN_WL_SINK (bsink); + GstTizenWlSink *sink = GST_TIZEN_WL_SINK (vsink); GstFlowReturn ret = GST_FLOW_OK; FUNCTION; @@ -2348,13 +2338,12 @@ gst_tizen_wl_sink_render (GstBaseSink * bsink, GstBuffer * buffer) if (sink->signal_handoffs) { GST_LOG ("g_signal_emit: hand-off "); g_signal_emit (sink, gst_waylandsink_signals[SIGNAL_HANDOFF], 0, buffer, - bsink->sinkpad); + GST_VIDEO_SINK_PAD (sink)); goto done; } /* drop buffers until we get a frame callback */ - if (g_atomic_int_get (&sink->redraw_pending) == TRUE - && !gst_tizen_wl_sink_is_gapless (sink)) + if (sink->redraw_pending && !gst_tizen_wl_sink_is_gapless (sink)) goto done; /* create wl_buffer */ @@ -2567,7 +2556,9 @@ gst_tizen_wl_sink_set_wl_window_wl_surface_id (GstVideoOverlay * overlay, /* we can use our own display with an external window handle */ if (G_LIKELY (sink->display->own_display)) { sink->display->wl_surface_id = (int) wl_surface_id; - sink->window = gst_wl_window_new_in_surface (sink->display, NULL); + sink->window = + gst_wl_window_new_in_surface (sink->display, NULL, + &sink->render_lock); } } else { GST_ERROR_OBJECT (sink, "Failed to find display handle, " @@ -2610,9 +2601,13 @@ gst_tizen_wl_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle) ("Now waylandsink use internal display handle " "which is created ourselves. Consider providing a " "display handle from your application with GstContext")); - sink->window = gst_wl_window_new_in_surface (sink->display, surface); + sink->window = + gst_wl_window_new_in_surface (sink->display, surface, + &sink->render_lock); } else { - sink->window = gst_wl_window_new_in_surface (sink->display, surface); + sink->window = + gst_wl_window_new_in_surface (sink->display, surface, + &sink->render_lock); } } else { GST_ERROR_OBJECT (sink, "Failed to find display handle, " diff --git a/tizenwlsink/src/wldisplay.c b/tizenwlsink/src/wldisplay.c index cb5b7b3..838f529 100644 --- a/tizenwlsink/src/wldisplay.c +++ b/tizenwlsink/src/wldisplay.c @@ -72,7 +72,7 @@ static void gst_wl_display_init (GstWlDisplay * self) { FUNCTION; - self->formats = g_array_new (FALSE, FALSE, sizeof (uint32_t)); + self->shm_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t)); #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT self->tbm_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t)); #endif @@ -93,7 +93,8 @@ gst_wl_display_finalize (GObject * gobject) FUNCTION; gst_poll_set_flushing (self->wl_fd_poll, TRUE); - g_thread_join (self->thread); + if (self->thread) + g_thread_join (self->thread); /* to avoid buffers being unregistered from another thread * at the same time, take their ownership */ @@ -106,7 +107,7 @@ gst_wl_display_finalize (GObject * gobject) (GHFunc) gst_wl_buffer_force_release_and_unref, NULL); g_hash_table_remove_all (self->buffers); - g_array_unref (self->formats); + g_array_unref (self->shm_formats); #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT g_array_unref (self->tbm_formats); #endif @@ -218,13 +219,53 @@ shm_format (void *data, struct wl_shm *wl_shm, uint32_t format) { GstWlDisplay *self = data; - g_array_append_val (self->formats, format); + g_array_append_val (self->shm_formats, format); } static const struct wl_shm_listener shm_listener = { shm_format }; +gboolean +gst_wl_display_check_format_for_shm (GstWlDisplay * display, + GstVideoFormat format) +{ + enum wl_shm_format shm_fmt; + GArray *formats; + guint i; + + shm_fmt = gst_video_format_to_wl_shm_format (format); + if (shm_fmt == (enum wl_shm_format) -1) + return FALSE; + + formats = display->shm_formats; + for (i = 0; i < formats->len; i++) { + if (g_array_index (formats, uint32_t, i) == shm_fmt) + return TRUE; + } + + return FALSE; +} + +gboolean +gst_wl_display_check_format_for_tbm (GstWlDisplay * display, + GstVideoFormat format) +{ + uint32_t tbm_format; + GArray *formats; + guint i; + + tbm_format = gst_video_format_to_wl_tbm_format (format); + + formats = display->tbm_formats; + for (i = 0; i < formats->len; i++) { + if (g_array_index (formats, uint32_t, i) == tbm_format) + return TRUE; + } + + return FALSE; +} + static void registry_handle_global (void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) diff --git a/tizenwlsink/src/wldisplay.h b/tizenwlsink/src/wldisplay.h index c3e4481..dd7e7d4 100644 --- a/tizenwlsink/src/wldisplay.h +++ b/tizenwlsink/src/wldisplay.h @@ -30,6 +30,8 @@ #include #include #define USE_WL_FLUSH_BUFFER +#include "tizen-wlvideoformat.h" +#include "wlvideoformat.h" #endif G_BEGIN_DECLS @@ -65,7 +67,7 @@ struct _GstWlDisplay struct wl_shell *shell; struct wl_shm *shm; struct wl_scaler *scaler; - GArray *formats; + GArray *shm_formats; #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT GArray *tbm_formats; #endif @@ -137,5 +139,10 @@ GstWlDisplay *gst_wl_display_new_existing (struct wl_display *display, void gst_wl_display_register_buffer (GstWlDisplay * self, gpointer buf); void gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer buf); +gboolean gst_wl_display_check_format_for_shm (GstWlDisplay * display, + GstVideoFormat format); +gboolean gst_wl_display_check_format_for_tbm (GstWlDisplay * display, + GstVideoFormat format); + G_END_DECLS #endif /* __GST_WL_DISPLAY_H__ */ diff --git a/tizenwlsink/src/wlvideoformat.c b/tizenwlsink/src/wlvideoformat.c index a4f57a7..615d206 100644 --- a/tizenwlsink/src/wlvideoformat.c +++ b/tizenwlsink/src/wlvideoformat.c @@ -33,9 +33,9 @@ typedef struct { enum wl_shm_format wl_format; GstVideoFormat gst_format; -} wl_VideoFormat; +} wl_ShmVideoFormat; -static const wl_VideoFormat formats[] = { +static const wl_ShmVideoFormat shm_formats[] = { #if G_BYTE_ORDER == G_BIG_ENDIAN {WL_SHM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_xRGB}, {WL_SHM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_ARGB}, @@ -82,9 +82,9 @@ gst_video_format_to_wl_shm_format (GstVideoFormat format) guint i; FUNCTION; - for (i = 0; i < G_N_ELEMENTS (formats); i++) - if (formats[i].gst_format == format) - return formats[i].wl_format; + for (i = 0; i < G_N_ELEMENTS (shm_formats); i++) + if (shm_formats[i].gst_format == format) + return shm_formats[i].wl_format; GST_WARNING ("wayland shm video format not found"); return -1; @@ -96,9 +96,9 @@ gst_wl_shm_format_to_video_format (enum wl_shm_format wl_format) guint i; FUNCTION; - for (i = 0; i < G_N_ELEMENTS (formats); i++) - if (formats[i].wl_format == wl_format) - return formats[i].gst_format; + for (i = 0; i < G_N_ELEMENTS (shm_formats); i++) + if (shm_formats[i].wl_format == wl_format) + return shm_formats[i].gst_format; GST_WARNING ("gst video format not found"); return GST_VIDEO_FORMAT_UNKNOWN; diff --git a/tizenwlsink/src/wlwindow.c b/tizenwlsink/src/wlwindow.c index a772bc5..c55473d 100644 --- a/tizenwlsink/src/wlwindow.c +++ b/tizenwlsink/src/wlwindow.c @@ -86,9 +86,9 @@ gst_wl_window_finalize (GObject * gobject) GstWlWindow *self = GST_WL_WINDOW (gobject); FUNCTION; - if (self->shell_surface) { + if (self->shell_surface) wl_shell_surface_destroy (self->shell_surface); - } + #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT if (self->video_object) tizen_video_object_destroy (self->video_object); @@ -173,7 +173,8 @@ gst_wl_window_map_sub_surface (GstWlDisplay * display, GstWlWindow * window, static GstWlWindow * #if 1 /* for enlightment, we need to get parent to create area_subsurface */ -gst_wl_window_new_internal (GstWlDisplay * display, struct wl_surface *parent) +gst_wl_window_new_internal (GstWlDisplay * display, struct wl_surface *parent, + GMutex * render_lock) #else gst_wl_window_new_internal (GstWlDisplay * display) #endif @@ -191,6 +192,7 @@ gst_wl_window_new_internal (GstWlDisplay * display) window = g_object_new (GST_TYPE_WL_WINDOW, NULL); window->display = g_object_ref (display); + window->render_lock = render_lock; window->area_surface = wl_compositor_create_surface (display->compositor); GST_WARNING @@ -389,7 +391,8 @@ gst_wl_window_new_internal (GstWlDisplay * display) } GstWlWindow * -gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info) +gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, + GMutex * render_lock) { #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT GstWlWindow *window; @@ -397,7 +400,7 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info) /* not create shell_surface here for enlightenment */ display->need_shell_surface = TRUE; - window = gst_wl_window_new_internal (display, NULL); + window = gst_wl_window_new_internal (display, NULL, render_lock); /* for tizen enlightenment */ #if 0 @@ -463,7 +466,7 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info) GstWlWindow * gst_wl_window_new_in_surface (GstWlDisplay * display, - struct wl_surface * parent) + struct wl_surface * parent, GMutex * render_lock) { #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT /* use App window */ @@ -473,10 +476,10 @@ gst_wl_window_new_in_surface (GstWlDisplay * display, display->use_parent_wl_surface = TRUE; if (parent) { /*use wl_surface */ - window = gst_wl_window_new_internal (display, parent); + window = gst_wl_window_new_internal (display, parent, render_lock); } else { /* use wl_surface id */ - window = gst_wl_window_new_internal (display, NULL); + window = gst_wl_window_new_internal (display, NULL, render_lock); } /*Area surface from App need to be under parent surface */ diff --git a/tizenwlsink/src/wlwindow.h b/tizenwlsink/src/wlwindow.h index 6f5397d..10c2dac 100644 --- a/tizenwlsink/src/wlwindow.h +++ b/tizenwlsink/src/wlwindow.h @@ -80,6 +80,7 @@ struct _GstWlWindow { GObject parent_instance; + GMutex *render_lock; GstWlDisplay *display; struct wl_surface *area_surface; struct wl_subsurface *area_subsurface; @@ -116,6 +117,13 @@ struct _GstWlWindow /* the size and position of the area_(sub)surface */ GstVideoRectangle render_rectangle; +#ifndef TIZEN_FEATURE_WLSINK_ENHANCEMENT /* no use for tizen view porot */ + /* the size and position of the video_subsurface */ + GstVideoRectangle video_rectangle; + /* this will be set when viewporter is available and black background has + * already been set on the area_subsurface */ + gboolean no_border_update; +#endif /* the size of the video in the buffers */ gint video_width, video_height; /* the size of the video_(sub)surface */ @@ -130,9 +138,9 @@ struct _GstWlWindowClass GType gst_wl_window_get_type (void); GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display, - const GstVideoInfo * info); + const GstVideoInfo * info, GMutex * render_lock); GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display, - struct wl_surface *parent); + struct wl_surface *parent, GMutex * render_lock); GstWlDisplay *gst_wl_window_get_display (GstWlWindow * window); struct wl_surface *gst_wl_window_get_wl_surface (GstWlWindow * window); -- 2.7.4 From 5d90a1adc384ba0b5ebffc148edf3105eba45731 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Mon, 2 Apr 2018 16:30:24 +0900 Subject: [PATCH 08/16] tizenwlsink: Change ROI mode behavior for player and camera ROI precondition Change-Id: Ic68169a0b19035b87b779ec0a40e2471f4bd7a42 Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 7 ++++++- tizenwlsink/src/wlwindow.c | 16 +++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index b334296..ab77c92 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -2627,6 +2627,7 @@ gst_tizen_wl_sink_set_render_rectangle (GstVideoOverlay * overlay, g_return_if_fail (sink != NULL); g_mutex_lock (&sink->render_lock); + if (!sink->window) { g_mutex_unlock (&sink->render_lock); GST_WARNING_OBJECT (sink, @@ -2636,11 +2637,15 @@ gst_tizen_wl_sink_set_render_rectangle (GstVideoOverlay * overlay, GST_WARNING_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d", x, y, w, h); + if (gst_wl_window_set_render_rectangle (sink->window, x, y, w, h)) { sink->video_info_changed = TRUE; - if (sink->window && GST_STATE (sink) == GST_STATE_PAUSED) + + if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI + && sink->window && GST_STATE (sink) == GST_STATE_PAUSED) gst_tizen_wl_sink_update_last_buffer_geometry (sink); } + g_mutex_unlock (&sink->render_lock); } diff --git a/tizenwlsink/src/wlwindow.c b/tizenwlsink/src/wlwindow.c index c55473d..ab115fd 100644 --- a/tizenwlsink/src/wlwindow.c +++ b/tizenwlsink/src/wlwindow.c @@ -620,7 +620,9 @@ gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window, } /*set tizen destination mode */ - if (window->disp_geo_method.changed || window->roi_area_changed) { + if (window->disp_geo_method.changed + || (window->disp_geo_method.value == DISP_GEO_METHOD_CUSTOM_ROI + && window->roi_area_changed)) { int tizen_disp_mode = -1; switch (window->disp_geo_method.value) { @@ -664,6 +666,12 @@ gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window, ("tizen_viewport_set_destination (tizen_video_viewport(tizen_viewport)@%p, x@%d, y@%d, w@%d, h@%d)", window->tizen_video_viewport, window->roi.x, window->roi.y, window->roi.w, window->roi.h); + if (window->roi.x == 0 && window->roi.y == 0 && window->roi.w == 0 + && window->roi.h == 0) { + GST_WARNING ("ROI Area isn't set"); + return; + } + tizen_viewport_set_destination (window->tizen_video_viewport, window->roi.x, window->roi.y, window->roi.w, window->roi.h); window->roi_area_changed = FALSE; @@ -940,12 +948,6 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, FUNCTION; g_return_val_if_fail (window != NULL, FALSE); - if (window->disp_geo_method.value != DISP_GEO_METHOD_CUSTOM_ROI) { - GST_ERROR - ("must be set display-geometry-method to DISP_GEO_METHOD_CUSTOM_ROI before setting render rectangle()"); - return FALSE; - } - if (w < 0 || h < 0) { GST_ERROR ("Error : wrong roi size w(%d), h(%d)", w, h); return FALSE; -- 2.7.4 From 83fe4eb456a36bc964710d7781b545d7fe209f75 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Fri, 30 Mar 2018 17:54:45 +0900 Subject: [PATCH 09/16] Add tizencamerasrc plugin, but disabled now. - It's a reference plugin to use tizen camera HAL interface. [Version] 1.0.0-54 [Profile] Common [Issue Type] Add [Dependency module] N/A Change-Id: Ia572295a8819b136de7a30af4c54b3148e0aae1a Signed-off-by: Jeongmo Yang --- Makefile.am | 4 + configure.ac | 20 + packaging/gst-plugins-tizen.spec | 8 +- tizencamerasrc/Makefile.am | 1 + tizencamerasrc/src/Makefile.am | 32 + tizencamerasrc/src/camera_hal_interface.c | 570 ++++++ tizencamerasrc/src/gsttizencamerasrc.c | 2049 ++++++++++++++++++++ tizencamerasrc/src/gsttizencamerasrccolorbalance.c | 92 + tizencamerasrc/src/gsttizencamerasrccontrol.c | 727 +++++++ tizencamerasrc/src/include/camera_hal_interface.h | 54 + tizencamerasrc/src/include/gsttizencamerasrc.h | 126 ++ .../src/include/gsttizencamerasrccolorbalance.h | 91 + .../src/include/gsttizencamerasrccontrol.h | 364 ++++ 13 files changed, 4136 insertions(+), 2 deletions(-) create mode 100644 tizencamerasrc/Makefile.am create mode 100644 tizencamerasrc/src/Makefile.am create mode 100644 tizencamerasrc/src/camera_hal_interface.c create mode 100644 tizencamerasrc/src/gsttizencamerasrc.c create mode 100644 tizencamerasrc/src/gsttizencamerasrccolorbalance.c create mode 100644 tizencamerasrc/src/gsttizencamerasrccontrol.c create mode 100644 tizencamerasrc/src/include/camera_hal_interface.h create mode 100644 tizencamerasrc/src/include/gsttizencamerasrc.h create mode 100644 tizencamerasrc/src/include/gsttizencamerasrccolorbalance.h create mode 100644 tizencamerasrc/src/include/gsttizencamerasrccontrol.h diff --git a/Makefile.am b/Makefile.am index 7dfb351..44500b4 100755 --- a/Makefile.am +++ b/Makefile.am @@ -65,6 +65,10 @@ if GST_TIZEN_USE_WAYLANDSINK SUBDIRS += tizenwlsink endif +if GST_TIZEN_USE_TIZENCAMERASRC +SUBDIRS += tizencamerasrc +endif + DIST_SUBDIRS = common if GST_TIZEN_USE_ENCODEBIN diff --git a/configure.ac b/configure.ac index a738fab..17703ba 100644 --- a/configure.ac +++ b/configure.ac @@ -169,6 +169,7 @@ AC_SUBST(TBM_LIBS) PKG_CHECK_MODULES(MMCOMMON,mm-common) AC_SUBST(MMCOMMON_CFLAGS) +AC_SUBST(MMCOMMON_LIBS) dnl belows are related to wfdtsdemux AG_GST_ARG_WITH_PACKAGE_NAME @@ -438,6 +439,23 @@ AC_SUBST(WAYLAND_CFLAGS) AC_SUBST(WAYLAND_LIBS) fi +dnl use tizencamerasrc -------------------------------------------------------------------------- +AC_ARG_ENABLE(tizencamerasrc, AC_HELP_STRING([--enable-tizencamerasrc], [using tizencamerasrc]), +[ + case "${enableval}" in + yes) GST_TIZEN_USE_TIZENCAMERASRC=yes ;; + no) GST_TIZEN_USE_TIZENCAMERASRC=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-tizencamerasrc) ;; + esac + ], + [GST_TIZEN_USE_TIZENCAMERASRC=yes]) +AM_CONDITIONAL([GST_TIZEN_USE_TIZENCAMERASRC], [test "x$GST_TIZEN_USE_TIZENCAMERASRC" = "xyes"]) +if test "x$GST_TIZEN_USE_TIZENCAMERASRC" = "xyes"; then +PKG_CHECK_MODULES(DLOG, dlog) +AC_SUBST(DLOG_CFLAGS) +AC_SUBST(DLOG_LIBS) +fi + AC_OUTPUT( Makefile common/Makefile @@ -469,4 +487,6 @@ video360/Makefile video360/src/Makefile tizenwlsink/Makefile tizenwlsink/src/Makefile +tizencamerasrc/Makefile +tizencamerasrc/src/Makefile ) diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 4439c5d..69474d2 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,13 +9,12 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 53 +Release: 54 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ Source0: %{name}-%{version}.tar.gz -#BuildRequires: pkgconfig(camsrcjpegenc) BuildRequires: pkgconfig(gstreamer-audio-1.0) BuildRequires: pkgconfig(gstreamer-video-1.0) BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) @@ -44,6 +43,9 @@ BuildRequires: pkgconfig(wayland-client) >= 1.0.0 BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(tizen-extension-client) %endif +# for tizencamerasrc +#BuildRequires: pkgconfig(dlog) +#BuildRequires: mm-hal-interface %description GStreamer tizen plugins (common) @@ -83,6 +85,7 @@ export CFLAGS="$CFLAGS_DEFAULT -DTIZEN_FEATURE_PRODUCT_TM1" --enable-ext-wfdtizenmanager\ --enable-ext-alfec\ --disable-tizenipc\ + --disable-tizencamerasrc\ --disable-static\ --with-tizen-platform \ --with-native-formats \ @@ -107,6 +110,7 @@ export CFLAGS="$CFLAGS_DEFAULT" --enable-ext-wfdtizenmanager\ --enable-ext-alfec\ --disable-tizenipc\ + --disable-tizencamerasrc\ --disable-static\ --with-tizen-platform \ --with-native-formats \ diff --git a/tizencamerasrc/Makefile.am b/tizencamerasrc/Makefile.am new file mode 100644 index 0000000..af437a6 --- /dev/null +++ b/tizencamerasrc/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src diff --git a/tizencamerasrc/src/Makefile.am b/tizencamerasrc/src/Makefile.am new file mode 100644 index 0000000..4396a7d --- /dev/null +++ b/tizencamerasrc/src/Makefile.am @@ -0,0 +1,32 @@ +# plugindir is set in configure + +plugin_LTLIBRARIES = libgsttizencamerasrc.la + +# sources used to compile this plug-in +libgsttizencamerasrc_la_SOURCES = gsttizencamerasrc.c \ + gsttizencamerasrccontrol.c \ + gsttizencamerasrccolorbalance.c \ + camera_hal_interface.c + +libgsttizencamerasrc_la_CFLAGS = -I$(srcdir)/include \ + $(GST_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_FLAGS) \ + $(MMCOMMON_CFLAGS) \ + $(MMUTIL_JPEG_CFLAGS) \ + $(DLOG_CFLAGS) \ + $(TBM_CFLAGS) + +libgsttizencamerasrc_la_LIBADD = -ldl -lpthread -lrt -lm \ + $(GST_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_VIDEO_LIBS) \ + $(MMCOMMON_LIBS) \ + $(MMUTIL_JPEG_LIBS) \ + $(DLOG_LIBS) \ + $(TBM_LIBS) + +libgsttizencamerasrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + +libgsttizencamerasrc_la_CPPFLAGS = -I$(srcdir)/include + diff --git a/tizencamerasrc/src/camera_hal_interface.c b/tizencamerasrc/src/camera_hal_interface.c new file mode 100644 index 0000000..65f13de --- /dev/null +++ b/tizencamerasrc/src/camera_hal_interface.c @@ -0,0 +1,570 @@ +/* + * camera_hal_interface.c + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include "camera_hal_interface.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif /* LOG_TAG */ +#define LOG_TAG "CAMERA_HAL_INTF" + +#define LIB_TIZEN_CAMERA "libtizen-camera.so" + +struct _camera_hal_interface { + void *dl_handle; + void *hal_handle; + camera_interface_t intf; +}; + +int camera_hal_interface_init(camera_hal_interface **h) +{ + int ret = CAMERA_ERROR_NONE; + camera_hal_interface *tmp_h = NULL; + + if (h == NULL) { + LOGE("invalid parameter for camera_hal_interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + tmp_h = g_new0(camera_hal_interface, 1); + if (tmp_h == NULL) { + LOGE("failed to allocate hal interface"); + return CAMERA_ERROR_OUT_OF_MEMORY; + } + + tmp_h->dl_handle = dlopen(LIB_TIZEN_CAMERA, RTLD_NOW); + if (tmp_h->dl_handle) { + tmp_h->intf.init = dlsym(tmp_h->dl_handle, "camera_init"); + tmp_h->intf.deinit = dlsym(tmp_h->dl_handle, "camera_deinit"); + tmp_h->intf.get_device_list = dlsym(tmp_h->dl_handle, "camera_get_device_list"); + tmp_h->intf.open_device = dlsym(tmp_h->dl_handle, "camera_open_device"); + tmp_h->intf.close_device = dlsym(tmp_h->dl_handle, "camera_close_device"); + tmp_h->intf.add_message_callback = dlsym(tmp_h->dl_handle, "camera_add_message_callback"); + tmp_h->intf.remove_message_callback = dlsym(tmp_h->dl_handle, "camera_remove_message_callback"); + tmp_h->intf.set_preview_stream_format = dlsym(tmp_h->dl_handle, "camera_set_preview_stream_format"); + tmp_h->intf.get_preview_stream_format = dlsym(tmp_h->dl_handle, "camera_get_preview_stream_format"); + tmp_h->intf.start_preview = dlsym(tmp_h->dl_handle, "camera_start_preview"); + tmp_h->intf.release_preview_buffer = dlsym(tmp_h->dl_handle, "camera_release_preview_buffer"); + tmp_h->intf.stop_preview = dlsym(tmp_h->dl_handle, "camera_stop_preview"); + tmp_h->intf.start_auto_focus = dlsym(tmp_h->dl_handle, "camera_start_auto_focus"); + tmp_h->intf.stop_auto_focus = dlsym(tmp_h->dl_handle, "camera_stop_auto_focus"); + tmp_h->intf.start_capture = dlsym(tmp_h->dl_handle, "camera_start_capture"); + tmp_h->intf.stop_capture = dlsym(tmp_h->dl_handle, "camera_stop_capture"); + tmp_h->intf.set_video_stream_format = dlsym(tmp_h->dl_handle, "camera_set_video_stream_format"); + tmp_h->intf.get_video_stream_format = dlsym(tmp_h->dl_handle, "camera_get_video_stream_format"); + tmp_h->intf.start_record = dlsym(tmp_h->dl_handle, "camera_start_record"); + tmp_h->intf.release_video_buffer = dlsym(tmp_h->dl_handle, "camera_release_video_buffer"); + tmp_h->intf.stop_record = dlsym(tmp_h->dl_handle, "camera_stop_record"); + tmp_h->intf.set_command = dlsym(tmp_h->dl_handle, "camera_set_command"); + tmp_h->intf.get_command = dlsym(tmp_h->dl_handle, "camera_get_command"); + tmp_h->intf.set_batch_command = dlsym(tmp_h->dl_handle, "camera_set_batch_command"); + + if (tmp_h->intf.init == NULL || tmp_h->intf.deinit == NULL) { + LOGE("could not get mandatory function. %p %1p", tmp_h->intf.init, tmp_h->intf.deinit); + ret = CAMERA_ERROR_INTERNAL; + goto _CAMERA_HAL_INTERFACE_GET_FAILED; + } + + if (tmp_h->intf.init) { + ret = tmp_h->intf.init(&tmp_h->hal_handle); + if (ret != CAMERA_ERROR_NONE) { + LOGE("camera_init failed 0x%x", ret); + goto _CAMERA_HAL_INTERFACE_GET_FAILED; + } + } else { + LOGE("no camera_init function"); + ret = CAMERA_ERROR_INTERNAL; + goto _CAMERA_HAL_INTERFACE_GET_FAILED; + } + } else { + LOGE("dlopen failed [%s]", LIB_TIZEN_CAMERA); + ret = CAMERA_ERROR_INTERNAL; + goto _CAMERA_HAL_INTERFACE_GET_FAILED; + } + + *h = tmp_h; + + return ret; + +_CAMERA_HAL_INTERFACE_GET_FAILED: + if (tmp_h) { + if (tmp_h->dl_handle) + dlclose(tmp_h->dl_handle); + + g_free(tmp_h); + } + + return ret; +} + +int camera_hal_interface_deinit(camera_hal_interface *h) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->dl_handle) { + ret = h->intf.deinit(h->hal_handle); + if (ret != CAMERA_ERROR_NONE) { + LOGE("camera_deinit failed 0x%x", ret); + return ret; + } + + h->hal_handle = NULL; + + dlclose(h->dl_handle); + h->dl_handle = NULL; + } + + g_free(h); + + return CAMERA_ERROR_NONE; +} + +int camera_hal_interface_get_device_list(camera_hal_interface *h, camera_device_list_t *device_list) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.get_device_list) { + ret = h->intf.get_device_list(h->hal_handle, device_list); + } else { + LOGE("camera_get_device_list not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_open_device(camera_hal_interface *h, int device_index) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.open_device) { + ret = h->intf.open_device(h->hal_handle, device_index); + } else { + LOGE("camera_open_device not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_close_device(camera_hal_interface *h) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.close_device) { + ret = h->intf.close_device(h->hal_handle); + } else { + LOGE("camera_close_device not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_add_message_callback(camera_hal_interface *h, camera_message_cb callback, void *user_data, uint32_t *cb_id) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.add_message_callback) { + ret = h->intf.add_message_callback(h->hal_handle, callback, user_data, cb_id); + } else { + LOGE("camera_add_message_callback not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_remove_message_callback(camera_hal_interface *h, uint32_t cb_id) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.remove_message_callback) { + ret = h->intf.remove_message_callback(h->hal_handle, cb_id); + } else { + LOGE("camera_remove_message_callback not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_set_preview_stream_format(camera_hal_interface *h, camera_format_t *format) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.set_preview_stream_format) { + ret = h->intf.set_preview_stream_format(h->hal_handle, format); + } else { + LOGE("camera_set_preview_stream_format not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_get_preview_stream_format(camera_hal_interface *h, camera_format_t *format) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.get_preview_stream_format) { + ret = h->intf.get_preview_stream_format(h->hal_handle, format); + } else { + LOGE("camera_get_preview_stream_format not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_start_preview(camera_hal_interface *h, camera_preview_frame_cb callback, void *user_data) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.start_preview) { + ret = h->intf.start_preview(h->hal_handle, callback, user_data); + } else { + LOGE("camera_start_preview not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_release_preview_buffer(camera_hal_interface *h, int buffer_index) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.release_preview_buffer) { + ret = h->intf.release_preview_buffer(h->hal_handle, buffer_index); + } else { + LOGE("camera_release_preview_buffer not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_stop_preview(camera_hal_interface *h) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.stop_preview) { + ret = h->intf.stop_preview(h->hal_handle); + } else { + LOGE("camera_stop_preview not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_start_auto_focus(camera_hal_interface *h) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.start_auto_focus) { + ret = h->intf.start_auto_focus(h->hal_handle); + } else { + LOGE("camera_start_auto_focus not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_stop_auto_focus(camera_hal_interface *h) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.stop_auto_focus) { + ret = h->intf.stop_auto_focus(h->hal_handle); + } else { + LOGE("camera_stop_auto_focus not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_start_capture(camera_hal_interface *h, camera_capture_cb callback, void *user_data) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.start_capture) { + ret = h->intf.start_capture(h->hal_handle, callback, user_data); + } else { + LOGE("camera_start_capture not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_stop_capture(camera_hal_interface *h) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.stop_capture) { + ret = h->intf.stop_capture(h->hal_handle); + } else { + LOGE("camera_stop_capture not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_set_video_stream_format(camera_hal_interface *h, camera_format_t *format) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.set_video_stream_format) { + ret = h->intf.set_video_stream_format(h->hal_handle, format); + } else { + LOGE("camera_set_video_stream_format not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_get_video_stream_format(camera_hal_interface *h, camera_format_t *format) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.get_video_stream_format) { + ret = h->intf.get_video_stream_format(h->hal_handle, format); + } else { + LOGE("camera_get_video_stream_format not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_start_record(camera_hal_interface *h, camera_video_frame_cb callback, void *user_data) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.start_record) { + ret = h->intf.start_record(h->hal_handle, callback, user_data); + } else { + LOGE("camera_start_record not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_release_video_buffer(camera_hal_interface *h, int buffer_index) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.release_video_buffer) { + ret = h->intf.release_video_buffer(h->hal_handle, buffer_index); + } else { + LOGE("camera_release_video_buffer not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_stop_record(camera_hal_interface *h) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.stop_record) { + ret = h->intf.stop_record(h->hal_handle); + } else { + LOGE("camera_stop_record not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_set_command(camera_hal_interface *h, int64_t command, void *value) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.set_command) { + ret = h->intf.set_command(h->hal_handle, command, value); + } else { + LOGE("camera_set_command not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_get_command(camera_hal_interface *h, int64_t command, void *value) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.get_command) { + ret = h->intf.get_command(h->hal_handle, command, value); + } else { + LOGE("camera_get_command not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} + +int camera_hal_interface_set_batch_command(camera_hal_interface *h, camera_batch_command_control_t *batch_command, int64_t *error_command) +{ + int ret = CAMERA_ERROR_NONE; + + if (h == NULL) { + LOGE("NULL interface"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + if (h->intf.set_batch_command) { + ret = h->intf.set_batch_command(h->hal_handle, batch_command, error_command); + } else { + LOGE("camera_set_batch_command not implemented"); + ret = CAMERA_ERROR_NOT_IMPLEMENTED; + } + + return ret; +} diff --git a/tizencamerasrc/src/gsttizencamerasrc.c b/tizencamerasrc/src/gsttizencamerasrc.c new file mode 100644 index 0000000..bb4bf78 --- /dev/null +++ b/tizencamerasrc/src/gsttizencamerasrc.c @@ -0,0 +1,2049 @@ +/* + * gsttizencamerasrc.c + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gsttizencamerasrc.h" +#include "gsttizencamerasrccontrol.h" +#include "gsttizencamerasrccolorbalance.h" + + +/****************************************************************************** + * Definitions + *******************************************************************************/ +GST_DEBUG_CATEGORY (camerasrc_debug); +#define GST_CAT_DEFAULT camerasrc_debug + + +#define CAMERASRC_ALIGN(addr,size) (((addr)+((size)-1))&(~((size)-1))) + +#if !defined (CLEAR) + #define CLEAR(x) memset(&(x), 0, sizeof(x)) +#endif + +/* Enables */ +#define _ENABLE_CAMERASRC_DEBUG 0 + +/* Local definitions */ +#define _DEFAULT_FPS 15 +#define _DEFAULT_HIGH_SPEED_FPS 0 +#define _DEFAULT_FPS_AUTO FALSE +#define _DEFAULT_PIX_FORMAT CAMERA_PIXEL_FORMAT_NV12 +#define _DEFAULT_PIX_FORMAT_NAME "NV12" +#define _DEFAULT_CAPTURE_FORMAT_NAME "JPEG" +#define _DEFAULT_CAMERA_ID 0 + +#define _CAMERA_ID_MIN 0 +#define _CAMERA_ID_MAX 1 + +#define _DEFAULT_CAP_JPG_QUALITY 95 +#define _DEFAULT_CAP_WIDTH 640 +#define _DEFAULT_CAP_HEIGHT 480 +#define _DEFAULT_CAP_COUNT 1 +#define _DEFAULT_CAP_INTERVAL 0 +#define _DEFAULT_CAP_PROVIDE_EXIF FALSE +#define _PREVIEW_BUFFER_WAIT_TIMEOUT 5000000 /* usec */ + +enum { + CAMERA_COLOR_BALANCE_BRIGHTNESS = 0, + CAMERA_COLOR_BALANCE_CONTRAST, + CAMERA_COLOR_BALANCE_WHITE_BALANCE, + CAMERA_COLOR_BALANCE_COLOR_TONE, + CAMERA_COLOR_BALANCE_SATURATION, + CAMERA_COLOR_BALANCE_HUE, + CAMERA_COLOR_BALANCE_SHARPNESS, + CAMERA_COLOR_BALANCE_NUM +}; + +#define SAFE_FREE_GQUEUE(gqueue) \ + if (gqueue) { \ + g_queue_free(gqueue); \ + gqueue = NULL; \ + } + +#define MAKE_FOURCC_FROM_STRING(string) ((guint32)(string[0] | (string[1] << 8) | (string[2] << 16) | (string[3] << 24))) + + +/* Enumerations */ +enum { + /*signal*/ + SIGNAL_STILL_CAPTURE, + + /*SIGNAL_REGISTER_TROUBLE,*/ + LAST_SIGNAL +}; + +enum { + ARG_0, + /* camera */ + ARG_CAMERA_HIGH_SPEED_FPS, + ARG_CAMERA_AUTO_FPS, + ARG_CAMERA_ID, + + /* capture */ + ARG_CAMERA_CAPTURE_FOURCC, + ARG_CAMERA_CAPTURE_WIDTH, + ARG_CAMERA_CAPTURE_HEIGHT, + ARG_CAMERA_CAPTURE_INTERVAL, + ARG_CAMERA_CAPTURE_COUNT, + ARG_CAMERA_CAPTURE_JPG_QUALITY, + ARG_CAMERA_CAPTURE_PROVIDE_EXIF, + + /* etc */ + ARG_VFLIP, + ARG_HFLIP, + ARG_NUM, +}; + +enum { + VIDEO_IN_MODE_NONE, + VIDEO_IN_MODE_PREVIEW, + VIDEO_IN_MODE_VIDEO, + VIDEO_IN_MODE_CAPTURE, +}; + + +static void gst_tizencamerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data); + +static guint gst_tizencamerasrc_signals[LAST_SIGNAL] = { 0 }; + +/* Element template variables */ +static GstStaticPadTemplate src_factory = + GST_STATIC_PAD_TEMPLATE("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS("video/x-raw," + "format = (string) { NV12 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; ")); + +/* Local static functions */ +static void gst_tizencamerasrc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gst_tizencamerasrc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static gboolean gst_tizencamerasrc_negotiate(GstBaseSrc *basesrc); +static gboolean gst_tizencamerasrc_src_start(GstBaseSrc *src); +static gboolean gst_tizencamerasrc_src_stop(GstBaseSrc *src); +static gboolean gst_tizencamerasrc_start(GstTizenCameraSrc *camerasrc); +static GstFlowReturn gst_tizencamerasrc_src_create(GstPushSrc *src, GstBuffer **buffer); +static GstFlowReturn gst_tizencamerasrc_read_preview(GstTizenCameraSrc *camerasrc, GstBuffer **buffer); +static GstStateChangeReturn gst_tizencamerasrc_change_state(GstElement *element, GstStateChange transition); +static GstCaps *gst_tizencamerasrc_get_caps(GstBaseSrc *src, GstCaps *filter); +static gboolean gst_tizencamerasrc_set_caps(GstBaseSrc *src, GstCaps *caps); +static gboolean gst_tizencamerasrc_get_caps_info(GstTizenCameraSrc *camerasrc, GstCaps *caps, guint *size); +static gboolean gst_tizencamerasrc_fill_ctrl_list(GstTizenCameraSrc *camerasrc); +static gboolean gst_tizencamerasrc_empty_ctrl_list(GstTizenCameraSrc *camerasrc); +static void gst_tizencamerasrc_finalize(GObject *object); +static gboolean gst_tizencamerasrc_get_timeinfo(GstTizenCameraSrc *camerasrc, GstBuffer *buffer); +static gboolean gst_tizencamerasrc_capture_start(GstTizenCameraSrc *camerasrc); +static gboolean gst_tizencamerasrc_capture_stop(GstTizenCameraSrc *camerasrc); +static void gst_tizencamerasrc_error_handler(GstTizenCameraSrc *camerasrc, int ret); + +/* Util functions */ +#if 0 +static unsigned long _get_current_time(void); +#endif +static gboolean _gst_tizencamerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize); +static gboolean _gst_tizencamerasrc_get_raw_pixel_info(int fourcc, int *pix_format); +static void _gst_tizencamerasrc_post_message_int(GstTizenCameraSrc *camerasrc, const char *msg_name, const char *field_name, int value); + +#if _ENABLE_CAMERASRC_DEBUG +static int __util_write_file(char *filename, void *data, int size); +#endif /* _ENABLE_CAMERASRC_DEBUG */ + +GST_IMPLEMENT_TIZENCAMERASRC_COLOR_BALANCE_METHODS(GstTizenCameraSrc, gst_tizencamera_src); +GST_IMPLEMENT_TIZENCAMERASRC_CONTROL_METHODS(GstTizenCameraSrc, gst_tizencamera_src); + + +/****************************************************************************** + * Implementations + *******************************************************************************/ +static void gst_tizencamerasrc_error_handler(GstTizenCameraSrc *camerasrc, int ret) +{ + if (!camerasrc) { + GST_ERROR_OBJECT(camerasrc, "NULL camerasrc"); + return; + } + + switch (ret) { + case CAMERA_ERROR_NONE: + GST_WARNING_OBJECT(camerasrc, "NO ERROR"); + break; + case CAMERA_ERROR_INTERNAL: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("IO control error"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_DEVICE_OPEN: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ_WRITE, ("camera open failed"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_DEVICE_BUSY: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, BUSY, ("camera device busy"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_DEVICE_NOT_FOUND: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, NOT_FOUND, ("camera device not found"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_DEVICE_UNAVAILABLE: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, OPEN_READ, ("camera device unavailable"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_DEVICE_TIME_OUT: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, TOO_LAZY, ("Time Out"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_DEVICE_NOT_SUPPORTED: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("Not supported"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_OUT_OF_MEMORY: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, SETTINGS, ("memory allocation failed"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_PERMISSION_DENIED: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, FAILED, ("Security service failed"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_DEVICE_READ: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, READ, ("camera read failed"), GST_ERROR_SYSTEM); + break; + case CAMERA_ERROR_DEVICE_WRITE: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, WRITE, ("camera write failed"), GST_ERROR_SYSTEM); + break; + default: + GST_ELEMENT_ERROR(camerasrc, RESOURCE, SEEK, (("General video device error[ret=%x]"), ret), GST_ERROR_SYSTEM); + break; + } + + return; +} + + +/* VOID:OBJECT,OBJECT,OBJECT (generated by 'glib-genmarshal') */ +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +static void +g_cclosure_user_marshal_VOID__OBJECT_OBJECT_OBJECT(GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT_OBJECT)(gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer data2); + + register GMarshalFunc_VOID__OBJECT_OBJECT_OBJECT callback; + register GCClosure *cc = (GCClosure *)closure; + register gpointer data1; + register gpointer data2; + + g_return_if_fail(n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA(closure)) { + data1 = closure->data; + data2 = g_value_peek_pointer(param_values + 0); + } else { + data1 = g_value_peek_pointer(param_values + 0); + data2 = closure->data; + } + + callback = (GMarshalFunc_VOID__OBJECT_OBJECT_OBJECT)(marshal_data ? marshal_data : cc->callback); + + callback(data1, + g_marshal_value_peek_object (param_values + 1), + g_marshal_value_peek_object (param_values + 2), + g_marshal_value_peek_object (param_values + 3), + data2); + + return; +} + +/* use following BOILERPLATE MACRO as _get_type entry */ +G_DEFINE_TYPE_WITH_CODE(GstTizenCameraSrc, gst_tizencamerasrc, GST_TYPE_PUSH_SRC, + G_IMPLEMENT_INTERFACE(GST_TYPE_URI_HANDLER, gst_tizencamerasrc_uri_handler_init) + G_IMPLEMENT_INTERFACE(GST_TYPE_CAMERA_CONTROL, gst_tizencamera_src_control_interface_init) + G_IMPLEMENT_INTERFACE(GST_TYPE_COLOR_BALANCE, gst_tizencamera_src_color_balance_interface_init)); + +static int _camera_hal_message_callback(camera_message_t *message, void *user_data) +{ + GstTizenCameraSrc *camerasrc = NULL; + + if (message == NULL || user_data == NULL) { + GST_ERROR("message callback error %p %p", message, user_data); + return FALSE; + } + + camerasrc = (GstTizenCameraSrc *)user_data; + + switch (message->type) { + case CAMERA_MESSAGE_TYPE_FOCUS_CHANGED: + GST_INFO_OBJECT(camerasrc, "focus state %d", message->focus_state); + _gst_tizencamerasrc_post_message_int(camerasrc, "camerasrc-AF", "focus-state", message->focus_state); + break; + case CAMERA_MESSAGE_TYPE_CAPTURED: + GST_INFO_OBJECT(camerasrc, "CAPTURED"); + break; + case CAMERA_MESSAGE_TYPE_HDR_PROGRESS: + GST_INFO_OBJECT(camerasrc, "HDR progress %d", message->hdr_progress); + break; + case CAMERA_MESSAGE_TYPE_ERROR: + GST_ERROR_OBJECT(camerasrc, "error from camera HAL 0x%x", message->error_code); + break; + default: + GST_ERROR_OBJECT(camerasrc, "unknown type message %d", message->type); + return FALSE; + } + + return TRUE; +} + + +static int _camera_preview_frame_cb(camera_buffer_t *buffer, camera_metadata_t *meta, void *user_data) +{ + int i = 0; + int copied_size = 0; + GstTizenCameraSrc *camerasrc = NULL; + GstBuffer *gst_buffer = NULL; + GstMapInfo map_info; + + if (!buffer || !user_data) { + GST_ERROR("preview callback error %p %p", buffer, user_data); + return FALSE; + } + + camerasrc = (GstTizenCameraSrc *)user_data; + + g_mutex_lock(&camerasrc->buffer_lock); + if (!camerasrc->buffer_running) { + GST_WARNING_OBJECT(camerasrc, "buffer is NOT running"); + g_mutex_unlock(&camerasrc->buffer_lock); + return FALSE; + } + + /* create new buffer */ + gst_buffer = gst_buffer_new_and_alloc(buffer->total_size); + if (!gst_buffer) { + GST_ERROR_OBJECT(camerasrc, "new buffer allocation failed. size %u", buffer->total_size); + g_mutex_unlock(&camerasrc->buffer_lock); + return FALSE; + } + + if (!gst_buffer_map(gst_buffer, &map_info, GST_MAP_WRITE)) { + GST_ERROR_OBJECT(camerasrc, "failed to map gst buffer %p", gst_buffer); + gst_buffer_unref(gst_buffer); + g_mutex_unlock(&camerasrc->buffer_lock); + return FALSE; + } + + /* copy buffer data */ + for (i = 0 ; i < buffer->num_planes ; i++) { + memcpy(map_info.data + copied_size, buffer->planes[i].data, buffer->planes[i].size); + copied_size += buffer->planes[i].size; + } + + gst_buffer_unmap(gst_buffer, &map_info); + + /* add new buffer to preview buffer list */ + g_queue_push_tail(camerasrc->preview_buffer_list, gst_buffer); + + GST_DEBUG_OBJECT(camerasrc, "buffer index %d - gst buffer %p", buffer->index, gst_buffer); + + g_cond_signal(&camerasrc->buffer_cond); + + g_mutex_unlock(&camerasrc->buffer_lock); + + /* release preview buffer from camera HAL */ + camera_hal_interface_release_preview_buffer(camerasrc->hal_intf_handle, buffer->index); + + return TRUE; +} + + +static GstVideoFormat __get_gst_video_format(camera_pixel_format_t pixel_format) +{ + switch (pixel_format) { + case CAMERA_PIXEL_FORMAT_NV12: + return GST_VIDEO_FORMAT_NV12; + case CAMERA_PIXEL_FORMAT_NV21: + return GST_VIDEO_FORMAT_NV21; + case CAMERA_PIXEL_FORMAT_I420: + return GST_VIDEO_FORMAT_I420; + case CAMERA_PIXEL_FORMAT_YV12: + return GST_VIDEO_FORMAT_YV12; + case CAMERA_PIXEL_FORMAT_YUYV: + return GST_VIDEO_FORMAT_YUY2; + case CAMERA_PIXEL_FORMAT_UYVY: + return GST_VIDEO_FORMAT_UYVY; + default: + GST_ERROR("unknown pixel format %d", pixel_format); + return -1; + } +} + +static GstSample *__create_buffer_sample(GstTizenCameraSrc *camerasrc, camera_buffer_t *cam_buffer) +{ + GstBuffer *gst_buffer = NULL; + GstCaps *caps = NULL; + GstSample *sample = NULL; + const gchar *string_fourcc = NULL; + + if (!camerasrc) { + GST_ERROR("NULL handle"); + return NULL; + } + + if (!cam_buffer) { + GST_ERROR_OBJECT(camerasrc, "NULL buffer"); + return NULL; + } + + gst_buffer = gst_buffer_new_wrapped_full(0, + cam_buffer->planes[0].data, + cam_buffer->planes[0].size, + 0, + cam_buffer->planes[0].size, + NULL, NULL); + if (!gst_buffer) { + GST_ERROR_OBJECT(camerasrc, "failed to allocate gst buffer for %p", cam_buffer); + return NULL; + } + + if (cam_buffer->format == CAMERA_PIXEL_FORMAT_ENCODED_JPEG) { + caps = gst_caps_new_simple("image/jpeg", + "width", G_TYPE_INT, cam_buffer->resolution.width, + "height", G_TYPE_INT, cam_buffer->resolution.height, + NULL); + } else { + string_fourcc = gst_video_format_to_string(__get_gst_video_format(cam_buffer->format)); + if (string_fourcc) { + caps = gst_caps_new_simple("image/jpeg", + "format", G_TYPE_STRING, string_fourcc, + "width", G_TYPE_INT, cam_buffer->resolution.width, + "height", G_TYPE_INT, cam_buffer->resolution.height, + NULL); + } else { + GST_ERROR_OBJECT(camerasrc, "failed to get string_fourcc"); + } + } + + if (!caps) { + GST_ERROR_OBJECT(camerasrc, "sample caps creation failed for %p", cam_buffer); + goto _CREATE_BUFFER_SAMPLE_DONE; + } + + sample = gst_sample_new(gst_buffer, caps, NULL, NULL); + if (!sample) { + GST_ERROR_OBJECT(camerasrc, "buffer sample1 creation failed"); + goto _CREATE_BUFFER_SAMPLE_DONE; + } + +_CREATE_BUFFER_SAMPLE_DONE: + if (gst_buffer) + gst_buffer_unref(gst_buffer); + if (caps) + gst_caps_unref(caps); + + GST_INFO_OBJECT(camerasrc, "sample %p - format %d, %dx%d", + sample, cam_buffer->format, cam_buffer->resolution.width, cam_buffer->resolution.height); + + return sample; +} + + +static int _camera_capture_cb(camera_buffer_t *main, camera_buffer_t *postview, camera_buffer_t *thumbnail, void *user_data) +{ + GstTizenCameraSrc *camerasrc = NULL; + GstSample *buf_sample1 = NULL; + GstSample *buf_sample2 = NULL; + GstSample *buf_sample3 = NULL; + + if (!main || !user_data) { + GST_ERROR("capture callback error %p %p", main, user_data); + return FALSE; + } + + camerasrc = (GstTizenCameraSrc *)user_data; + + buf_sample1 = __create_buffer_sample(camerasrc, main); + if (!buf_sample1) { + GST_ERROR_OBJECT(camerasrc, "buffer sample1 creation failed"); + return FALSE; + } + + buf_sample2 = __create_buffer_sample(camerasrc, postview); + if (!buf_sample2) + GST_WARNING_OBJECT(camerasrc, "No sample for postview"); + + buf_sample3 = __create_buffer_sample(camerasrc, thumbnail); + if (!buf_sample3) + GST_WARNING_OBJECT(camerasrc, "No sample for thumbnail"); + + GST_INFO_OBJECT(camerasrc, "CALL: capture callback"); + + g_signal_emit(G_OBJECT(camerasrc), + gst_tizencamerasrc_signals[SIGNAL_STILL_CAPTURE], + 0, + buf_sample1, + buf_sample2, + buf_sample3); + + GST_INFO_OBJECT(camerasrc, "RETURN: capture callback"); + + return TRUE; +} + + +static gboolean gst_tizencamerasrc_create(GstTizenCameraSrc *camerasrc) +{ + int ret = 0; + + /* camera interface handle init */ + GST_INFO("camera_hal_interface init"); + + ret = camera_hal_interface_init(&camerasrc->hal_intf_handle); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR("camera_hal_interface_init() failed. errcode = 0x%08X", ret); + goto _ERROR; + } + + GST_INFO("camera_hal_interface_init() done"); + + ret = camera_hal_interface_open_device(camerasrc->hal_intf_handle, 0); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR("camera_hal_interface_open_device() failed. errcode = 0x%08X", ret); + camera_hal_interface_deinit(camerasrc->hal_intf_handle); + camerasrc->hal_intf_handle = NULL; + goto _ERROR; + } + + if (!gst_tizencamerasrc_fill_ctrl_list(camerasrc)) { + GST_WARNING("Can't fill v4l2 control list."); + } + + return TRUE; + + _ERROR: + gst_tizencamerasrc_error_handler(camerasrc, ret); + return FALSE; +} + + +static gboolean gst_tizencamerasrc_destroy(GstTizenCameraSrc *camerasrc) +{ + int ret = CAMERA_ERROR_NONE; + + GST_INFO_OBJECT(camerasrc, "ENTERED"); + + if (camerasrc->hal_intf_handle == NULL) { + GST_ERROR_OBJECT(camerasrc, "not initialized"); + return FALSE; + } + + if (camerasrc->hal_intf_handle) { + /* camera hal interface deinit */ + GST_INFO_OBJECT(camerasrc, "camerasrc_destroy() calling..."); + + camera_hal_interface_close_device(camerasrc->hal_intf_handle); + + ret = camera_hal_interface_deinit(camerasrc->hal_intf_handle); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR_OBJECT(camerasrc, "camera_hal_interface_deinit failed 0x%x", ret); + return FALSE; + } + + camerasrc->hal_intf_handle = NULL; + + /* Empty control list */ + gst_tizencamerasrc_empty_ctrl_list(camerasrc); + } + + GST_INFO_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static gboolean gst_tizencamerasrc_fill_ctrl_list(GstTizenCameraSrc *camerasrc) +{ + int n = 0; + + char *camerasrc_ctrl_label[CAMERA_COLOR_BALANCE_NUM] = { + "brightness", + "contrast", + "white balance", + "color tone", + "saturation", + "hue", + "sharpness", + }; + + uint64_t camerasrc_ctrl_cmd[CAMERA_COLOR_BALANCE_NUM] = { + CAMERA_COMMAND_EXPOSURE, + CAMERA_COMMAND_CONTRAST, + CAMERA_COMMAND_WHITE_BALANCE, + CAMERA_COMMAND_EFFECT, + CAMERA_COMMAND_SATURATION, + CAMERA_COMMAND_HUE, + CAMERA_COMMAND_SHARPNESS + }; + + g_return_val_if_fail(camerasrc, FALSE); + + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + + for (n = CAMERA_COMMAND_EXPOSURE ; n < CAMERA_COLOR_BALANCE_NUM ; n++) { + GstTizenCameraSrcColorBalanceChannel *camerasrc_color_channel = NULL; + GstColorBalanceChannel *color_channel = NULL; + + GstTizenCamerasrcControlChannel *camerasrc_control_channel = NULL; + GstCameraControlChannel *control_channel = NULL; + + gint channel_type; + + switch (n) { + case CAMERA_COLOR_BALANCE_BRIGHTNESS: + case CAMERA_COLOR_BALANCE_CONTRAST: + case CAMERA_COLOR_BALANCE_WHITE_BALANCE: + case CAMERA_COLOR_BALANCE_COLOR_TONE: + case CAMERA_COLOR_BALANCE_SATURATION: + case CAMERA_COLOR_BALANCE_HUE: + case CAMERA_COLOR_BALANCE_SHARPNESS: + channel_type = INTERFACE_COLOR_BALANCE; + break; + default: + channel_type = INTERFACE_CAMERA_CONTROL; + continue; + } + + if (channel_type == INTERFACE_COLOR_BALANCE) { + camerasrc_color_channel = g_object_new(GST_TYPE_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL, NULL); + color_channel = GST_COLOR_BALANCE_CHANNEL(camerasrc_color_channel); + + color_channel->label = g_strdup((const gchar *)camerasrc_ctrl_label[n]); + camerasrc_color_channel->id = camerasrc_ctrl_cmd[n]; + color_channel->min_value = 0; + color_channel->max_value = 0; + + camerasrc->colors = g_list_append(camerasrc->colors, (gpointer)color_channel); + GST_INFO_OBJECT(camerasrc, "Adding Color Balance Channel %s [%"PRIx64"]", + color_channel->label, camerasrc_color_channel->id); + } else { /* if( channel_type == INTERFACE_CAMERA_CONTROL ) */ + camerasrc_control_channel = g_object_new(GST_TYPE_TIZENCAMERASRC_CONTROL_CHANNEL, NULL); + control_channel = GST_CAMERA_CONTROL_CHANNEL(camerasrc_control_channel); + + control_channel->label = g_strdup((const gchar *)camerasrc_ctrl_label[n]); + camerasrc_control_channel->id = camerasrc_ctrl_cmd[n]; + control_channel->min_value = 0; + control_channel->max_value = 0; + + camerasrc->camera_controls = g_list_append(camerasrc->camera_controls, (gpointer)control_channel); + GST_INFO_OBJECT(camerasrc, "Adding Camera Control Channel %s [%"PRIx64"]", + control_channel->label, camerasrc_control_channel->id); + } + } + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static gboolean gst_tizencamerasrc_empty_ctrl_list(GstTizenCameraSrc *camerasrc) +{ + g_return_val_if_fail(camerasrc, FALSE); + + GST_DEBUG_OBJECT (camerasrc, "ENTERED"); + + g_list_foreach(camerasrc->colors, (GFunc)g_object_unref, NULL); + g_list_free(camerasrc->colors); + camerasrc->colors = NULL; + + g_list_foreach(camerasrc->camera_controls, (GFunc)g_object_unref, NULL); + g_list_free(camerasrc->camera_controls); + camerasrc->camera_controls = NULL; + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static gboolean gst_tizencamerasrc_start(GstTizenCameraSrc *camerasrc) +{ + int ret = 0; + + camera_flip_t set_flip; + camera_format_t set_format; + + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + + /* set message callback */ + camera_hal_interface_add_message_callback(camerasrc->hal_intf_handle, _camera_hal_message_callback, camerasrc, &camerasrc->msg_cb_id); + + CLEAR(set_format); + + /* set preview stream format */ + set_format.stream_format = camerasrc->pix_format; + set_format.stream_resolution.width = camerasrc->width; + set_format.stream_resolution.height = camerasrc->height; + switch (camerasrc->rotate) { + case 90: + set_format.stream_rotation = CAMERA_ROTATION_90; + break; + case 180: + set_format.stream_rotation = CAMERA_ROTATION_180; + break; + case 270: + set_format.stream_rotation = CAMERA_ROTATION_270; + break; + case 0: + default: + set_format.stream_rotation = CAMERA_ROTATION_0; + break; + } + if (camerasrc->fps_auto) { + /*if fps is zero, auto fps mode*/ + set_format.stream_fps = 0; + + GST_INFO_OBJECT (camerasrc, "AUTO FPS mode"); + } else if (camerasrc->high_speed_fps <= 0) { + if (camerasrc->fps <= 0) { + /*if fps is zero, auto fps mode*/ + set_format.stream_fps = 0; + } else { + set_format.stream_fps = camerasrc->fps; + } + } else { + GST_INFO_OBJECT(camerasrc, "high speed fps %d", camerasrc->high_speed_fps); + set_format.stream_fps = camerasrc->high_speed_fps; + } + + set_format.capture_format = CAMERA_PIXEL_FORMAT_ENCODED_JPEG; + set_format.capture_resolution.width = camerasrc->cap_width; + set_format.capture_resolution.height = camerasrc->cap_height; + set_format.capture_quality = (uint32_t)camerasrc->cap_jpg_quality; + + GST_INFO_OBJECT(camerasrc, "resolution [%dx%d] fps %d, format %d, rotation %d", + camerasrc->width, camerasrc->height, set_format.stream_fps, + camerasrc->pix_format, camerasrc->rotate); + + ret = camera_hal_interface_set_preview_stream_format(camerasrc->hal_intf_handle, &set_format); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR_OBJECT(camerasrc, "camera_hal_interface_set_preview_stream_format() failed 0x%x", ret); + goto _ERROR; + } + + /* set flip */ + if (camerasrc->vflip) { + if (camerasrc->hflip) + set_flip = CAMERA_FLIP_BOTH; + else + set_flip = CAMERA_FLIP_VERTICAL; + } else { + if (camerasrc->hflip) + set_flip = CAMERA_FLIP_HORIZONTAL; + else + set_flip = CAMERA_FLIP_NONE; + } + + camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FLIP, (void *)&set_flip); + + GST_INFO("VFLIP : %d, HFLIP : %d", camerasrc->vflip, camerasrc->hflip); + + /* start preview stream */ + ret = camera_hal_interface_start_preview(camerasrc->hal_intf_handle, _camera_preview_frame_cb, camerasrc); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR_OBJECT(camerasrc, "camera_hal_interface_start_preview() failed 0x%x", ret); + camerasrc->buffer_running = FALSE; + goto _ERROR; + } + + GST_INFO_OBJECT(camerasrc, "camerasrc_start_preview_stream() done"); + + camerasrc->mode = VIDEO_IN_MODE_PREVIEW; + camerasrc->buffer_running = TRUE; + + GST_INFO_OBJECT(camerasrc, "LEAVED"); + + return TRUE; + +_ERROR: + gst_tizencamerasrc_error_handler(camerasrc, ret); + GST_ERROR_OBJECT(camerasrc, "LEAVED 0x%x", ret); + + return FALSE; +} + + +static gboolean gst_tizencamerasrc_stop(GstTizenCameraSrc *camerasrc) +{ + int ret = CAMERA_ERROR_NONE; + + GST_INFO_OBJECT (camerasrc, "ENTERED"); + + if (camerasrc->hal_intf_handle) { + GstBuffer *buffer = NULL; + + /* Stop preview stream */ + g_mutex_lock(&camerasrc->buffer_lock); + if (camerasrc->buffer_running) { + camerasrc->buffer_running = FALSE; + } else { + GST_ERROR_OBJECT(camerasrc, "buffer NOT running"); + g_mutex_unlock(&camerasrc->buffer_lock); + return FALSE; + } + g_mutex_unlock(&camerasrc->buffer_lock); + + GST_INFO_OBJECT(camerasrc, "stop preview stream"); + + ret = camera_hal_interface_stop_preview(camerasrc->hal_intf_handle); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR_OBJECT(camerasrc, "camera_hal_interface_stop_preview failed 0x%x", ret); + camerasrc->buffer_running = TRUE; + return FALSE; + } + + camerasrc->mode = VIDEO_IN_MODE_NONE; + + while (!g_queue_is_empty(camerasrc->preview_buffer_list)) { + buffer = g_queue_pop_head(camerasrc->preview_buffer_list); + if (buffer) { + GST_INFO_OBJECT(camerasrc, "unref buffer %p", buffer); + gst_buffer_unref(buffer); + buffer = NULL; + } + } + } + + GST_INFO_OBJECT(camerasrc, "LEAVED"); + + return TRUE; +} + + +static gboolean gst_tizencamerasrc_capture_start(GstTizenCameraSrc *camerasrc) +{ + int ret = CAMERA_ERROR_NONE; + + GST_INFO_OBJECT(camerasrc, "ENTERED - mode %d", camerasrc->mode); + + if (camerasrc->mode == VIDEO_IN_MODE_PREVIEW) { + /* set preview buffer running flag to FALSE to release preview buffer immediately */ + g_mutex_lock(&camerasrc->buffer_lock); + + if (camerasrc->buffer_running) { + camerasrc->buffer_running = FALSE; + } else { + GST_ERROR_OBJECT(camerasrc, "buffer NOT running"); + g_mutex_unlock(&camerasrc->buffer_lock); + return FALSE; + } + + g_mutex_unlock(&camerasrc->buffer_lock); + + GST_INFO_OBJECT(camerasrc, "start capture"); + + ret = camera_hal_interface_start_capture(camerasrc->hal_intf_handle, _camera_capture_cb, camerasrc); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR_OBJECT(camerasrc, "camera_hal_interface_start_capture failed 0x%x", ret); + camerasrc->buffer_running = TRUE; + return FALSE; + } + + camerasrc->mode = VIDEO_IN_MODE_CAPTURE; + + g_mutex_lock(&camerasrc->buffer_lock); + + camerasrc->buffer_running = TRUE; + + g_cond_signal(&camerasrc->buffer_cond); + + g_mutex_unlock(&camerasrc->buffer_lock); + + GST_INFO_OBJECT(camerasrc, "CAPTURE STARTED!"); + + return TRUE; + } else { + GST_WARNING_OBJECT(camerasrc, "Wrong state[%d]!", camerasrc->mode); + return FALSE; + } +} + + +static gboolean gst_tizencamerasrc_capture_stop(GstTizenCameraSrc *camerasrc) +{ + int ret = CAMERA_ERROR_NONE; + + GST_INFO_OBJECT(camerasrc, "ENTERED - mode %d", camerasrc->mode); + + if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) { + ret = camera_hal_interface_stop_capture(camerasrc->hal_intf_handle); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR_OBJECT(camerasrc, "camera_hal_interface_stop_capture failed 0x%x", ret); + return FALSE; + } + + g_mutex_lock(&camerasrc->buffer_lock); + + camerasrc->mode = VIDEO_IN_MODE_PREVIEW; + + g_cond_signal(&camerasrc->buffer_cond); + + g_mutex_unlock(&camerasrc->buffer_lock); + + GST_INFO_OBJECT(camerasrc, "CAPTURE STOPPED!"); + + return TRUE; + } else { + GST_WARNING_OBJECT(camerasrc, "Wrong state[%d]!", camerasrc->mode); + return FALSE; + } +} + + +static GstFlowReturn gst_tizencamerasrc_read_preview(GstTizenCameraSrc *camerasrc, GstBuffer **buffer) +{ + int preview_check_count = 0; + gint64 end_time = 0; + + GST_DEBUG_OBJECT(camerasrc, "check preview buffer list"); + + g_mutex_lock(&camerasrc->buffer_lock); + + while (g_queue_is_empty(camerasrc->preview_buffer_list)) { + GST_DEBUG_OBJECT(camerasrc, "Preview buffer list is empty. waiting..."); + + if (camerasrc->mode == VIDEO_IN_MODE_PREVIEW) { + end_time = g_get_monotonic_time () + _PREVIEW_BUFFER_WAIT_TIMEOUT; + if (!g_cond_wait_until(&camerasrc->buffer_cond, &camerasrc->buffer_lock, end_time)) { + GST_ERROR_OBJECT(camerasrc, "Buffer wait timeout[%d usec]. Return ERROR", _PREVIEW_BUFFER_WAIT_TIMEOUT); + g_mutex_unlock(&camerasrc->buffer_lock); + gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_DEVICE_READ); + return GST_FLOW_ERROR; + } else { + preview_check_count++; + GST_DEBUG_OBJECT(camerasrc, "Signal received. Retry...[count %d]", preview_check_count); + } + } else if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) { + GST_INFO_OBJECT(camerasrc, "now capture mode. wait..."); + g_cond_wait(&camerasrc->buffer_cond, &camerasrc->buffer_lock); + GST_INFO_OBJECT(camerasrc, "capture mode - signal received, check preview buffer again."); + preview_check_count = 0; + } else if (preview_check_count > 5) { + GST_ERROR_OBJECT(camerasrc, "preview buffer check failed"); + g_mutex_unlock(&camerasrc->buffer_lock); + gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_DEVICE_READ); + return GST_FLOW_ERROR; + } + } + + *buffer = g_queue_pop_head(camerasrc->preview_buffer_list); + + g_mutex_unlock(&camerasrc->buffer_lock); + + if (*buffer == NULL) { + GST_ERROR_OBJECT(camerasrc, "popped buffer is NULL"); + + gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_DEVICE_READ); + + return GST_FLOW_ERROR; + } + + /* set timestamp and duration */ + gst_tizencamerasrc_get_timeinfo(camerasrc, *buffer); + + if (camerasrc->firsttime) { + camerasrc->firsttime = FALSE; + } + + GST_DEBUG_OBJECT(camerasrc, "preview buffer %p", *buffer); + + return GST_FLOW_OK; +} + + +static GstFlowReturn gst_tizencamerasrc_read(GstTizenCameraSrc *camerasrc, GstBuffer **buffer) +{ + GstFlowReturn ret = GST_FLOW_OK; + + switch (camerasrc->mode) { + case VIDEO_IN_MODE_PREVIEW: + case VIDEO_IN_MODE_CAPTURE: + case VIDEO_IN_MODE_VIDEO: + GST_DEBUG_OBJECT(camerasrc, "gst_tizencamerasrc_read_preview"); + ret = gst_tizencamerasrc_read_preview(camerasrc, buffer); + break; + case VIDEO_IN_MODE_NONE: + default: + ret = GST_FLOW_ERROR; + GST_ERROR_OBJECT (camerasrc, "can't reach statement.[camerasrc->mode=%d]", camerasrc->mode); + break; + } + + if (!buffer || !(*buffer) || !GST_IS_BUFFER(*buffer)) { + /* To avoid seg fault, make dummy buffer. */ + GST_WARNING_OBJECT (camerasrc, "Make a dummy buffer"); + *buffer = gst_buffer_new(); + } + + return ret; +} + + +static gboolean gst_tizencamerasrc_get_timeinfo(GstTizenCameraSrc *camerasrc, GstBuffer *buffer) +{ + int fps_nu = 0; + int fps_de = 0; + GstClock *clock = NULL; + GstClockTime timestamp = GST_CLOCK_TIME_NONE; + GstClockTime duration = GST_CLOCK_TIME_NONE; + + if (!camerasrc || !buffer) { + GST_WARNING_OBJECT (camerasrc, "Invalid pointer [hadle:%p, buffer:%p]", camerasrc, buffer); + return FALSE; + } + + /* timestamps, LOCK to get clock and base time. */ + clock = GST_ELEMENT_CLOCK(camerasrc); + if (clock) { + /* the time now is the time of the clock minus the base time */ + gst_object_ref(clock); + timestamp = gst_clock_get_time(clock) - GST_ELEMENT(camerasrc)->base_time; + gst_object_unref(clock); + + /* if we have a framerate adjust timestamp for frame latency */ + if (camerasrc->fps_auto) { + /* auto fps mode */ + duration = GST_CLOCK_TIME_NONE; + } else { + if (camerasrc->fps <= 0) { + /*if fps is zero, auto fps mode*/ + fps_nu = 0; + fps_de = 1; + } else { + fps_nu = 1; + fps_de = camerasrc->fps; + } + + if (fps_nu > 0 && fps_de > 0) { + duration = gst_util_uint64_scale_int(GST_SECOND, fps_nu, fps_de); + } + } + + /* set default duration if duration is NONE : 30 fps */ + if (duration == GST_CLOCK_TIME_NONE) { + duration = gst_util_uint64_scale_int(GST_SECOND, 1, 30); + } + } else { + /* no clock, can't set timestamps */ + timestamp = GST_CLOCK_TIME_NONE; + } + + GST_BUFFER_TIMESTAMP(buffer) = timestamp; + GST_BUFFER_DURATION(buffer) = duration; + + GST_LOG_OBJECT(camerasrc, "timestamp [%"GST_TIME_FORMAT" dur %" GST_TIME_FORMAT "]", + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), + GST_TIME_ARGS(GST_BUFFER_DURATION(buffer))); + + return TRUE; +} + + +/* Gstreamer general functions */ +static gboolean gst_tizencamerasrc_src_start(GstBaseSrc *src) +{ + int ret = TRUE; + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC (src); + + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + + camerasrc->firsttime = TRUE; + /* 'gst_tizencamerasrc_set_caps' will call gst_tizencamerasrc_start(). So skip to call it. */ + /*ret = gst_tizencamerasrc_start(camerasrc);*/ + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return ret; +} + + +static gboolean gst_tizencamerasrc_src_stop(GstBaseSrc *src) +{ + int ret = 0; + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(src); + + GST_DEBUG_OBJECT (camerasrc, "ENTERED"); + + ret = gst_tizencamerasrc_stop(camerasrc); + + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return ret; +} + + +static GstFlowReturn gst_tizencamerasrc_src_create(GstPushSrc *src, GstBuffer **buffer) +{ + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC (src); + GstFlowReturn ret; + + GST_LOG_OBJECT(camerasrc, "ENTERED"); + + ret = gst_tizencamerasrc_read(camerasrc, buffer); + + GST_LOG_OBJECT (camerasrc, "LEAVED"); + + return ret; +} + + +static void gst_tizencamerasrc_set_property(GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + int tmp = 0; + GstTizenCameraSrc *camerasrc = NULL; + + g_return_if_fail(GST_IS_TIZENCAMERA_SRC(object)); + camerasrc = GST_TIZENCAMERA_SRC(object); + + switch (prop_id) { + case ARG_CAMERA_HIGH_SPEED_FPS: + camerasrc->high_speed_fps = g_value_get_int(value); + GST_INFO_OBJECT(camerasrc, "Set HIGH SPEED FPS: %d", camerasrc->high_speed_fps); + break; + case ARG_CAMERA_AUTO_FPS: + camerasrc->fps_auto = g_value_get_boolean(value); + GST_INFO_OBJECT(camerasrc, "Set AUTO_FPS: %d", camerasrc->fps_auto); + break; + case ARG_CAMERA_ID: + camerasrc->camera_id = g_value_get_int(value); + break; + case ARG_CAMERA_CAPTURE_FOURCC: + camerasrc->cap_fourcc = g_value_get_uint(value); + break; + case ARG_CAMERA_CAPTURE_WIDTH: + camerasrc->cap_width = g_value_get_int(value); + GST_INFO_OBJECT(camerasrc, "Set capture width: %d", camerasrc->cap_width); + break; + case ARG_CAMERA_CAPTURE_HEIGHT: + camerasrc->cap_height = g_value_get_int(value); + GST_INFO_OBJECT(camerasrc, "Set capture height: %d", camerasrc->cap_height); + break; + case ARG_CAMERA_CAPTURE_INTERVAL: + camerasrc->cap_interval = g_value_get_int(value); + GST_INFO_OBJECT(camerasrc, "Set capture interval: %d", camerasrc->cap_interval); + break; + case ARG_CAMERA_CAPTURE_COUNT: + tmp = g_value_get_int(value); + camerasrc->cap_count = tmp; + camerasrc->cap_count_reverse = tmp; + GST_INFO_OBJECT(camerasrc, "Set capture count: %d", camerasrc->cap_count_reverse); + break; + case ARG_CAMERA_CAPTURE_JPG_QUALITY: + { + camerasrc->cap_jpg_quality = g_value_get_int(value); + GST_INFO_OBJECT(camerasrc, "Set jpeg quality : %d", camerasrc->cap_jpg_quality); + break; + } + case ARG_VFLIP: + camerasrc->vflip = g_value_get_boolean(value); + GST_INFO_OBJECT(camerasrc, "Set VFLIP : %d", camerasrc->vflip); + break; + case ARG_HFLIP: + camerasrc->hflip = g_value_get_boolean(value); + GST_INFO_OBJECT(camerasrc, "Set HFLIP : %d", camerasrc->hflip); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } + + return; +} + + +static void gst_tizencamerasrc_get_property(GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GstTizenCameraSrc *camerasrc; + + g_return_if_fail(GST_IS_TIZENCAMERA_SRC(object)); + camerasrc = GST_TIZENCAMERA_SRC(object); + + switch (prop_id) { + case ARG_CAMERA_HIGH_SPEED_FPS: + g_value_set_int(value, camerasrc->high_speed_fps); + break; + case ARG_CAMERA_AUTO_FPS: + g_value_set_boolean(value, camerasrc->fps_auto); + break; + case ARG_CAMERA_ID: + g_value_set_int(value, camerasrc->camera_id); + break; + case ARG_CAMERA_CAPTURE_FOURCC: + g_value_set_uint(value, camerasrc->cap_fourcc); + break; + case ARG_CAMERA_CAPTURE_WIDTH: + g_value_set_int(value, camerasrc->cap_width); + break; + case ARG_CAMERA_CAPTURE_HEIGHT: + g_value_set_int(value, camerasrc->cap_height); + break; + case ARG_CAMERA_CAPTURE_INTERVAL: + g_value_set_int(value, camerasrc->cap_interval); + break; + case ARG_CAMERA_CAPTURE_COUNT: + g_value_set_int(value, camerasrc->cap_count); + break; + case ARG_CAMERA_CAPTURE_JPG_QUALITY: + g_value_set_int(value, camerasrc->cap_jpg_quality); + GST_INFO("GET jpeg compress ratio : %d", camerasrc->cap_jpg_quality); + break; + case ARG_CAMERA_CAPTURE_PROVIDE_EXIF: + g_value_set_boolean(value, camerasrc->cap_provide_exif); + GST_INFO("Is Exif provided? : %d", camerasrc->cap_provide_exif); + break; + case ARG_VFLIP: + g_value_set_boolean(value, camerasrc->vflip); + break; + case ARG_HFLIP: + g_value_set_boolean(value, camerasrc->hflip); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } + + return; +} + + +static GstStateChangeReturn gst_tizencamerasrc_change_state(GstElement *element, GstStateChange transition) +{ + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstTizenCameraSrc *camerasrc; + camerasrc = GST_TIZENCAMERA_SRC (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: NULL -> READY"); + GST_INFO(" gst_tizencamerasrc_create"); + if (!gst_tizencamerasrc_create(camerasrc)){ + goto statechange_failed; + } + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: READY -> PAUSED"); + ret = GST_STATE_CHANGE_NO_PREROLL; + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> PLAYING"); + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS(gst_tizencamerasrc_parent_class)->change_state(element, transition); + if (ret == GST_STATE_CHANGE_FAILURE){ + return ret; + } + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PLAYING -> PAUSED"); + ret = GST_STATE_CHANGE_NO_PREROLL; + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: PAUSED -> READY"); + break; + case GST_STATE_CHANGE_READY_TO_NULL: + GST_INFO_OBJECT(camerasrc, "GST CAMERA SRC: READY -> NULL"); + GST_INFO(" gst_tizencamerasrc_destroy"); + if (!gst_tizencamerasrc_destroy(camerasrc)){ + goto statechange_failed; + } + break; + default: + break; + } + + return ret; + + statechange_failed: + /* subclass must post a meaningful error message */ + GST_ERROR_OBJECT(camerasrc, "state change failed"); + + return GST_STATE_CHANGE_FAILURE; +} + + +static void gst_tizencamerasrc_finalize(GObject *object) +{ + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(object); + + GST_INFO("ENTERED"); + + g_cond_clear(&camerasrc->buffer_cond); + g_mutex_clear(&camerasrc->buffer_lock); + SAFE_FREE_GQUEUE(camerasrc->preview_buffer_list); + + if (G_OBJECT_CLASS (gst_tizencamerasrc_parent_class)->finalize) + G_OBJECT_CLASS(gst_tizencamerasrc_parent_class)->finalize(object); + + GST_INFO("LEAVED"); + + return; +} + + +void gst_tizencamerasrc_set_capture_command(GstTizenCameraSrc *camerasrc, GstCameraControlCaptureCommand cmd) +{ + if (camerasrc == NULL) { + GST_ERROR_OBJECT(camerasrc, "camerasrc is NULL"); + return; + } + + GST_INFO_OBJECT(camerasrc, "ENTERED"); + + if (cmd == GST_CAMERA_CONTROL_CAPTURE_COMMAND_START) + gst_tizencamerasrc_capture_start(camerasrc); + else if (cmd == GST_CAMERA_CONTROL_CAPTURE_COMMAND_STOP) + gst_tizencamerasrc_capture_stop(camerasrc); + else + GST_WARNING_OBJECT(camerasrc, "not supported command %d", cmd); + + GST_INFO_OBJECT(camerasrc, "LEAVE"); + + return; +} + + +static gboolean +gst_tizencamerasrc_negotiate (GstBaseSrc * basesrc) +{ + GstCaps *thiscaps; + GstCaps *caps = NULL; + GstCaps *peercaps = NULL; + gboolean result = FALSE; + GstStructure *s; + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(basesrc); + + GST_INFO_OBJECT(camerasrc, "ENTERED"); + /* first see what is possible on our source pad */ + thiscaps = gst_pad_query_caps (GST_BASE_SRC_PAD (basesrc), NULL); + GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps); + + /* nothing or anything is allowed, we're done */ + if (thiscaps == NULL || gst_caps_is_any (thiscaps)) + goto no_nego_needed; + + /* get the peer caps */ + peercaps = gst_pad_peer_query_caps (GST_BASE_SRC_PAD (basesrc), NULL); + GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps); + //LOG_CAPS (basesrc, peercaps); + if (peercaps && !gst_caps_is_any (peercaps)) { + GstCaps *icaps = NULL; + int i; + + /* Prefer the first caps we are compatible with that the peer proposed */ + for (i = 0; i < gst_caps_get_size (peercaps); i++) { + /* get intersection */ + GstCaps *ipcaps = gst_caps_copy_nth (peercaps, i); + + GST_DEBUG_OBJECT (basesrc, "peer: %" GST_PTR_FORMAT, ipcaps); + icaps = gst_caps_intersect (thiscaps, ipcaps); + gst_caps_unref (ipcaps); + + /*s = gst_caps_get_structure (icaps, 0); + gst_structure_get_fourcc(s, "format", &camerasrc->fourcc); + if ((camerasrc->fourcc == GST_MAKE_FOURCC('S','N','1','2')) || + (camerasrc->fourcc == GST_MAKE_FOURCC('S','T','1','2'))) { + break; + }*/ + if (!gst_caps_is_empty (icaps)) + break; + + gst_caps_unref (icaps); + icaps = NULL; + } + + GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, icaps); + if (icaps) { + /* If there are multiple intersections pick the one with the smallest + * resolution strictly bigger then the first peer caps */ + if (gst_caps_get_size (icaps) > 1) { + s = gst_caps_get_structure (peercaps, 0); + int best = 0; + int twidth, theight; + int width = G_MAXINT, height = G_MAXINT; + + if (gst_structure_get_int (s, "width", &twidth) + && gst_structure_get_int (s, "height", &theight)) { + + /* Walk the structure backwards to get the first entry of the + * smallest resolution bigger (or equal to) the preferred resolution) + */ + for (i = gst_caps_get_size (icaps) - 1; i >= 0; i--) { + GstStructure *is = gst_caps_get_structure (icaps, i); + int w, h; + + if (gst_structure_get_int (is, "width", &w) + && gst_structure_get_int (is, "height", &h)) { + if (w >= twidth && w <= width && h >= theight && h <= height) { + width = w; + height = h; + best = i; + } + } + } + } + + caps = gst_caps_copy_nth (icaps, best); + gst_caps_unref (icaps); + } else { + caps = icaps; + } + } + gst_caps_unref (thiscaps); + gst_caps_unref (peercaps); + } else { + /* no peer or peer have ANY caps, work with our own caps then */ + caps = thiscaps; + } + if (caps) { + caps = gst_caps_fixate(caps); + + /* now fixate */ + if (!gst_caps_is_empty (caps)) { + GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps); + + if (gst_caps_is_any (caps)) { + /* hmm, still anything, so element can do anything and + * nego is not needed */ + result = TRUE; + } else if (gst_caps_is_fixed (caps)) { + /* yay, fixed caps, use those then */ + result = gst_tizencamerasrc_set_caps(basesrc, caps); + } + } + gst_caps_unref (caps); + } + return result; + +no_nego_needed: + { + GST_DEBUG_OBJECT (basesrc, "no negotiation needed"); + if (thiscaps) + gst_caps_unref (thiscaps); + return TRUE; + } +} + + +static GstCaps *gst_tizencamerasrc_get_caps(GstBaseSrc *src, GstCaps *filter) +{ + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(src); + GstCaps *ret = NULL; + + GST_DEBUG_OBJECT(camerasrc, "ENTERED"); + + if (camerasrc->mode == VIDEO_IN_MODE_NONE) { + GST_INFO_OBJECT(camerasrc, "Just return template caps."); + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + ret = gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc)); + return filter ? gst_caps_intersect(ret, filter) : gst_caps_copy(ret); + } + + /*FIXME: Using "VIDIOC_ENUM_FMT".*/ + ret = gst_caps_copy(gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(camerasrc))); + + if (filter != NULL) { + gst_caps_take(&ret, gst_caps_intersect(ret, filter)); + } + + GST_INFO_OBJECT(camerasrc, "probed caps: %p", ret); + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + + return ret; +} + + +static gboolean _gst_tizencamerasrc_get_raw_pixel_info(int fourcc, int *pix_format) +{ + if (pix_format == NULL) { + GST_ERROR("NULL pointer"); + return FALSE; + } + + switch (fourcc) { + case GST_MAKE_FOURCC('I','4','2','0'): + case GST_MAKE_FOURCC('S','4','2','0'): + *pix_format = CAMERA_PIXEL_FORMAT_I420;; + break; + case GST_MAKE_FOURCC('Y','V','1','2'): + *pix_format = CAMERA_PIXEL_FORMAT_YV12; + break; + case GST_MAKE_FOURCC('Y','U','Y','V'): + case GST_MAKE_FOURCC('Y','U','Y','2'): + case GST_MAKE_FOURCC('S','U','Y','V'): + case GST_MAKE_FOURCC('S','U','Y','2'): + *pix_format = CAMERA_PIXEL_FORMAT_YUYV; + break; + case GST_MAKE_FOURCC('U','Y','V','Y'): + case GST_MAKE_FOURCC('S','Y','V','Y'): + *pix_format = CAMERA_PIXEL_FORMAT_UYVY; + break; + case GST_MAKE_FOURCC('N','V','1','2'): + case GST_MAKE_FOURCC('S','N','1','2'): + *pix_format = CAMERA_PIXEL_FORMAT_NV12; + break; + default: + GST_ERROR("unknown fourcc %c%c%c%c", + fourcc, fourcc >> 8, fourcc >> 16, fourcc >> 24); + return FALSE; + } + + return TRUE; +} + + +static gboolean _gst_tizencamerasrc_get_frame_size(int fourcc, int width, int height, unsigned int *outsize) +{ + switch (fourcc) { + case GST_MAKE_FOURCC('I','4','2','0'): /* V4L2_PIX_FMT_YUV420 */ + case GST_MAKE_FOURCC('I','Y','U','V'): + case GST_MAKE_FOURCC('Y','U','1','2'): + case GST_MAKE_FOURCC('Y','V','1','2'): + case GST_MAKE_FOURCC('S','4','2','0'): /* V4L2_PIX_FMT_NV12 tiled non-linear */ + *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height); + *outsize += 2 * ((GST_ROUND_UP_8 (width) / 2) * (GST_ROUND_UP_2 (height) / 2)); + break; + case GST_MAKE_FOURCC('Y','U','Y','V'): /* V4L2_PIX_FMT_YUYV */ + case GST_MAKE_FOURCC('Y','U','Y','2'): /* V4L2_PIX_FMT_YUYV */ + case GST_MAKE_FOURCC('S','U','Y','V'): + case GST_MAKE_FOURCC('S','U','Y','2'): + case GST_MAKE_FOURCC('U','Y','V','Y'): /* V4L2_PIX_FMT_UYVY */ + case GST_MAKE_FOURCC('S','Y','V','Y'): /* V4L2_PIX_FMT_UYVY */ + case GST_MAKE_FOURCC('4','2','2','P'): /* V4L2_PIX_FMT_YUV422P */ + case GST_MAKE_FOURCC('Y','4','2','B'): /* V4L2_PIX_FMT_YUV422P */ + case GST_MAKE_FOURCC('Y','4','1','P'): /* V4L2_PIX_FMT_Y41P */ + *outsize = (GST_ROUND_UP_2 (width) * 2) * height; + break; + case GST_MAKE_FOURCC('Y','4','1','B'): /* V4L2_PIX_FMT_YUV411P */ + *outsize = GST_ROUND_UP_4 (width) * height; + *outsize += 2 * ((GST_ROUND_UP_8 (width) / 4) * height); + break; + case GST_MAKE_FOURCC('N','V','1','2'): /* V4L2_PIX_FMT_NV12 */ + case GST_MAKE_FOURCC('N','V','2','1'): /* V4L2_PIX_FMT_NV21 */ + case GST_MAKE_FOURCC('S','N','1','2'): /* V4L2_PIX_FMT_NV12 non-linear */ + case GST_MAKE_FOURCC('S','N','2','1'): /* V4L2_PIX_FMT_NV21 non-linear */ + *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height); + *outsize += (GST_ROUND_UP_4 (width) * height) / 2; + break; + case GST_MAKE_FOURCC('J','P','E','G'): + case GST_MAKE_FOURCC('j','p','e','g'): + /* jpeg size can't be calculated here. */ + *outsize = 0; + break; + default: + /* unknown format!! */ + *outsize = 0; + break; + } + + return TRUE; +} + + +static gboolean gst_tizencamerasrc_get_caps_info(GstTizenCameraSrc *camerasrc, GstCaps *caps, guint *size) +{ + gint fps_n = 0; + gint fps_d = 0; + gint width = 0; + gint height = 0; + gint rotate = 0; + gchar *caps_string = NULL; + const gchar *mimetype; + GstVideoInfo caps_info; + const gchar *caps_format_name = NULL; + guint32 caps_fourcc = 0; + const GValue *framerate; + GstStructure *structure = NULL; + + GST_INFO_OBJECT(camerasrc, "ENTERED Collect data for given caps.(caps:%p)", caps); + + structure = gst_caps_get_structure(caps, 0); + + if (!gst_structure_get_int(structure, "width", &width)) { + goto _caps_info_failed; + } + + if (!gst_structure_get_int(structure, "height", &height)) { + goto _caps_info_failed; + } + + if (!gst_structure_get_int(structure, "rotate", &rotate)) { + GST_WARNING_OBJECT(camerasrc, "Failed to get rotate info in caps. set default 0."); + camerasrc->use_rotate_caps = FALSE; + } else { + GST_INFO_OBJECT(camerasrc, "Succeed to get rotate [%d] info in caps", rotate); + camerasrc->use_rotate_caps = TRUE; + } + + camerasrc->width = width; + camerasrc->height = height; + camerasrc->rotate = rotate; + + framerate = gst_structure_get_value(structure, "framerate"); + if (!framerate) { + GST_INFO("Set FPS as default(30/1)"); + + /* set default fps if framerate is not existed in caps */ + fps_n = _DEFAULT_FPS; + fps_d = 1; + } else { + fps_n = gst_value_get_fraction_numerator(framerate); + fps_d = gst_value_get_fraction_denominator(framerate); + + /* numerator and denominator should be bigger than zero */ + if (fps_n <= 0) { + GST_WARNING("numerator of FPS is %d. make it default(15).", fps_n); + fps_n = _DEFAULT_FPS; + } + + if (fps_d <= 0) { + GST_WARNING("denominator of FPS is %d. make it 1.", fps_d); + fps_d = 1; + } + } + + camerasrc->fps = (int)((float)fps_n / (float)fps_d); + + mimetype = gst_structure_get_name (structure); + + *size = 0; + + if (!strcmp(mimetype, "video/x-raw")) { + gst_video_info_init(&caps_info); + if (gst_video_info_from_caps(&caps_info, caps) && + GST_VIDEO_INFO_IS_YUV(&caps_info)) { + caps_format_name = gst_structure_get_string(structure, "format"); + if (caps_format_name == NULL) { + GST_ERROR_OBJECT(camerasrc, "Getting format name is NULL."); + goto _caps_info_failed; + } + + strncpy(camerasrc->format_name, caps_format_name, sizeof(camerasrc->format_name)); + caps_fourcc = MAKE_FOURCC_FROM_STRING(camerasrc->format_name); + + _gst_tizencamerasrc_get_frame_size(caps_fourcc, width, height, size); + _gst_tizencamerasrc_get_raw_pixel_info(caps_fourcc, &camerasrc->pix_format); + } else { + GST_ERROR_OBJECT(camerasrc, "video/x-raw, but NOT YUV"); + goto _caps_info_failed; + } + } else { + GST_ERROR_OBJECT(camerasrc, "NOT video/x-raw"); + goto _caps_info_failed; + } + + GST_INFO_OBJECT(camerasrc, "pixformat %d, size %d", camerasrc->pix_format, *size); + + caps_string = gst_caps_to_string(caps); + if (caps_string) { + GST_INFO_OBJECT(camerasrc, "caps : [%s]", caps_string); + g_free(caps_string); + caps_string = NULL; + } + + return TRUE; + +_caps_info_failed: + GST_INFO_OBJECT(camerasrc, "Failed to get caps info."); + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + return FALSE; +} + + +static void _gst_tizencamerasrc_post_message_int(GstTizenCameraSrc *camerasrc, const char *msg_name, const char *field_name, int value) +{ + GstMessage *m = NULL; + GstStructure *s = NULL; + + if (!camerasrc || !msg_name || !field_name) { + GST_ERROR("pointer is NULL %p, %p, %p", camerasrc, msg_name, field_name); + return; + } + + GST_INFO("post message [%s] %s %d", msg_name, field_name, value); + + s = gst_structure_new(msg_name, field_name, G_TYPE_INT, value, NULL); + if (s == NULL) { + GST_ERROR("gst_structure_new failed"); + gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_OUT_OF_MEMORY); + return; + } + + m = gst_message_new_element(GST_OBJECT(camerasrc), s); + if (m == NULL) { + GST_ERROR("gst_message_new_element failed"); + gst_tizencamerasrc_error_handler(camerasrc, CAMERA_ERROR_OUT_OF_MEMORY); + return; + } + + gst_element_post_message(GST_ELEMENT(camerasrc), m); + + return; +} + + +static gboolean gst_tizencamerasrc_set_caps(GstBaseSrc *src, GstCaps *caps) +{ + guint size; + GstTizenCameraSrc *camerasrc = NULL; + gboolean res = FALSE; + + camerasrc = GST_TIZENCAMERA_SRC(src); + + GST_INFO_OBJECT(camerasrc, "ENTERED"); + + if (camerasrc->mode == VIDEO_IN_MODE_PREVIEW || + camerasrc->mode == VIDEO_IN_MODE_VIDEO) { + GST_INFO_OBJECT(camerasrc, "Proceed set_caps"); + GST_INFO(" gst_tizencamerasrc_stop"); + if (!gst_tizencamerasrc_stop(camerasrc)) { + GST_INFO_OBJECT(camerasrc, "Cam sensor stop failed."); + } + } else if (camerasrc->mode == VIDEO_IN_MODE_CAPTURE) { + GST_ERROR_OBJECT(camerasrc, "A mode of avsystem camera is capture. Not to proceed set_caps."); + GST_DEBUG_OBJECT(camerasrc, "LEAVED"); + return FALSE; + } else { + GST_INFO_OBJECT(camerasrc, "A mode of avsystem camera is unknown[%d]. Proceed set_caps.", camerasrc->mode); + } + + /* we want our own v4l2 type of fourcc codes */ + if (!gst_tizencamerasrc_get_caps_info(camerasrc, caps, &size)) { + GST_INFO_OBJECT(camerasrc, "can't get capture information from caps %p", caps); + return FALSE; + } + + GST_INFO(" gst_tizencamerasrc_start"); + if (!gst_tizencamerasrc_start(camerasrc)) { + GST_INFO_OBJECT (camerasrc, "Cam sensor start failed."); + } + + res = gst_pad_push_event (GST_BASE_SRC_PAD (src), gst_event_new_caps (caps)); + + GST_INFO_OBJECT (camerasrc, "LEAVED"); + + return res; +} + + +static void gst_tizencamerasrc_class_init(GstTizenCameraSrcClass *klass) +{ + GST_DEBUG_CATEGORY_INIT(camerasrc_debug, "camerasrc", 0, "camerasrc element"); + + GObjectClass *gobject_class; + GstElementClass *element_class; + GstBaseSrcClass *basesrc_class; + GstPushSrcClass *pushsrc_class; + + GST_DEBUG("ENTERED"); + + gobject_class = G_OBJECT_CLASS(klass); + element_class = GST_ELEMENT_CLASS(klass); + basesrc_class = GST_BASE_SRC_CLASS(klass); + pushsrc_class = GST_PUSH_SRC_CLASS(klass); + + gobject_class->set_property = gst_tizencamerasrc_set_property; + gobject_class->get_property = gst_tizencamerasrc_get_property; + gobject_class->finalize = gst_tizencamerasrc_finalize; + element_class->change_state = gst_tizencamerasrc_change_state; + gst_element_class_add_pad_template(element_class, gst_static_pad_template_get (&src_factory)); + gst_element_class_set_static_metadata(element_class, + "Camera Source GStreamer Plug-in", + "Source/Video", + "camera src for videosrc based GStreamer Plug-in", + "Jeongmo Yang "); + basesrc_class->start = gst_tizencamerasrc_src_start; + basesrc_class->stop = gst_tizencamerasrc_src_stop; + basesrc_class->get_caps = gst_tizencamerasrc_get_caps; + basesrc_class->set_caps = gst_tizencamerasrc_set_caps; + basesrc_class->negotiate = gst_tizencamerasrc_negotiate; + pushsrc_class->create = gst_tizencamerasrc_src_create; + + g_object_class_install_property(gobject_class, ARG_CAMERA_HIGH_SPEED_FPS, + g_param_spec_int("high-speed-fps", "Fps for high speed recording", + "If this value is 0, the element doesn't activate high speed recording.", + 0, G_MAXINT, _DEFAULT_HIGH_SPEED_FPS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_AUTO_FPS, + g_param_spec_boolean("fps-auto", "FPS Auto", + "Field for auto fps setting", + _DEFAULT_FPS_AUTO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_ID, + g_param_spec_int("camera-id", "index number of camera to activate", + "index number of camera to activate", + _CAMERA_ID_MIN, _CAMERA_ID_MAX, 0, + G_PARAM_READWRITE)); + + /*Capture*/ + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_FOURCC, + g_param_spec_uint("capture-fourcc", "Capture format", + "Fourcc value for capture format", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_WIDTH, + g_param_spec_int("capture-width", "Capture width", + "Width for camera size to capture", + 0, G_MAXINT, _DEFAULT_CAP_WIDTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_HEIGHT, + g_param_spec_int("capture-height", "Capture height", + "Height for camera size to capture", + 0, G_MAXINT, _DEFAULT_CAP_HEIGHT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_INTERVAL, + g_param_spec_int("capture-interval", "Capture interval", + "Interval time to capture (millisecond)", + 0, G_MAXINT, _DEFAULT_CAP_INTERVAL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_COUNT, + g_param_spec_int("capture-count", "Capture count", + "Capture count for multishot", + 1, G_MAXINT, _DEFAULT_CAP_COUNT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_JPG_QUALITY, + g_param_spec_int("capture-jpg-quality", "JPEG Capture compress ratio", + "Quality of capture image compress ratio", + 1, 100, _DEFAULT_CAP_JPG_QUALITY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_CAMERA_CAPTURE_PROVIDE_EXIF, + g_param_spec_boolean("provide-exif", "Whether EXIF is provided", + "Does capture provide EXIF?", + _DEFAULT_CAP_PROVIDE_EXIF, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_VFLIP, + g_param_spec_boolean("vflip", "Flip vertically", + "Flip camera input vertically", + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class, ARG_HFLIP, + g_param_spec_boolean("hflip", "Flip horizontally", + "Flip camera input horizontally", + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstTizenCameraSrc::still-capture: + * @camerasrc: the camerasrc instance + * @buffer: the buffer that will be pushed - Main + * @buffer: the buffer that will be pushed - Thumbnail + * @buffer: the buffer that will be pushed - Screennail + * + * This signal gets emitted before sending the buffer. + */ + gst_tizencamerasrc_signals[SIGNAL_STILL_CAPTURE] = + g_signal_new("still-capture", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GstTizenCameraSrcClass, still_capture), + NULL, + NULL, + g_cclosure_user_marshal_VOID__OBJECT_OBJECT_OBJECT, + G_TYPE_NONE, + 3, /* Number of parameter */ + GST_TYPE_SAMPLE, /* Main image buffer */ + GST_TYPE_SAMPLE, /* Thumbnail image buffer */ + GST_TYPE_SAMPLE); /* Screennail image buffer */ + + GST_DEBUG("LEAVED"); + + return; +} + + +static void gst_tizencamerasrc_init(GstTizenCameraSrc *camerasrc) +{ + GST_INFO("ENTERED"); + + camerasrc->hal_intf_handle = NULL; + camerasrc->mode = VIDEO_IN_MODE_NONE; + camerasrc->firsttime = TRUE; + camerasrc->cap_count_current = -1; + camerasrc->cap_count_reverse = _DEFAULT_CAP_COUNT; + + /*camera*/ + camerasrc->fps = _DEFAULT_FPS; + camerasrc->rotate = 0; + camerasrc->use_rotate_caps = FALSE; + camerasrc->high_speed_fps = _DEFAULT_HIGH_SPEED_FPS; + camerasrc->fps_auto = _DEFAULT_FPS_AUTO; + camerasrc->pix_format = _DEFAULT_PIX_FORMAT; + strcpy(camerasrc->format_name, _DEFAULT_PIX_FORMAT_NAME); + camerasrc->buffer_running = FALSE; + camerasrc->vflip = FALSE; + camerasrc->hflip = FALSE; + camerasrc->camera_id = _DEFAULT_CAMERA_ID; + camerasrc->preview_buffer_list = g_queue_new (); + + /*capture*/ + camerasrc->cap_fourcc = MAKE_FOURCC_FROM_STRING(_DEFAULT_CAPTURE_FORMAT_NAME); + camerasrc->cap_width = _DEFAULT_CAP_WIDTH; + camerasrc->cap_height = _DEFAULT_CAP_HEIGHT; + camerasrc->cap_interval = _DEFAULT_CAP_INTERVAL; + camerasrc->cap_count = _DEFAULT_CAP_COUNT; + camerasrc->cap_jpg_quality = _DEFAULT_CAP_JPG_QUALITY; + camerasrc->cap_provide_exif = _DEFAULT_CAP_PROVIDE_EXIF; + + g_mutex_init(&camerasrc->buffer_lock); + g_cond_init(&camerasrc->buffer_cond); + + /* we operate in time */ + gst_base_src_set_format(GST_BASE_SRC(camerasrc), GST_FORMAT_TIME); + gst_base_src_set_live(GST_BASE_SRC(camerasrc), TRUE); + gst_base_src_set_do_timestamp(GST_BASE_SRC(camerasrc), TRUE); + + GST_INFO("LEAVED"); + + return; +} + +#if 0 +static unsigned long _get_current_time(void) +{ + struct timeval lc_time; + gettimeofday(&lc_time, NULL); + return ((unsigned long)(lc_time.tv_sec * 1000L) + (unsigned long)(lc_time.tv_usec / 1000L)); +} +#endif + + +#if _ENABLE_CAMERASRC_DEBUG +#include +static int __util_write_file(char *filename, void *data, int size) +{ + FILE *fp = NULL; + + fp = fopen(filename, "wb"); + if (!fp) { + return FALSE; + } + + fwrite(data, 1, size, fp); + fclose(fp); + + return TRUE; +} +#endif + + +static gboolean plugin_init(GstPlugin *plugin) +{ + gboolean error; + + error = gst_element_register(plugin, "tizencamerasrc", GST_RANK_PRIMARY + 100, GST_TYPE_TIZENCAMERA_SRC); + + return error; +} + + +GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, + GST_VERSION_MINOR, + tizencamerasrc, + "Tizen reference camera source plug-in", + plugin_init, + PACKAGE_VERSION, + "LGPL", + "Samsung Electronics Co", + "http://www.samsung.com") + +/* GstURIHandler interface */ +static GstURIType +gst_tizencamerasrc_uri_get_type (GType type) +{ + return GST_URI_SRC; +} + +static const gchar * const* +gst_tizencamerasrc_uri_get_protocols (GType type) +{ + static const gchar *protocols[] = { "camera", NULL }; + return protocols; +} + +static gchar * +gst_tizencamerasrc_uri_get_uri (GstURIHandler * handler) +{ + return strdup("camera://0"); +} + +static gboolean +gst_tizencamerasrc_uri_set_uri (GstURIHandler * handler, const gchar * uri, GError **error) +{ + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC (handler); + const gchar *device = "0"; + if (strcmp (uri, "camera://") != 0) { + device = uri + 9; + } + g_object_set (camerasrc, "camera-id", atoi(device), NULL); + + return TRUE; +} + + +static void +gst_tizencamerasrc_uri_handler_init (gpointer g_iface, gpointer iface_data) +{ + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + + iface->get_type = gst_tizencamerasrc_uri_get_type; + iface->get_protocols = gst_tizencamerasrc_uri_get_protocols; + iface->get_uri = gst_tizencamerasrc_uri_get_uri; + iface->set_uri = gst_tizencamerasrc_uri_set_uri; +} +/* EOF */ diff --git a/tizencamerasrc/src/gsttizencamerasrccolorbalance.c b/tizencamerasrc/src/gsttizencamerasrccolorbalance.c new file mode 100644 index 0000000..3dcc761 --- /dev/null +++ b/tizencamerasrc/src/gsttizencamerasrccolorbalance.c @@ -0,0 +1,92 @@ +/* + * gsttizencamerasrccolorbalance.c + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gsttizencamerasrccolorbalance.h" + +G_DEFINE_TYPE(GstTizenCameraSrcColorBalanceChannel, + gst_tizencamerasrc_color_balance_channel, + GST_TYPE_COLOR_BALANCE_CHANNEL); + +#ifndef GST_CAT_DEFAULT +GST_DEBUG_CATEGORY_EXTERN(camerasrc_debug); +#define GST_CAT_DEFAULT camerasrc_debug +#endif /* GST_CAT_DEFAULT */ + + +static void gst_tizencamerasrc_color_balance_channel_class_init(GstTizenCameraSrcColorBalanceChannelClass *klass) +{ +} + +static void gst_tizencamerasrc_color_balance_channel_init(GstTizenCameraSrcColorBalanceChannel *camerasrc_color_channel) +{ + camerasrc_color_channel->id = (guint32) - 1; +} + +static G_GNUC_UNUSED gboolean gst_tizencamerasrc_color_balance_contains_channel(GstTizenCameraSrc *camerasrc, GstTizenCameraSrcColorBalanceChannel *camerasrc_color_channel) +{ + const GList *item = NULL; + + for (item = camerasrc->colors ; item != NULL ; item = item->next) { + if (item->data == camerasrc_color_channel) + return TRUE; + } + + return FALSE; +} + +const GList *gst_tizencamerasrc_color_balance_list_channels(GstTizenCameraSrc *camerasrc) +{ + return camerasrc->colors; +} + +void gst_tizencamerasrc_color_balance_set_value(GstTizenCameraSrc *camerasrc, GstColorBalanceChannel *color_channel, gint value) +{ + GstTizenCameraSrcColorBalanceChannel *camerasrc_color_channel = GST_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL(color_channel); + + /* assert that we're opened and that we're using a known item */ + g_return_if_fail(camerasrc); + g_return_if_fail(gst_tizencamerasrc_color_balance_contains_channel(camerasrc, camerasrc_color_channel)); + + /* TODO */ + + return; +} + +gint gst_tizencamerasrc_color_balance_get_value(GstTizenCameraSrc *camerasrc, GstColorBalanceChannel *color_channel) +{ + int value = 0; + GstTizenCameraSrcColorBalanceChannel *camerasrc_color_channel = GST_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL(color_channel); + + /* assert that we're opened and that we're using a known item */ + g_return_val_if_fail(camerasrc, FALSE); + g_return_val_if_fail(gst_tizencamerasrc_color_balance_contains_channel(camerasrc, camerasrc_color_channel), FALSE); + + /* TODO */ + + return value; +} diff --git a/tizencamerasrc/src/gsttizencamerasrccontrol.c b/tizencamerasrc/src/gsttizencamerasrccontrol.c new file mode 100644 index 0000000..1f2140f --- /dev/null +++ b/tizencamerasrc/src/gsttizencamerasrccontrol.c @@ -0,0 +1,727 @@ +/* + * gsttizencamerasrccontrol.c + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gsttizencamerasrccontrol.h" +#include "camera_hal_interface.h" + +#define gst_tizencamerasrc_debug(fmt, args...) GST_INFO(fmt, ##args) + +#define CAMERA_CONTROL_AF_STOP_TOTALTIME 2000000 +#define CAMERA_CONTROL_AF_STOP_INTERVAL 20000 + +/** + * Enumeration of Wide Dynamic Range + */ +enum { + CAMERA_CONTROL_WDR_OFF = 1, + CAMERA_CONTROL_WDR_ON, + CAMERA_CONTROL_WDR_AUTO, +}; + +G_DEFINE_TYPE(GstTizenCamerasrcControlChannel, + gst_tizencamerasrc_control_channel, + GST_TYPE_CAMERA_CONTROL_CHANNEL); + +static void gst_tizencamerasrc_control_channel_class_init(GstTizenCamerasrcControlChannelClass *klass) +{ + gst_tizencamerasrc_debug("class init"); +} + +static void gst_tizencamerasrc_control_channel_init(GstTizenCamerasrcControlChannel *control_channel) +{ + gst_tizencamerasrc_debug("channel init"); + control_channel->id = (guint32) - 1; +} + +static G_GNUC_UNUSED gboolean gst_tizencamerasrc_control_contains_channel(GstTizenCameraSrc *camerasrc, GstTizenCamerasrcControlChannel *camerasrc_control_channel) +{ + gst_tizencamerasrc_debug("contains channel"); + + const GList *item = NULL; + + for (item = camerasrc->camera_controls ; item != NULL ; item = item->next) { + if (item->data == camerasrc_control_channel) { + return TRUE; + } + } + + return FALSE; +} + +const GList *gst_tizencamerasrc_control_list_channels(GstTizenCameraSrc *camerasrc) +{ + gst_tizencamerasrc_debug("list channels"); + return camerasrc->camera_controls; +} + +gboolean gst_tizencamerasrc_control_set_value(GstTizenCameraSrc *camerasrc, GstCameraControlChannel *control_channel, gint value) +{ + gst_tizencamerasrc_debug("set value : %d", value); + + GstTizenCamerasrcControlChannel *camerasrc_control_channel = GST_TIZENCAMERASRC_CONTROL_CHANNEL(control_channel); + + g_return_val_if_fail(camerasrc, FALSE); + g_return_val_if_fail(gst_tizencamerasrc_control_contains_channel(camerasrc, camerasrc_control_channel), FALSE); + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_value(GstTizenCameraSrc *camerasrc, GstCameraControlChannel *control_channel, gint *value) +{ + gst_tizencamerasrc_debug("get value"); + + GstTizenCamerasrcControlChannel *camerasrc_control_channel = GST_TIZENCAMERASRC_CONTROL_CHANNEL(control_channel); + + g_return_val_if_fail(camerasrc, FALSE); + g_return_val_if_fail(gst_tizencamerasrc_control_contains_channel(camerasrc, camerasrc_control_channel), FALSE); + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_exposure(GstTizenCameraSrc *camerasrc, gint type, gint value1, gint value2) +{ + int ret = CAMERA_ERROR_NONE; + camera_fraction_t frac; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set exposure"); + + /* TODO : F number */ + switch (type) { + case GST_CAMERA_CONTROL_F_NUMBER: + ret = CAMERA_ERROR_NONE; + break; + case GST_CAMERA_CONTROL_SHUTTER_SPEED: + frac.numerator = value1; + frac.denominator = value2; + gst_tizencamerasrc_debug(" camerasrc_set_shutter_speed"); + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_SHUTTER_SPEED, &frac); + break; + case GST_CAMERA_CONTROL_ISO: + gst_tizencamerasrc_debug(" camerasrc_set_iso_value"); + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_ISO, &value1); + break; + case GST_CAMERA_CONTROL_PROGRAM_MODE: + gst_tizencamerasrc_debug(" camerasrc_set_control"); + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_SCENE_MODE, &value1); + break; + case GST_CAMERA_CONTROL_EXPOSURE_MODE: + gst_tizencamerasrc_debug(" camerasrc_set_exposure_mode"); + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_EXPOSURE_MODE, &value1); + break; + case GST_CAMERA_CONTROL_EXPOSURE_VALUE: + frac.numerator = value1; + frac.denominator = value2; + gst_tizencamerasrc_debug(" camerasrc_set_exposure_value"); + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_EXPOSURE, &frac); + break; + default: + gst_tizencamerasrc_debug("Not supported type."); + return FALSE; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set exposure 0x%x Type[%d] value1[%d] value2[%d]", ret, type, value1, value2); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_exposure(GstTizenCameraSrc *camerasrc, gint type, gint *value1, gint *value2) +{ + int ret = CAMERA_ERROR_NONE; + camera_fraction_t frac; + + g_return_val_if_fail(camerasrc, FALSE); + g_return_val_if_fail(value1, FALSE); + + gst_tizencamerasrc_debug("get exposure"); + + /* TODO : F number */ + switch (type) { + case GST_CAMERA_CONTROL_F_NUMBER: + break; + case GST_CAMERA_CONTROL_SHUTTER_SPEED: + g_return_val_if_fail(value2, FALSE); + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_SHUTTER_SPEED, &frac); + if (ret == CAMERA_ERROR_NONE) { + *value1 = frac.numerator; + *value2 = frac.denominator; + } + break; + case GST_CAMERA_CONTROL_ISO: + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_ISO, value1); + break; + case GST_CAMERA_CONTROL_PROGRAM_MODE: + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_SCENE_MODE, value1); + break; + case GST_CAMERA_CONTROL_EXPOSURE_MODE: + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_EXPOSURE_MODE, value1); + break; + case GST_CAMERA_CONTROL_EXPOSURE_VALUE: + g_return_val_if_fail(value2, FALSE); + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_EXPOSURE, &frac); + if (ret == CAMERA_ERROR_NONE) { + *value1 = frac.numerator; + *value2 = frac.denominator; + } + break; + default: + gst_tizencamerasrc_debug("Not supported type."); + return FALSE; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to get exposure 0x%x Type[%d]", ret, type); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_capture_mode(GstTizenCameraSrc *camerasrc, gint type, gint value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set capture mode"); + + switch (type) { + case GST_CAMERA_CONTROL_CAPTURE_MODE: + break; + case GST_CAMERA_CONTROL_OUTPUT_MODE: + break; + case GST_CAMERA_CONTROL_FRAME_COUNT: + break; + case GST_CAMERA_CONTROL_JPEG_QUALITY: + break; + default: + gst_tizencamerasrc_debug("Not supported type."); + return FALSE; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set capture mode. Type[%d],value[%d],err code[%x]", type, value, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_capture_mode(GstTizenCameraSrc *camerasrc, gint type, gint *value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get capture mode"); + + switch (type) { + case GST_CAMERA_CONTROL_CAPTURE_MODE: + break; + case GST_CAMERA_CONTROL_OUTPUT_MODE: + break; + case GST_CAMERA_CONTROL_FRAME_COUNT: + break; + case GST_CAMERA_CONTROL_JPEG_QUALITY: + break; + default: + gst_tizencamerasrc_debug("Not supported type."); + return FALSE; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set capture mode. Type[%d],err code[%x]", type, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_strobe(GstTizenCameraSrc *camerasrc, gint type, gint value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set strobe"); + + switch (type) { + case GST_CAMERA_CONTROL_STROBE_MODE: + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FLASH_MODE, &value); + break; + case GST_CAMERA_CONTROL_STROBE_CONTROL: + case GST_CAMERA_CONTROL_STROBE_CAPABILITIES: + case GST_CAMERA_CONTROL_STROBE_STATUS: + case GST_CAMERA_CONTROL_STROBE_EV: + default: + gst_tizencamerasrc_debug("Not supported type[%d], return CAMERASRC_ERR_DEVICE_NOT_SUPPORT.", type); + ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED; + break; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set strobe. Type[%d],value[%d],err code[%x]", type, value, ret); + return FALSE; + } + + gst_tizencamerasrc_debug("Succeed to set strobe. Type[%d],value[%d]", type, value); + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_strobe(GstTizenCameraSrc *camerasrc, gint type, gint *value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get strobe"); + + switch (type) { + case GST_CAMERA_CONTROL_STROBE_MODE: + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FLASH_MODE, value); + break; + case GST_CAMERA_CONTROL_STROBE_CONTROL: + case GST_CAMERA_CONTROL_STROBE_CAPABILITIES: + case GST_CAMERA_CONTROL_STROBE_STATUS: + case GST_CAMERA_CONTROL_STROBE_EV: + default: + gst_tizencamerasrc_debug("Not supported type[%d].", type); + ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED; + break; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to get strobe. Type[%d],err code[%x]", type, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_detect(GstTizenCameraSrc *camerasrc, gint type, gint value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set detect"); + + /* TODO */ + switch (type) { + case GST_CAMERA_CONTROL_FACE_DETECT_MODE: + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FACE_DETECTION, &value); + break; + case GST_CAMERA_CONTROL_FACE_DETECT_NUMBER: + break; + case GST_CAMERA_CONTROL_FACE_FOCUS_SELECT: + break; + case GST_CAMERA_CONTROL_FACE_SELECT_NUMBER: + break; + case GST_CAMERA_CONTROL_FACE_DETECT_STATUS: + break; + default: + gst_tizencamerasrc_debug("Not supported type."); + return FALSE; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set detect. Type[%d],value[%d],err code[%x]", type, value, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_detect(GstTizenCameraSrc *camerasrc, gint type, gint *value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get detect"); + + /* TODO : detection number, focus select, select number, detect status */ + switch (type) { + case GST_CAMERA_CONTROL_FACE_DETECT_MODE: + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FACE_DETECTION, value); + break; + case GST_CAMERA_CONTROL_FACE_DETECT_NUMBER: + break; + case GST_CAMERA_CONTROL_FACE_FOCUS_SELECT: + break; + case GST_CAMERA_CONTROL_FACE_SELECT_NUMBER: + break; + case GST_CAMERA_CONTROL_FACE_DETECT_STATUS: + break; + default: + gst_tizencamerasrc_debug("Not supported type."); + return FALSE; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to get detect. Type[%d],err code[%x]", type, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_zoom(GstTizenCameraSrc *camerasrc, gint type, gint value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set zoom"); + + switch (type) { + case GST_CAMERA_CONTROL_DIGITAL_ZOOM: + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_DIGITAL_ZOOM, &value); + break; + case GST_CAMERA_CONTROL_OPTICAL_ZOOM: + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_OPTICAL_ZOOM, &value); + break; + default: + gst_tizencamerasrc_debug("Not supported type."); + return FALSE; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set zoom. Type[%d],value[%d],err code[%x]", type, value, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_zoom(GstTizenCameraSrc *camerasrc, gint type, gint *value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get zoom"); + + switch (type) { + case GST_CAMERA_CONTROL_DIGITAL_ZOOM: + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_DIGITAL_ZOOM, value); + break; + case GST_CAMERA_CONTROL_OPTICAL_ZOOM: + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_OPTICAL_ZOOM, value); + break; + default: + gst_tizencamerasrc_debug("Not supported type."); + return FALSE; + } + + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to get zoom. Type[%d],err code[%x]", type, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_focus(GstTizenCameraSrc *camerasrc, gint focus_mode, gint focus_range) +{ + int ret = CAMERA_ERROR_NONE; + int64_t error_cmd = 0; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set focus"); + + camera_batch_command_control_t batch_cmd; + + memset(&batch_cmd, 0x0, sizeof(camera_batch_command_control_t)); + + batch_cmd.focus_mode = focus_mode; + batch_cmd.command_set_flag |= CAMERA_COMMAND_FOCUS_MODE; + batch_cmd.focus_range = focus_range; + batch_cmd.command_set_flag |= CAMERA_COMMAND_FOCUS_RANGE; + + ret = camera_hal_interface_set_batch_command(camerasrc->hal_intf_handle, &batch_cmd, &error_cmd); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set AF mode. error cmd %lld", error_cmd); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_focus(GstTizenCameraSrc *camerasrc, gint *focus_mode, gint *focus_range) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get focus"); + + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FOCUS_MODE, focus_mode); + ret |= camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FOCUS_RANGE, focus_range); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to get AF mode."); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_start_auto_focus(GstTizenCameraSrc *camerasrc) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("start auto focus"); + + ret = camera_hal_interface_start_auto_focus(camerasrc->hal_intf_handle); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to start AF. error[0x%x]", ret); + return FALSE; + } else { + gst_tizencamerasrc_debug("Succeeded to start AF."); + return TRUE; + } +} + +gboolean gst_tizencamerasrc_control_stop_auto_focus(GstTizenCameraSrc *camerasrc) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("stop auto focus"); + + ret = camera_hal_interface_stop_auto_focus(camerasrc->hal_intf_handle); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to stop autofocus."); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_focus_level(GstTizenCameraSrc *camerasrc, gint focus_level) +{ + /* TODO : */ + + gst_tizencamerasrc_debug("Not support"); + return FALSE; +} + +gboolean gst_tizencamerasrc_control_get_focus_level(GstTizenCameraSrc *camerasrc, gint *focus_level) +{ + /* TODO : */ + + gst_tizencamerasrc_debug("Not support"); + return FALSE; +} + +gboolean gst_tizencamerasrc_control_set_auto_focus_area(GstTizenCameraSrc *camerasrc, GstCameraControlRectType rect) +{ + int ret = CAMERA_ERROR_NONE; + camera_rectangle_t set_rect; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set auto focus area"); + + set_rect.x = rect.x; + set_rect.y = rect.y; + set_rect.width = rect.width; + set_rect.height = rect.height; + + GST_INFO_OBJECT(camerasrc, "Set AF area %d,%d,%dx%d", + set_rect.x, set_rect.y, + set_rect.width, set_rect.height); + + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FOCUS_AREA, &set_rect); + if (ret != CAMERA_ERROR_NONE) { + GST_ERROR_OBJECT(camerasrc, "Failed to set auto focus area 0x%x", ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_auto_focus_area(GstTizenCameraSrc *camerasrc, GstCameraControlRectType *rect) +{ + int ret = CAMERA_ERROR_NONE; + camera_rectangle_t get_rect; + + g_return_val_if_fail(camerasrc, FALSE); + g_return_val_if_fail(rect, FALSE); + + gst_tizencamerasrc_debug("get auto focus area"); + + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_FOCUS_AREA, &get_rect); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to get auto focus area."); + return FALSE; + } + + rect->x = get_rect.x; + rect->y = get_rect.y; + rect->width = get_rect.width; + rect->height = get_rect.height; + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_wdr(GstTizenCameraSrc *camerasrc, gint value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set wdr"); + + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_WDR, &value); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set wdr. value[%d],err code[%x]", value, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_wdr(GstTizenCameraSrc *camerasrc, gint *value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get wdr"); + + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_WDR, value); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to get wdr. err code[%x]", ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_set_ahs(GstTizenCameraSrc *camerasrc, gint value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("set ahs"); + + ret = camera_hal_interface_set_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_ANTI_SHAKE, &value); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to set ahs. value[%d],err code[%x]", value, ret); + return FALSE; + } + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_ahs(GstTizenCameraSrc *camerasrc, gint *value) +{ + int ret = CAMERA_ERROR_NONE; + + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get ahs"); + + ret = camera_hal_interface_get_command(camerasrc->hal_intf_handle, CAMERA_COMMAND_ANTI_SHAKE, value); + if (ret != CAMERA_ERROR_NONE) { + gst_tizencamerasrc_debug("Failed to get ahs. err code[%x]", ret); + return FALSE; + } + + return TRUE; +} + + +gboolean gst_tizencamerasrc_control_get_exif_info(GstTizenCameraSrc *camerasrc, GstCameraControlExifInfo *info) +{ + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get exif info"); + + /* TODO */ + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_basic_dev_info (GstTizenCameraSrc *camerasrc, gint dev_id, GstCameraControlCapsInfoType *info) +{ + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get basic dev info"); + + /* TODO */ + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_misc_dev_info(GstTizenCameraSrc *camerasrc, gint dev_id, GstCameraControlCtrlListInfoType *info) +{ + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get misc dev info"); + + /* TODO */ + + return TRUE; +} + +gboolean gst_tizencamerasrc_control_get_extra_dev_info(GstTizenCameraSrc *camerasrc, gint dev_id, GstCameraControlExtraInfoType *info) +{ + g_return_val_if_fail(camerasrc, FALSE); + + gst_tizencamerasrc_debug("get extra dev info"); + + /* TODO */ + + return TRUE; +} + +void gst_tizencamerasrc_control_set_capture_command(GstTizenCameraSrc *camerasrc, GstCameraControlCaptureCommand cmd) +{ + gst_tizencamerasrc_debug("set capture command"); + + if (camerasrc == NULL) { + gst_tizencamerasrc_debug("camerasrc is NULL"); + return; + } + + gst_tizencamerasrc_set_capture_command(camerasrc, cmd); + + return; +} diff --git a/tizencamerasrc/src/include/camera_hal_interface.h b/tizencamerasrc/src/include/camera_hal_interface.h new file mode 100644 index 0000000..3ab6179 --- /dev/null +++ b/tizencamerasrc/src/include/camera_hal_interface.h @@ -0,0 +1,54 @@ +/* + * camera_hal_interface.h + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +#include + + + +typedef struct _camera_hal_interface camera_hal_interface; + +int camera_hal_interface_init(camera_hal_interface **h); +int camera_hal_interface_deinit(camera_hal_interface *h); +int camera_hal_interface_get_device_list(camera_hal_interface *h, camera_device_list_t *device_list); +int camera_hal_interface_open_device(camera_hal_interface *h, int device_index); +int camera_hal_interface_close_device(camera_hal_interface *h); +int camera_hal_interface_add_message_callback(camera_hal_interface *h, camera_message_cb callback, void *user_data, uint32_t *cb_id); +int camera_hal_interface_remove_message_callback(camera_hal_interface *h, uint32_t cb_id); +int camera_hal_interface_set_preview_stream_format(camera_hal_interface *h, camera_format_t *format); +int camera_hal_interface_get_preview_stream_format(camera_hal_interface *h, camera_format_t *format); +int camera_hal_interface_start_preview(camera_hal_interface *h, camera_preview_frame_cb callback, void *user_data); +int camera_hal_interface_release_preview_buffer(camera_hal_interface *h, int buffer_index); +int camera_hal_interface_stop_preview(camera_hal_interface *h); +int camera_hal_interface_start_auto_focus(camera_hal_interface *h); +int camera_hal_interface_stop_auto_focus(camera_hal_interface *h); +int camera_hal_interface_start_capture(camera_hal_interface *h, camera_capture_cb callback, void *user_data); +int camera_hal_interface_stop_capture(camera_hal_interface *h); +int camera_hal_interface_set_video_stream_format(camera_hal_interface *h, camera_format_t *format); +int camera_hal_interface_get_video_stream_format(camera_hal_interface *h, camera_format_t *format); +int camera_hal_interface_start_record(camera_hal_interface *h, camera_video_frame_cb callback, void *user_data); +int camera_hal_interface_release_video_buffer(camera_hal_interface *h, int buffer_index); +int camera_hal_interface_stop_record(camera_hal_interface *h); +int camera_hal_interface_set_command(camera_hal_interface *h, int64_t command, void *value); +int camera_hal_interface_get_command(camera_hal_interface *h, int64_t command, void *value); +int camera_hal_interface_set_batch_command(camera_hal_interface *h, camera_batch_command_control_t *batch_command, int64_t *error_command); diff --git a/tizencamerasrc/src/include/gsttizencamerasrc.h b/tizencamerasrc/src/include/gsttizencamerasrc.h new file mode 100644 index 0000000..f7845dc --- /dev/null +++ b/tizencamerasrc/src/include/gsttizencamerasrc.h @@ -0,0 +1,126 @@ +/* + * gsttizencamerasrc.h + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_TIZENCAMERASRC_H__ +#define __GST_TIZENCAMERASRC_H__ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "camera_hal_interface.h" + + +G_BEGIN_DECLS +#define GST_TYPE_TIZENCAMERA_SRC (gst_tizencamerasrc_get_type()) +#define GST_TIZENCAMERA_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TIZENCAMERA_SRC,GstTizenCameraSrc)) +#define GST_TIZENCAMERA_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TIZENCAMERA_SRC,GstTizenCameraSrcClass)) +#define GST_IS_TIZENCAMERA_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TIZENCAMERA_SRC)) +#define GST_IS_TIZENCAMERA_SRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TIZENCAMERA_SRC)) + + +#define FORMAT_NAME_LENGTH 10 + + +typedef struct _GstTizenCameraSrc GstTizenCameraSrc; +typedef struct _GstTizenCameraSrcClass GstTizenCameraSrcClass; + +struct _GstTizenCameraSrc +{ + GstPushSrc element; + + /*private*/ + camera_hal_interface *hal_intf_handle; /**< Camera HAL interface handle */ + int mode; + gboolean vflip; /**< flip camera input vertically */ + gboolean hflip; /**< flip camera input horizontally */ + gboolean firsttime; + + int cap_count_current; /**< current capture count */ + int cap_count_reverse; /**< current capture count (reverse counting) */ + GQueue *preview_buffer_list; + uint32_t msg_cb_id; + + /*camera property*/ + int width; /**< Width */ + int height; /**< Height */ + int fps; /**< Video source fps */ + + gchar format_name[FORMAT_NAME_LENGTH]; /**< Format name */ + int pix_format; /**< Image format of video source */ + int high_speed_fps; /**< Video source fps for high speed recording */ + gboolean fps_auto; /**< Auto Video source fps */ + + int camera_id; + int rotate; /**< Video source rotate */ + gboolean use_rotate_caps; /**< Use or not rotate value in caps */ + + GCond buffer_cond; /**< condition for buffer control */ + GMutex buffer_lock; /**< lock for buffer control */ + gboolean buffer_running; /**< with lock */ + + /* Colorbalance , CameraControl interface */ + GList *colors; + GList *camera_controls; + + /*capture property*/ + guint32 cap_fourcc; /**< gstreamer fourcc value(GST_MAKE_FOURCC format) for raw capturing */ + int cap_width; /**< Capture width */ + int cap_height; /**< Capture height */ + int cap_interval; /**< Capture interval */ + int cap_count; /**< Capture count */ + int cap_jpg_quality; /**< Capture quality for jpg compress ratio */ + gboolean cap_provide_exif; /**< Is exif provided? */ +}; + +struct _GstTizenCameraSrcClass { + GstPushSrcClass parent_class; + /* signals */ + void (*still_capture) (GstElement *element, GstBuffer *main, GstBuffer *sub, GstBuffer *scrnl); + void (*nego_complete) (GstElement *element); + void (*register_trouble) (GstElement *element); +}; + +typedef enum { + INTERFACE_NONE, + INTERFACE_COLOR_BALANCE, + INTERFACE_CAMERA_CONTROL, +} GstInterfaceType; + + +void gst_tizencamerasrc_set_capture_command(GstTizenCameraSrc* camerasrc, GstCameraControlCaptureCommand cmd); + + +GType gst_tizencamerasrc_get_type(void); + +G_END_DECLS + +#endif /* __GST_TIZENCAMERASRC_H__ */ diff --git a/tizencamerasrc/src/include/gsttizencamerasrccolorbalance.h b/tizencamerasrc/src/include/gsttizencamerasrccolorbalance.h new file mode 100644 index 0000000..d6ed7fa --- /dev/null +++ b/tizencamerasrc/src/include/gsttizencamerasrccolorbalance.h @@ -0,0 +1,91 @@ +/* + * gsttizencamerasrccolorbalance.h + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_TIZENCAMERASRC_COLOR_BALANCE_H__ +#define __GST_TIZENCAMERASRC_COLOR_BALANCE_H__ + +#include +#include +#include "gsttizencamerasrc.h" + +G_BEGIN_DECLS + +#define GST_TYPE_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL (gst_tizencamerasrc_color_balance_channel_get_type ()) +#define GST_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL, GstTizenCameraSrcColorBalanceChannel)) +#define GST_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL, GstTizenCameraSrcColorBalanceChannelClass)) +#define GST_IS_CAMERASRC_COLOR_BALANCE_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL)) +#define GST_IS_CAMERASRC_COLOR_BALANCE_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TIZENCAMERASRC_COLOR_BALANCE_CHANNEL)) + +typedef struct _GstTizenCameraSrcColorBalanceChannel { + GstColorBalanceChannel parent; + + int64_t id; +} GstTizenCameraSrcColorBalanceChannel; + +typedef struct _GstTizenCameraSrcColorBalanceChannelClass { + GstColorBalanceChannelClass parent; +} GstTizenCameraSrcColorBalanceChannelClass; + +GType gst_tizencamerasrc_color_balance_channel_get_type( void ); + +const GList *gst_tizencamerasrc_color_balance_list_channels( GstTizenCameraSrc *camerasrc ); +void gst_tizencamerasrc_color_balance_set_value( GstTizenCameraSrc *camerasrc, GstColorBalanceChannel *color_channel, gint value ); +gint gst_tizencamerasrc_color_balance_get_value( GstTizenCameraSrc *camerasrc, GstColorBalanceChannel *color_channel ); + +#define GST_IMPLEMENT_TIZENCAMERASRC_COLOR_BALANCE_METHODS( Type, interface_as_function ) \ + \ +static const GList* \ +interface_as_function ## _color_balance_list_channels( GstColorBalance *balance ) \ +{ \ + Type *this = (Type*) balance; \ + return gst_tizencamerasrc_color_balance_list_channels( this ); \ +} \ + \ +static void \ +interface_as_function ## _color_balance_set_value( GstColorBalance *balance, \ + GstColorBalanceChannel *color_channel, \ + gint value ) \ +{ \ + Type *this = (Type*) balance; \ + return gst_tizencamerasrc_color_balance_set_value( this, color_channel, value ); \ +} \ + \ +static gint \ +interface_as_function ## _color_balance_get_value( GstColorBalance *balance, \ + GstColorBalanceChannel *color_channel )\ +{ \ + Type *this = (Type*) balance; \ + return gst_tizencamerasrc_color_balance_get_value( this, color_channel ); \ +} \ + \ +void \ +interface_as_function ## _color_balance_interface_init( GstColorBalanceInterface *klass ) \ +{ \ + /* default virtual functions */ \ + klass->list_channels = interface_as_function ## _color_balance_list_channels; \ + klass->set_value = interface_as_function ## _color_balance_set_value; \ + klass->get_value = interface_as_function ## _color_balance_get_value; \ +} + +#endif /* __GST_TIZENCAMERASRC_COLOR_BALANCE_H__ */ + diff --git a/tizencamerasrc/src/include/gsttizencamerasrccontrol.h b/tizencamerasrc/src/include/gsttizencamerasrccontrol.h new file mode 100644 index 0000000..f5afe10 --- /dev/null +++ b/tizencamerasrc/src/include/gsttizencamerasrccontrol.h @@ -0,0 +1,364 @@ +/* + * gsttizencamerasrccontrol.h + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_TIZENCAMERASRC_CONTROL_H__ +#define __GST_TIZENCAMERASRC_CONTROL_H__ + +#include +#include +#include "gsttizencamerasrc.h" + +G_BEGIN_DECLS + +#define GST_TYPE_TIZENCAMERASRC_CONTROL_CHANNEL (gst_tizencamerasrc_control_channel_get_type ()) +#define GST_TIZENCAMERASRC_CONTROL_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TIZENCAMERASRC_CONTROL_CHANNEL, GstTizenCamerasrcControlChannel)) +#define GST_TIZENCAMERASRC_CONTROL_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TIZENCAMERASRC_CONTROL_CHANNEL, GstTizenCamerasrcControlChannelClass)) +#define GST_IS_TIZENCAMERASRC_CONTROL_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TIZENCAMERASRC_CONTROL_CHANNEL)) +#define GST_IS_TIZENCAMERASRC_CONTROL_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TIZENCAMERASRC_CONTROL_CHANNEL)) + +typedef struct _GstTizenCamerasrcControlChannel { + GstCameraControlChannel parent; + int64_t id; +} GstTizenCamerasrcControlChannel; + +typedef struct _GstTizenCamerasrcControlChannelClass { + GstCameraControlChannelClass parent; +} GstTizenCamerasrcControlChannelClass; + +GType gst_tizencamerasrc_control_channel_get_type(void); + +const GList *gst_tizencamerasrc_control_list_channels(GstTizenCameraSrc *camera_src); + +gboolean gst_tizencamerasrc_control_set_value (GstTizenCameraSrc *camera_src, GstCameraControlChannel *control_channel, gint value); +gboolean gst_tizencamerasrc_control_get_value (GstTizenCameraSrc *camera_src, GstCameraControlChannel *control_channel, gint *value); +gboolean gst_tizencamerasrc_control_set_exposure (GstTizenCameraSrc *camera_src, gint type, gint value1, gint value2); +gboolean gst_tizencamerasrc_control_get_exposure (GstTizenCameraSrc *camera_src, gint type, gint *value1, gint *value2); +gboolean gst_tizencamerasrc_control_set_capture_mode (GstTizenCameraSrc *camera_src, gint type, gint value); +gboolean gst_tizencamerasrc_control_get_capture_mode (GstTizenCameraSrc *camera_src, gint type, gint *value); +gboolean gst_tizencamerasrc_control_set_strobe (GstTizenCameraSrc *camera_src, gint type, gint value); +gboolean gst_tizencamerasrc_control_get_strobe (GstTizenCameraSrc *camera_src, gint type, gint *value); +gboolean gst_tizencamerasrc_control_set_detect (GstTizenCameraSrc *camera_src, gint type, gint value); +gboolean gst_tizencamerasrc_control_get_detect (GstTizenCameraSrc *camera_src, gint type, gint *value); +gboolean gst_tizencamerasrc_control_set_zoom (GstTizenCameraSrc *camera_src, gint type, gint value); +gboolean gst_tizencamerasrc_control_get_zoom (GstTizenCameraSrc *camera_src, gint type, gint *value); +gboolean gst_tizencamerasrc_control_set_focus (GstTizenCameraSrc *camera_src, gint mode, gint range); +gboolean gst_tizencamerasrc_control_get_focus (GstTizenCameraSrc *camera_src, gint *mode, gint *range); +gboolean gst_tizencamerasrc_control_start_auto_focus (GstTizenCameraSrc *camera_src); +gboolean gst_tizencamerasrc_control_stop_auto_focus (GstTizenCameraSrc *camera_src); +gboolean gst_tizencamerasrc_control_set_focus_level (GstTizenCameraSrc *camera_src, gint manual_level); +gboolean gst_tizencamerasrc_control_get_focus_level (GstTizenCameraSrc *camera_src, gint *manual_level); +gboolean gst_tizencamerasrc_control_set_auto_focus_area(GstTizenCameraSrc *camera_src, GstCameraControlRectType rect); +gboolean gst_tizencamerasrc_control_get_auto_focus_area(GstTizenCameraSrc *camera_src, GstCameraControlRectType *rect); +gboolean gst_tizencamerasrc_control_set_wdr (GstTizenCameraSrc *camera_src, gint value); +gboolean gst_tizencamerasrc_control_get_wdr (GstTizenCameraSrc *camera_src, gint *value); +gboolean gst_tizencamerasrc_control_set_ahs (GstTizenCameraSrc *camera_src, gint value); +gboolean gst_tizencamerasrc_control_get_ahs (GstTizenCameraSrc *camera_src, gint *value); +gboolean gst_tizencamerasrc_control_get_exif_info (GstTizenCameraSrc *camera_src, GstCameraControlExifInfo *info); +gboolean gst_tizencamerasrc_control_get_basic_dev_info (GstTizenCameraSrc *camera_src, gint dev_id, GstCameraControlCapsInfoType *info); +gboolean gst_tizencamerasrc_control_get_misc_dev_info (GstTizenCameraSrc *camera_src, gint dev_id, GstCameraControlCtrlListInfoType *info); +gboolean gst_tizencamerasrc_control_get_extra_dev_info (GstTizenCameraSrc *camera_src, gint dev_id, GstCameraControlExtraInfoType *info); +void gst_tizencamerasrc_control_set_capture_command(GstTizenCameraSrc *camera_src, GstCameraControlCaptureCommand cmd); + +#define GST_IMPLEMENT_TIZENCAMERASRC_CONTROL_METHODS(Type, interface_as_function) \ + \ +static const GList* \ +interface_as_function ## _control_list_channels(GstCameraControl *control) \ +{ \ + Type *this = (Type *) control; \ + return gst_tizencamerasrc_control_list_channels(this); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_value(GstCameraControl *control, \ + GstCameraControlChannel *control_channel, int value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_value(this, control_channel, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_value(GstCameraControl *control, \ + GstCameraControlChannel *control_channel, int *value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_value(this, control_channel, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_exposure(GstCameraControl *control, \ + gint type, gint value1, gint value2) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_exposure(this, type, value1, value2); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_exposure(GstCameraControl *control, \ + gint type, gint *value1, gint *value2) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_exposure(this, type, value1, value2); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_capture_mode(GstCameraControl *control, \ + gint type, gint value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_capture_mode(this, type, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_capture_mode(GstCameraControl *control, \ + gint type, gint *value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_capture_mode(this, type, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_strobe(GstCameraControl *control, \ + gint type, gint value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_strobe(this, type, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_strobe(GstCameraControl *control, \ + gint type, gint *value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_strobe(this, type, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_detect(GstCameraControl *control, \ + gint type, gint value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_detect(this, type, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_detect(GstCameraControl *control, \ + gint type, gint *value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_detect(this, type, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_zoom(GstCameraControl *control, \ + gint type, gint value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_zoom(this, type, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_zoom(GstCameraControl *control, \ + gint type, gint *value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_zoom(this, type, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_focus(GstCameraControl *control, \ + gint focus_mode, gint focus_range) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_focus(this, focus_mode, focus_range); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_focus(GstCameraControl *control, \ + gint *focus_mode, gint *focus_range) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_focus(this, focus_mode, focus_range); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_start_auto_focus(GstCameraControl *control) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_start_auto_focus(this); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_stop_auto_focus(GstCameraControl *control) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_stop_auto_focus(this); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_focus_level(GstCameraControl *control, \ + gint focus_level) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_focus_level(this, focus_level); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_focus_level(GstCameraControl *control, \ + gint *focus_level) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_focus_level(this, focus_level); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_auto_focus_area(GstCameraControl *control, \ + GstCameraControlRectType rect) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_auto_focus_area(this, rect); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_auto_focus_area(GstCameraControl *control, \ + GstCameraControlRectType *rect) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_auto_focus_area(this, rect); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_wdr(GstCameraControl *control, \ + gint value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_wdr(this, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_wdr(GstCameraControl *control, \ + gint *value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_wdr(this, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_set_ahs(GstCameraControl *control, \ + gint value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_set_ahs(this, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_ahs(GstCameraControl *control, \ + gint *value) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_ahs(this, value); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_exif_info(GstCameraControl *control, \ + GstCameraControlExifInfo *info) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_exif_info(this, info); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_basic_dev_info(GstCameraControl *control, \ + gint dev_id, \ + GstCameraControlCapsInfoType *info) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_basic_dev_info(this, dev_id, info); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_misc_dev_info(GstCameraControl *control, \ + gint dev_id, \ + GstCameraControlCtrlListInfoType *info) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_misc_dev_info(this, dev_id, info); \ +} \ + \ +static gboolean \ +interface_as_function ## _control_get_extra_dev_info(GstCameraControl *control, \ + gint dev_id, \ + GstCameraControlExtraInfoType *info) \ +{ \ + Type *this = (Type *)control; \ + return gst_tizencamerasrc_control_get_extra_dev_info(this, dev_id, info); \ +} \ + \ +static void \ +interface_as_function ## _control_set_capture_command(GstCameraControl *control, \ + GstCameraControlCaptureCommand cmd) \ +{ \ + Type *this = (Type *)control; \ + gst_tizencamerasrc_control_set_capture_command(this, cmd); \ + return; \ +} \ + \ +void \ +interface_as_function ## _control_interface_init(GstCameraControlClass *klass) \ +{ \ + GST_CAMERA_CONTROL_TYPE(klass) = GST_CAMERA_CONTROL_HARDWARE; \ + \ + /* default virtual functions */ \ + klass->list_channels = interface_as_function ## _control_list_channels; \ + klass->set_value = interface_as_function ## _control_set_value; \ + klass->get_value = interface_as_function ## _control_get_value; \ + klass->set_exposure = interface_as_function ## _control_set_exposure; \ + klass->get_exposure = interface_as_function ## _control_get_exposure; \ + klass->set_capture_mode = interface_as_function ## _control_set_capture_mode; \ + klass->get_capture_mode = interface_as_function ## _control_get_capture_mode; \ + klass->set_strobe = interface_as_function ## _control_set_strobe; \ + klass->get_strobe = interface_as_function ## _control_get_strobe; \ + klass->set_detect = interface_as_function ## _control_set_detect; \ + klass->get_detect = interface_as_function ## _control_get_detect; \ + klass->set_zoom = interface_as_function ## _control_set_zoom; \ + klass->get_zoom = interface_as_function ## _control_get_zoom; \ + klass->set_focus = interface_as_function ## _control_set_focus; \ + klass->get_focus = interface_as_function ## _control_get_focus; \ + klass->start_auto_focus = interface_as_function ## _control_start_auto_focus; \ + klass->stop_auto_focus = interface_as_function ## _control_stop_auto_focus; \ + klass->set_focus_level = interface_as_function ## _control_set_focus_level; \ + klass->get_focus_level = interface_as_function ## _control_get_focus_level; \ + klass->set_auto_focus_area = interface_as_function ## _control_set_auto_focus_area; \ + klass->get_auto_focus_area = interface_as_function ## _control_get_auto_focus_area; \ + klass->set_wdr = interface_as_function ## _control_set_wdr; \ + klass->get_wdr = interface_as_function ## _control_get_wdr; \ + klass->set_ahs = interface_as_function ## _control_set_ahs; \ + klass->get_ahs = interface_as_function ## _control_get_ahs; \ + klass->get_exif_info = interface_as_function ## _control_get_exif_info; \ + klass->get_basic_dev_info = interface_as_function ## _control_get_basic_dev_info; \ + klass->get_misc_dev_info = interface_as_function ## _control_get_misc_dev_info; \ + klass->get_extra_dev_info = interface_as_function ## _control_get_extra_dev_info; \ + klass->set_capture_command = interface_as_function ## _control_set_capture_command; \ + \ +} + +#endif /* __GST_TIZENCAMERASRC_CONTROL_H__ */ -- 2.7.4 From 859161f9ecb51633b2529e21abde634b66c2d5d5 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Mon, 9 Apr 2018 11:05:00 +0900 Subject: [PATCH 10/16] Change enum for camera pixel format - CAMERA_PIXEL_FORMAT_ENCODED_JPEG -> CAMERA_PIXEL_FORMAT_JPEG [Version] 1.0.0-55 [Profile] Common [Issue Type] Update [Dependency module] mm-hal-interface Change-Id: I7c749dcd8ac9eac46a2c6cb2217f08e04b3665fa Signed-off-by: Jeongmo Yang --- packaging/gst-plugins-tizen.spec | 2 +- tizencamerasrc/src/gsttizencamerasrc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 69474d2..7fd2bf6 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,7 +9,7 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 54 +Release: 55 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ diff --git a/tizencamerasrc/src/gsttizencamerasrc.c b/tizencamerasrc/src/gsttizencamerasrc.c index bb4bf78..194b473 100644 --- a/tizencamerasrc/src/gsttizencamerasrc.c +++ b/tizencamerasrc/src/gsttizencamerasrc.c @@ -436,7 +436,7 @@ static GstSample *__create_buffer_sample(GstTizenCameraSrc *camerasrc, camera_bu return NULL; } - if (cam_buffer->format == CAMERA_PIXEL_FORMAT_ENCODED_JPEG) { + if (cam_buffer->format == CAMERA_PIXEL_FORMAT_JPEG) { caps = gst_caps_new_simple("image/jpeg", "width", G_TYPE_INT, cam_buffer->resolution.width, "height", G_TYPE_INT, cam_buffer->resolution.height, @@ -746,7 +746,7 @@ static gboolean gst_tizencamerasrc_start(GstTizenCameraSrc *camerasrc) set_format.stream_fps = camerasrc->high_speed_fps; } - set_format.capture_format = CAMERA_PIXEL_FORMAT_ENCODED_JPEG; + set_format.capture_format = CAMERA_PIXEL_FORMAT_JPEG; set_format.capture_resolution.width = camerasrc->cap_width; set_format.capture_resolution.height = camerasrc->cap_height; set_format.capture_quality = (uint32_t)camerasrc->cap_jpg_quality; -- 2.7.4 From 98ee96db591c2022d7ea45772d226c779fa29b08 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 19 Apr 2018 11:27:38 +0900 Subject: [PATCH 11/16] Add build option for security issues Change-Id: I1b33f3daa27b7d81ea24798e45e47992cf9ecb80 --- packaging/gst-plugins-tizen.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 7fd2bf6..8922c14 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -69,7 +69,8 @@ GStreamer tizen plugins Extension for mobile TM1 %build -export CFLAGS+=" -DTIZEN_FEATURE_WLSINK_ENHANCEMENT -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" " +export CFLAGS+=" -DTIZEN_FEATURE_WLSINK_ENHANCEMENT -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" \ + -fstack-protector-strong -Wl,-z,relro -D_FORTIFY_SOURCE=2" export CFLAGS_DEFAULT="$CFLAGS" %ifarch %{arm} -- 2.7.4 From 5b2ce578239a3f42c6df6c93de79790f64835b7b Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Wed, 18 Apr 2018 14:32:13 +0900 Subject: [PATCH 12/16] [tizencamerasrc] Bug fix and update code [Version] 1.0.0-56 [Profile] Common [Issue Type] Bug fix [Dependency module] N/A Change-Id: I74283e73e46aed06e8f138678cc01838a4ad07b9 Signed-off-by: Jeongmo Yang --- packaging/gst-plugins-tizen.spec | 2 +- tizencamerasrc/src/camera_hal_interface.c | 10 ++-- tizencamerasrc/src/gsttizencamerasrc.c | 70 ++++++++++++++++++++--- tizencamerasrc/src/include/camera_hal_interface.h | 2 +- tizencamerasrc/src/include/gsttizencamerasrc.h | 5 ++ 5 files changed, 74 insertions(+), 15 deletions(-) diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 8922c14..79480ef 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,7 +9,7 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 55 +Release: 56 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ diff --git a/tizencamerasrc/src/camera_hal_interface.c b/tizencamerasrc/src/camera_hal_interface.c index 65f13de..bc77b6e 100644 --- a/tizencamerasrc/src/camera_hal_interface.c +++ b/tizencamerasrc/src/camera_hal_interface.c @@ -63,7 +63,7 @@ int camera_hal_interface_init(camera_hal_interface **h) if (tmp_h->dl_handle) { tmp_h->intf.init = dlsym(tmp_h->dl_handle, "camera_init"); tmp_h->intf.deinit = dlsym(tmp_h->dl_handle, "camera_deinit"); - tmp_h->intf.get_device_list = dlsym(tmp_h->dl_handle, "camera_get_device_list"); + tmp_h->intf.get_device_info_list = dlsym(tmp_h->dl_handle, "camera_get_device_info_list"); tmp_h->intf.open_device = dlsym(tmp_h->dl_handle, "camera_open_device"); tmp_h->intf.close_device = dlsym(tmp_h->dl_handle, "camera_close_device"); tmp_h->intf.add_message_callback = dlsym(tmp_h->dl_handle, "camera_add_message_callback"); @@ -151,7 +151,7 @@ int camera_hal_interface_deinit(camera_hal_interface *h) return CAMERA_ERROR_NONE; } -int camera_hal_interface_get_device_list(camera_hal_interface *h, camera_device_list_t *device_list) +int camera_hal_interface_get_device_info_list(camera_hal_interface *h, camera_device_info_list_t *device_info_list) { int ret = CAMERA_ERROR_NONE; @@ -160,10 +160,10 @@ int camera_hal_interface_get_device_list(camera_hal_interface *h, camera_device_ return CAMERA_ERROR_INVALID_PARAMETER; } - if (h->intf.get_device_list) { - ret = h->intf.get_device_list(h->hal_handle, device_list); + if (h->intf.get_device_info_list) { + ret = h->intf.get_device_info_list(device_info_list); } else { - LOGE("camera_get_device_list not implemented"); + LOGE("camera_get_device_info_list not implemented"); ret = CAMERA_ERROR_NOT_IMPLEMENTED; } diff --git a/tizencamerasrc/src/gsttizencamerasrc.c b/tizencamerasrc/src/gsttizencamerasrc.c index 194b473..8cfb263 100644 --- a/tizencamerasrc/src/gsttizencamerasrc.c +++ b/tizencamerasrc/src/gsttizencamerasrc.c @@ -146,7 +146,15 @@ static GstStaticPadTemplate src_factory = GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS("video/x-raw," - "format = (string) { NV12 }, " + "format = (string) { I420 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw," + "format = (string) { YV12 }, " + "width = (int) [ 1, 4096 ], " + "height = (int) [ 1, 4096 ]; " + "video/x-raw," + "format = (string) { YUYV }, " "width = (int) [ 1, 4096 ], " "height = (int) [ 1, 4096 ]; ")); @@ -344,23 +352,20 @@ static int _camera_preview_frame_cb(camera_buffer_t *buffer, camera_metadata_t * g_mutex_lock(&camerasrc->buffer_lock); if (!camerasrc->buffer_running) { GST_WARNING_OBJECT(camerasrc, "buffer is NOT running"); - g_mutex_unlock(&camerasrc->buffer_lock); - return FALSE; + goto _FRAME_CB_DONE; } /* create new buffer */ gst_buffer = gst_buffer_new_and_alloc(buffer->total_size); if (!gst_buffer) { GST_ERROR_OBJECT(camerasrc, "new buffer allocation failed. size %u", buffer->total_size); - g_mutex_unlock(&camerasrc->buffer_lock); - return FALSE; + goto _FRAME_CB_DONE; } if (!gst_buffer_map(gst_buffer, &map_info, GST_MAP_WRITE)) { GST_ERROR_OBJECT(camerasrc, "failed to map gst buffer %p", gst_buffer); gst_buffer_unref(gst_buffer); - g_mutex_unlock(&camerasrc->buffer_lock); - return FALSE; + goto _FRAME_CB_DONE; } /* copy buffer data */ @@ -370,14 +375,17 @@ static int _camera_preview_frame_cb(camera_buffer_t *buffer, camera_metadata_t * } gst_buffer_unmap(gst_buffer, &map_info); + gst_buffer_set_size(gst_buffer, buffer->total_size); /* add new buffer to preview buffer list */ g_queue_push_tail(camerasrc->preview_buffer_list, gst_buffer); - GST_DEBUG_OBJECT(camerasrc, "buffer index %d - gst buffer %p", buffer->index, gst_buffer); + GST_DEBUG_OBJECT(camerasrc, "index %d, %p [size total %d, copied %d]", + buffer->index, gst_buffer, buffer->total_size, copied_size); g_cond_signal(&camerasrc->buffer_cond); +_FRAME_CB_DONE: g_mutex_unlock(&camerasrc->buffer_lock); /* release preview buffer from camera HAL */ @@ -978,6 +986,13 @@ static GstFlowReturn gst_tizencamerasrc_read_preview(GstTizenCameraSrc *camerasr return GST_FLOW_ERROR; } + if (camerasrc->is_flushing) { + gst_buffer_unref(*buffer); + *buffer = NULL; + GST_INFO_OBJECT(camerasrc, "GST_FLOW_FLUSHING"); + return GST_FLOW_FLUSHING; + } + /* set timestamp and duration */ gst_tizencamerasrc_get_timeinfo(camerasrc, *buffer); @@ -1621,6 +1636,11 @@ static gboolean gst_tizencamerasrc_get_caps_info(GstTizenCameraSrc *camerasrc, G camerasrc->use_rotate_caps = TRUE; } + if (!gst_video_info_from_caps(&camerasrc->vinfo, caps)) { + GST_ERROR_OBJECT(camerasrc, "failed to get video info from caps"); + goto _caps_info_failed; + } + camerasrc->width = width; camerasrc->height = height; camerasrc->rotate = rotate; @@ -1772,6 +1792,38 @@ static gboolean gst_tizencamerasrc_set_caps(GstBaseSrc *src, GstCaps *caps) } +static gboolean gst_tizencamerasrc_unlock(GstBaseSrc *basesrc) +{ + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(basesrc); + + if (!camerasrc) { + GST_ERROR("NULL handle"); + return FALSE; + } + + GST_INFO_OBJECT(camerasrc, "flush start"); + + camerasrc->is_flushing = TRUE; + + return TRUE; +} + +static gboolean gst_tizencamerasrc_unlock_stop(GstBaseSrc *basesrc) +{ + GstTizenCameraSrc *camerasrc = GST_TIZENCAMERA_SRC(basesrc); + + if (!camerasrc) { + GST_ERROR("NULL handle"); + return FALSE; + } + + GST_INFO_OBJECT(camerasrc, "flush stop"); + + camerasrc->is_flushing = FALSE; + + return TRUE; +} + static void gst_tizencamerasrc_class_init(GstTizenCameraSrcClass *klass) { GST_DEBUG_CATEGORY_INIT(camerasrc_debug, "camerasrc", 0, "camerasrc element"); @@ -1803,6 +1855,8 @@ static void gst_tizencamerasrc_class_init(GstTizenCameraSrcClass *klass) basesrc_class->get_caps = gst_tizencamerasrc_get_caps; basesrc_class->set_caps = gst_tizencamerasrc_set_caps; basesrc_class->negotiate = gst_tizencamerasrc_negotiate; + basesrc_class->unlock = GST_DEBUG_FUNCPTR(gst_tizencamerasrc_unlock); + basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR(gst_tizencamerasrc_unlock_stop); pushsrc_class->create = gst_tizencamerasrc_src_create; g_object_class_install_property(gobject_class, ARG_CAMERA_HIGH_SPEED_FPS, diff --git a/tizencamerasrc/src/include/camera_hal_interface.h b/tizencamerasrc/src/include/camera_hal_interface.h index 3ab6179..084cc27 100644 --- a/tizencamerasrc/src/include/camera_hal_interface.h +++ b/tizencamerasrc/src/include/camera_hal_interface.h @@ -30,7 +30,7 @@ typedef struct _camera_hal_interface camera_hal_interface; int camera_hal_interface_init(camera_hal_interface **h); int camera_hal_interface_deinit(camera_hal_interface *h); -int camera_hal_interface_get_device_list(camera_hal_interface *h, camera_device_list_t *device_list); +int camera_hal_interface_get_device_info_list(camera_hal_interface *h, camera_device_info_list_t *device_info_list); int camera_hal_interface_open_device(camera_hal_interface *h, int device_index); int camera_hal_interface_close_device(camera_hal_interface *h); int camera_hal_interface_add_message_callback(camera_hal_interface *h, camera_message_cb callback, void *user_data, uint32_t *cb_id); diff --git a/tizencamerasrc/src/include/gsttizencamerasrc.h b/tizencamerasrc/src/include/gsttizencamerasrc.h index f7845dc..f87f91e 100644 --- a/tizencamerasrc/src/include/gsttizencamerasrc.h +++ b/tizencamerasrc/src/include/gsttizencamerasrc.h @@ -25,6 +25,7 @@ #define __GST_TIZENCAMERASRC_H__ #include +#include #include #include @@ -57,12 +58,16 @@ struct _GstTizenCameraSrc { GstPushSrc element; + /* Video info */ + GstVideoInfo vinfo; + /*private*/ camera_hal_interface *hal_intf_handle; /**< Camera HAL interface handle */ int mode; gboolean vflip; /**< flip camera input vertically */ gboolean hflip; /**< flip camera input horizontally */ gboolean firsttime; + gboolean is_flushing; int cap_count_current; /**< current capture count */ int cap_count_reverse; /**< current capture count (reverse counting) */ -- 2.7.4 From 9f0441fc9ce1f62cbc028580e14a11f596e9afb1 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Wed, 18 Apr 2018 16:46:03 +0900 Subject: [PATCH 13/16] tizenwlsink : remove unused code Change-Id: I33bc6f8aed675ccae39990b37922d5dbe517ed00 Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 133 --------------------------------------- tizenwlsink/src/wlwindow.c | 83 ------------------------ 2 files changed, 216 deletions(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index ab77c92..465e734 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -1799,25 +1799,6 @@ gst_tizen_wl_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) if (sink->window) gst_tizen_wl_sink_update_window_geometry (sink); -#else /*open source */ - /* create a new pool for the new configuration */ - newpool = gst_video_buffer_pool_new (); - if (!newpool) - goto pool_failed; - - structure = gst_buffer_pool_get_config (newpool); - gst_buffer_pool_config_set_params (structure, caps, info.size, 6, 0); - gst_buffer_pool_config_set_allocator (structure, - gst_tizen_wl_shm_allocator_get (), NULL); - if (!gst_buffer_pool_set_config (newpool, structure)) - goto config_failed; - - /* store the video info */ - sink->video_info = info; - sink->video_info_changed = TRUE; - - gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); - gst_object_unref (newpool); #endif return TRUE; @@ -1837,9 +1818,6 @@ unsupported_format: else /*USE SHM */ GST_DEBUG_OBJECT (sink, "Format %s is not available on the display", gst_wl_shm_format_to_string (format)); -#else /*open source */ - GST_DEBUG_OBJECT (sink, "Format %s is not available on the display", - gst_wl_shm_format_to_string (format)); #endif return FALSE; } @@ -2375,117 +2353,6 @@ gst_tizen_wl_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) goto done; -#else /* open source */ - - GstTizenWlSink *sink = GST_TIZEN_WL_SINK (bsink); - GstBuffer *to_render = NULL; - GstFlowReturn ret = GST_FLOW_OK; - - g_mutex_lock (&sink->render_lock); - - if (G_UNLIKELY (!sink->window)) { - /* ask for window handle. Unlock render_lock while doing that because - * set_window_handle & friends will lock it in this context */ - g_mutex_unlock (&sink->render_lock); - gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink)); - g_mutex_lock (&sink->render_lock); - - if (!sink->window) { - /* if we were not provided a window, create one ourselves */ - sink->window = - gst_wl_window_new_toplevel (sink->display, &sink->video_info); - } - } - - /* drop buffers until we get a frame callback */ - if (g_atomic_int_get (&sink->redraw_pending) == TRUE - && !gst_tizen_wl_sink_is_gapless (sink)) - goto done; - - /* make sure that the application has called set_render_rectangle() */ - if (G_UNLIKELY (sink->window->render_rectangle.w == 0)) - goto no_window_size; - - wlbuffer = gst_buffer_get_wl_buffer (buffer); - - if (G_LIKELY (wlbuffer && wlbuffer->display == sink->display)) { - GST_LOG_OBJECT (sink, - "buffer %p has a wl_buffer from our display, " "writing directly", - buffer); - GST_LOG ("wl_buffer (%p)", wlbuffer->wlbuffer); - to_render = buffer; - - } else { - GstMemory *mem; - struct wl_buffer *wbuf = NULL; - - GST_LOG_OBJECT (sink, - "buffer %p does not have a wl_buffer from our " "display, creating it", - buffer); - mem = gst_buffer_peek_memory (buffer, 0); - if (gst_is_wl_shm_memory (mem)) { /* is wayland memory */ - FUNCTION; - wbuf = gst_tizen_wl_shm_memory_construct_wl_buffer (mem, sink->display, - &sink->video_info); - } - if (wbuf) { - gst_buffer_add_wl_buffer (buffer, wbuf, sink->display); - to_render = buffer; - - } else { - GstMapInfo src; - /* we don't know how to create a wl_buffer directly from the provided - * memory, so we have to copy the data to a memory that we know how - * to handle... */ - - GST_LOG_OBJECT (sink, "buffer %p is not from our pool", buffer); - GST_LOG_OBJECT (sink, "buffer %p cannot have a wl_buffer, " "copying", - buffer); - /* sink->pool always exists (created in set_caps), but it may not - * be active if upstream is not using it */ - if (!gst_buffer_pool_is_active (sink->pool) && - !gst_buffer_pool_set_active (sink->pool, TRUE)) - goto activate_failed; - - ret = gst_buffer_pool_acquire_buffer (sink->pool, &to_render, NULL); - if (ret != GST_FLOW_OK) - goto no_buffer; - - /* the first time we acquire a buffer, - * we need to attach a wl_buffer on it */ - wlbuffer = gst_buffer_get_wl_buffer (buffer); - if (G_UNLIKELY (!wlbuffer)) { - mem = gst_buffer_peek_memory (to_render, 0); - wbuf = gst_tizen_wl_shm_memory_construct_wl_buffer (mem, sink->display, - &sink->video_info); - if (G_UNLIKELY (!wbuf)) - goto no_wl_buffer; - - gst_buffer_add_wl_buffer (to_render, wbuf, sink->display); - } - - gst_buffer_map (buffer, &src, GST_MAP_READ); - gst_buffer_fill (to_render, 0, src.data, src.size); - gst_buffer_unmap (buffer, &src); - } - } - /* drop double rendering */ - if (G_UNLIKELY (buffer == sink->last_buffer)) { - GST_LOG_OBJECT (sink, "Buffer already being rendered"); - goto done; - } - - gst_buffer_replace (&sink->last_buffer, to_render); - render_last_buffer (sink); - - if (buffer != to_render) - gst_buffer_unref (to_render); - - goto done; - -#endif /* TIZEN_FEATURE_WLSINK_ENHANCEMENT */ - -#ifndef TIZEN_FEATURE_WLSINK_ENHANCEMENT no_window_size: { GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, diff --git a/tizenwlsink/src/wlwindow.c b/tizenwlsink/src/wlwindow.c index ab115fd..c8333e6 100644 --- a/tizenwlsink/src/wlwindow.c +++ b/tizenwlsink/src/wlwindow.c @@ -496,23 +496,6 @@ gst_wl_window_new_in_surface (GstWlDisplay * display, window->video_subsurface); } return window; - -#else /* open source */ - - GstWlWindow *window; - window = gst_wl_window_new_internal (display, parent); //add parent for enlightment - - /*for enlightment , move to gst_wl_window_new_internal() */ -#if 0 - /* embed in parent */ - window->area_subsurface = - wl_subcompositor_get_subsurface (display->subcompositor, - window->area_surface, parent); - wl_subsurface_set_desync (window->area_subsurface); -#endif - - return window; - #endif } @@ -905,38 +888,6 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, } wl_display_flush (window->display->display); - -#else /* open source */ - - if (G_UNLIKELY (info)) { - window->video_width = - gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); - window->video_height = info->height; - - wl_subsurface_set_sync (window->video_subsurface); - gst_wl_window_resize_video_surface (window, FALSE); - } - - GST_LOG ("GstWlBuffer(%p)", buffer); - if (G_LIKELY (buffer)) - gst_wl_buffer_attach (buffer, window->video_surface); - else - wl_surface_attach (window->video_surface, NULL, 0, 0); - - wl_surface_damage (window->video_surface, 0, 0, window->surface_width, - window->surface_height); - wl_surface_commit (window->video_surface); - - if (G_UNLIKELY (info)) { - /* commit also the parent (area_surface) in order to change - * the position of the video_subsurface */ - wl_surface_damage (window->area_surface, 0, 0, window->render_rectangle.w, - window->render_rectangle.h); - wl_surface_commit (window->area_surface); - wl_subsurface_set_desync (window->video_subsurface); - } - - wl_display_flush (window->display->display); #endif } @@ -962,41 +913,7 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, return TRUE; } -#else /* open source */ -void -gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, - gint w, gint h) -{ - - g_return_if_fail (window != NULL); - - window->render_rectangle.x = x; - window->render_rectangle.y = y; - window->render_rectangle.w = w; - window->render_rectangle.h = h; - - /* position the area inside the parent - needs a parent commit to apply */ - if (window->area_subsurface) - wl_subsurface_set_position (window->area_subsurface, x, y); - - /* change the size of the area */ - wl_viewport_set_destination (window->area_viewport, w, h); - - if (window->video_width != 0) { - wl_subsurface_set_sync (window->video_subsurface); - gst_wl_window_resize_video_surface (window, TRUE); - } - - wl_surface_damage (window->area_surface, 0, 0, w, h); - wl_surface_commit (window->area_surface); - - if (window->video_width != 0) - wl_subsurface_set_desync (window->video_subsurface); - -} -#endif -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT void gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle) { -- 2.7.4 From d2522b0baa0e3db7b17de26505cd9ad3d1dd42ab Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Thu, 26 Apr 2018 18:05:33 +0900 Subject: [PATCH 14/16] [tizencamerasrc] Update build settings - Remove camera_hal_interface.* sources from tizencamerasrc - Change build requirement - Remove unused dependency [Version] 1.0.0-57 [Profile] Common [Issue Type] Update [Dependency module] mm-hal-interface Change-Id: I36b4492b96e0342a4d581803ccba91fe8b07063a Signed-off-by: Jeongmo Yang --- configure.ac | 6 +- packaging/gst-plugins-tizen.spec | 5 +- tizencamerasrc/src/Makefile.am | 7 +- tizencamerasrc/src/camera_hal_interface.c | 570 ---------------------- tizencamerasrc/src/include/camera_hal_interface.h | 54 -- 5 files changed, 8 insertions(+), 634 deletions(-) delete mode 100644 tizencamerasrc/src/camera_hal_interface.c delete mode 100644 tizencamerasrc/src/include/camera_hal_interface.h diff --git a/configure.ac b/configure.ac index 17703ba..0c91739 100644 --- a/configure.ac +++ b/configure.ac @@ -451,9 +451,9 @@ AC_ARG_ENABLE(tizencamerasrc, AC_HELP_STRING([--enable-tizencamerasrc], [using t [GST_TIZEN_USE_TIZENCAMERASRC=yes]) AM_CONDITIONAL([GST_TIZEN_USE_TIZENCAMERASRC], [test "x$GST_TIZEN_USE_TIZENCAMERASRC" = "xyes"]) if test "x$GST_TIZEN_USE_TIZENCAMERASRC" = "xyes"; then -PKG_CHECK_MODULES(DLOG, dlog) -AC_SUBST(DLOG_CFLAGS) -AC_SUBST(DLOG_LIBS) +PKG_CHECK_MODULES(CAMERA_HAL_INTERFACE, camera-hal-interface) +AC_SUBST(CAMERA_HAL_INTERFACE_CFLAGS) +AC_SUBST(CAMERA_HAL_INTERFACE_LIBS) fi AC_OUTPUT( diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 79480ef..cbad4bb 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,7 +9,7 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 56 +Release: 57 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ @@ -44,8 +44,7 @@ BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(tizen-extension-client) %endif # for tizencamerasrc -#BuildRequires: pkgconfig(dlog) -#BuildRequires: mm-hal-interface +#BuildRequires: pkgconfig(camera-hal-interface) %description GStreamer tizen plugins (common) diff --git a/tizencamerasrc/src/Makefile.am b/tizencamerasrc/src/Makefile.am index 4396a7d..b9642f8 100644 --- a/tizencamerasrc/src/Makefile.am +++ b/tizencamerasrc/src/Makefile.am @@ -5,25 +5,24 @@ plugin_LTLIBRARIES = libgsttizencamerasrc.la # sources used to compile this plug-in libgsttizencamerasrc_la_SOURCES = gsttizencamerasrc.c \ gsttizencamerasrccontrol.c \ - gsttizencamerasrccolorbalance.c \ - camera_hal_interface.c + gsttizencamerasrccolorbalance.c libgsttizencamerasrc_la_CFLAGS = -I$(srcdir)/include \ + $(CAMERA_HAL_INTERFACE_CFLAGS) \ $(GST_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(GST_VIDEO_FLAGS) \ $(MMCOMMON_CFLAGS) \ $(MMUTIL_JPEG_CFLAGS) \ - $(DLOG_CFLAGS) \ $(TBM_CFLAGS) libgsttizencamerasrc_la_LIBADD = -ldl -lpthread -lrt -lm \ + $(CAMERA_HAL_INTERFACE_LIBS) \ $(GST_LIBS) \ $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ $(MMCOMMON_LIBS) \ $(MMUTIL_JPEG_LIBS) \ - $(DLOG_LIBS) \ $(TBM_LIBS) libgsttizencamerasrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/tizencamerasrc/src/camera_hal_interface.c b/tizencamerasrc/src/camera_hal_interface.c deleted file mode 100644 index bc77b6e..0000000 --- a/tizencamerasrc/src/camera_hal_interface.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * camera_hal_interface.c - * - * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Jeongmo Yang - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "camera_hal_interface.h" - -#ifdef LOG_TAG -#undef LOG_TAG -#endif /* LOG_TAG */ -#define LOG_TAG "CAMERA_HAL_INTF" - -#define LIB_TIZEN_CAMERA "libtizen-camera.so" - -struct _camera_hal_interface { - void *dl_handle; - void *hal_handle; - camera_interface_t intf; -}; - -int camera_hal_interface_init(camera_hal_interface **h) -{ - int ret = CAMERA_ERROR_NONE; - camera_hal_interface *tmp_h = NULL; - - if (h == NULL) { - LOGE("invalid parameter for camera_hal_interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - tmp_h = g_new0(camera_hal_interface, 1); - if (tmp_h == NULL) { - LOGE("failed to allocate hal interface"); - return CAMERA_ERROR_OUT_OF_MEMORY; - } - - tmp_h->dl_handle = dlopen(LIB_TIZEN_CAMERA, RTLD_NOW); - if (tmp_h->dl_handle) { - tmp_h->intf.init = dlsym(tmp_h->dl_handle, "camera_init"); - tmp_h->intf.deinit = dlsym(tmp_h->dl_handle, "camera_deinit"); - tmp_h->intf.get_device_info_list = dlsym(tmp_h->dl_handle, "camera_get_device_info_list"); - tmp_h->intf.open_device = dlsym(tmp_h->dl_handle, "camera_open_device"); - tmp_h->intf.close_device = dlsym(tmp_h->dl_handle, "camera_close_device"); - tmp_h->intf.add_message_callback = dlsym(tmp_h->dl_handle, "camera_add_message_callback"); - tmp_h->intf.remove_message_callback = dlsym(tmp_h->dl_handle, "camera_remove_message_callback"); - tmp_h->intf.set_preview_stream_format = dlsym(tmp_h->dl_handle, "camera_set_preview_stream_format"); - tmp_h->intf.get_preview_stream_format = dlsym(tmp_h->dl_handle, "camera_get_preview_stream_format"); - tmp_h->intf.start_preview = dlsym(tmp_h->dl_handle, "camera_start_preview"); - tmp_h->intf.release_preview_buffer = dlsym(tmp_h->dl_handle, "camera_release_preview_buffer"); - tmp_h->intf.stop_preview = dlsym(tmp_h->dl_handle, "camera_stop_preview"); - tmp_h->intf.start_auto_focus = dlsym(tmp_h->dl_handle, "camera_start_auto_focus"); - tmp_h->intf.stop_auto_focus = dlsym(tmp_h->dl_handle, "camera_stop_auto_focus"); - tmp_h->intf.start_capture = dlsym(tmp_h->dl_handle, "camera_start_capture"); - tmp_h->intf.stop_capture = dlsym(tmp_h->dl_handle, "camera_stop_capture"); - tmp_h->intf.set_video_stream_format = dlsym(tmp_h->dl_handle, "camera_set_video_stream_format"); - tmp_h->intf.get_video_stream_format = dlsym(tmp_h->dl_handle, "camera_get_video_stream_format"); - tmp_h->intf.start_record = dlsym(tmp_h->dl_handle, "camera_start_record"); - tmp_h->intf.release_video_buffer = dlsym(tmp_h->dl_handle, "camera_release_video_buffer"); - tmp_h->intf.stop_record = dlsym(tmp_h->dl_handle, "camera_stop_record"); - tmp_h->intf.set_command = dlsym(tmp_h->dl_handle, "camera_set_command"); - tmp_h->intf.get_command = dlsym(tmp_h->dl_handle, "camera_get_command"); - tmp_h->intf.set_batch_command = dlsym(tmp_h->dl_handle, "camera_set_batch_command"); - - if (tmp_h->intf.init == NULL || tmp_h->intf.deinit == NULL) { - LOGE("could not get mandatory function. %p %1p", tmp_h->intf.init, tmp_h->intf.deinit); - ret = CAMERA_ERROR_INTERNAL; - goto _CAMERA_HAL_INTERFACE_GET_FAILED; - } - - if (tmp_h->intf.init) { - ret = tmp_h->intf.init(&tmp_h->hal_handle); - if (ret != CAMERA_ERROR_NONE) { - LOGE("camera_init failed 0x%x", ret); - goto _CAMERA_HAL_INTERFACE_GET_FAILED; - } - } else { - LOGE("no camera_init function"); - ret = CAMERA_ERROR_INTERNAL; - goto _CAMERA_HAL_INTERFACE_GET_FAILED; - } - } else { - LOGE("dlopen failed [%s]", LIB_TIZEN_CAMERA); - ret = CAMERA_ERROR_INTERNAL; - goto _CAMERA_HAL_INTERFACE_GET_FAILED; - } - - *h = tmp_h; - - return ret; - -_CAMERA_HAL_INTERFACE_GET_FAILED: - if (tmp_h) { - if (tmp_h->dl_handle) - dlclose(tmp_h->dl_handle); - - g_free(tmp_h); - } - - return ret; -} - -int camera_hal_interface_deinit(camera_hal_interface *h) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->dl_handle) { - ret = h->intf.deinit(h->hal_handle); - if (ret != CAMERA_ERROR_NONE) { - LOGE("camera_deinit failed 0x%x", ret); - return ret; - } - - h->hal_handle = NULL; - - dlclose(h->dl_handle); - h->dl_handle = NULL; - } - - g_free(h); - - return CAMERA_ERROR_NONE; -} - -int camera_hal_interface_get_device_info_list(camera_hal_interface *h, camera_device_info_list_t *device_info_list) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.get_device_info_list) { - ret = h->intf.get_device_info_list(device_info_list); - } else { - LOGE("camera_get_device_info_list not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_open_device(camera_hal_interface *h, int device_index) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.open_device) { - ret = h->intf.open_device(h->hal_handle, device_index); - } else { - LOGE("camera_open_device not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_close_device(camera_hal_interface *h) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.close_device) { - ret = h->intf.close_device(h->hal_handle); - } else { - LOGE("camera_close_device not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_add_message_callback(camera_hal_interface *h, camera_message_cb callback, void *user_data, uint32_t *cb_id) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.add_message_callback) { - ret = h->intf.add_message_callback(h->hal_handle, callback, user_data, cb_id); - } else { - LOGE("camera_add_message_callback not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_remove_message_callback(camera_hal_interface *h, uint32_t cb_id) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.remove_message_callback) { - ret = h->intf.remove_message_callback(h->hal_handle, cb_id); - } else { - LOGE("camera_remove_message_callback not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_set_preview_stream_format(camera_hal_interface *h, camera_format_t *format) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.set_preview_stream_format) { - ret = h->intf.set_preview_stream_format(h->hal_handle, format); - } else { - LOGE("camera_set_preview_stream_format not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_get_preview_stream_format(camera_hal_interface *h, camera_format_t *format) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.get_preview_stream_format) { - ret = h->intf.get_preview_stream_format(h->hal_handle, format); - } else { - LOGE("camera_get_preview_stream_format not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_start_preview(camera_hal_interface *h, camera_preview_frame_cb callback, void *user_data) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.start_preview) { - ret = h->intf.start_preview(h->hal_handle, callback, user_data); - } else { - LOGE("camera_start_preview not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_release_preview_buffer(camera_hal_interface *h, int buffer_index) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.release_preview_buffer) { - ret = h->intf.release_preview_buffer(h->hal_handle, buffer_index); - } else { - LOGE("camera_release_preview_buffer not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_stop_preview(camera_hal_interface *h) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.stop_preview) { - ret = h->intf.stop_preview(h->hal_handle); - } else { - LOGE("camera_stop_preview not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_start_auto_focus(camera_hal_interface *h) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.start_auto_focus) { - ret = h->intf.start_auto_focus(h->hal_handle); - } else { - LOGE("camera_start_auto_focus not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_stop_auto_focus(camera_hal_interface *h) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.stop_auto_focus) { - ret = h->intf.stop_auto_focus(h->hal_handle); - } else { - LOGE("camera_stop_auto_focus not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_start_capture(camera_hal_interface *h, camera_capture_cb callback, void *user_data) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.start_capture) { - ret = h->intf.start_capture(h->hal_handle, callback, user_data); - } else { - LOGE("camera_start_capture not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_stop_capture(camera_hal_interface *h) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.stop_capture) { - ret = h->intf.stop_capture(h->hal_handle); - } else { - LOGE("camera_stop_capture not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_set_video_stream_format(camera_hal_interface *h, camera_format_t *format) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.set_video_stream_format) { - ret = h->intf.set_video_stream_format(h->hal_handle, format); - } else { - LOGE("camera_set_video_stream_format not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_get_video_stream_format(camera_hal_interface *h, camera_format_t *format) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.get_video_stream_format) { - ret = h->intf.get_video_stream_format(h->hal_handle, format); - } else { - LOGE("camera_get_video_stream_format not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_start_record(camera_hal_interface *h, camera_video_frame_cb callback, void *user_data) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.start_record) { - ret = h->intf.start_record(h->hal_handle, callback, user_data); - } else { - LOGE("camera_start_record not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_release_video_buffer(camera_hal_interface *h, int buffer_index) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.release_video_buffer) { - ret = h->intf.release_video_buffer(h->hal_handle, buffer_index); - } else { - LOGE("camera_release_video_buffer not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_stop_record(camera_hal_interface *h) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.stop_record) { - ret = h->intf.stop_record(h->hal_handle); - } else { - LOGE("camera_stop_record not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_set_command(camera_hal_interface *h, int64_t command, void *value) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.set_command) { - ret = h->intf.set_command(h->hal_handle, command, value); - } else { - LOGE("camera_set_command not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_get_command(camera_hal_interface *h, int64_t command, void *value) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.get_command) { - ret = h->intf.get_command(h->hal_handle, command, value); - } else { - LOGE("camera_get_command not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} - -int camera_hal_interface_set_batch_command(camera_hal_interface *h, camera_batch_command_control_t *batch_command, int64_t *error_command) -{ - int ret = CAMERA_ERROR_NONE; - - if (h == NULL) { - LOGE("NULL interface"); - return CAMERA_ERROR_INVALID_PARAMETER; - } - - if (h->intf.set_batch_command) { - ret = h->intf.set_batch_command(h->hal_handle, batch_command, error_command); - } else { - LOGE("camera_set_batch_command not implemented"); - ret = CAMERA_ERROR_NOT_IMPLEMENTED; - } - - return ret; -} diff --git a/tizencamerasrc/src/include/camera_hal_interface.h b/tizencamerasrc/src/include/camera_hal_interface.h deleted file mode 100644 index 084cc27..0000000 --- a/tizencamerasrc/src/include/camera_hal_interface.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * camera_hal_interface.h - * - * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Jeongmo Yang - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#include - - - -typedef struct _camera_hal_interface camera_hal_interface; - -int camera_hal_interface_init(camera_hal_interface **h); -int camera_hal_interface_deinit(camera_hal_interface *h); -int camera_hal_interface_get_device_info_list(camera_hal_interface *h, camera_device_info_list_t *device_info_list); -int camera_hal_interface_open_device(camera_hal_interface *h, int device_index); -int camera_hal_interface_close_device(camera_hal_interface *h); -int camera_hal_interface_add_message_callback(camera_hal_interface *h, camera_message_cb callback, void *user_data, uint32_t *cb_id); -int camera_hal_interface_remove_message_callback(camera_hal_interface *h, uint32_t cb_id); -int camera_hal_interface_set_preview_stream_format(camera_hal_interface *h, camera_format_t *format); -int camera_hal_interface_get_preview_stream_format(camera_hal_interface *h, camera_format_t *format); -int camera_hal_interface_start_preview(camera_hal_interface *h, camera_preview_frame_cb callback, void *user_data); -int camera_hal_interface_release_preview_buffer(camera_hal_interface *h, int buffer_index); -int camera_hal_interface_stop_preview(camera_hal_interface *h); -int camera_hal_interface_start_auto_focus(camera_hal_interface *h); -int camera_hal_interface_stop_auto_focus(camera_hal_interface *h); -int camera_hal_interface_start_capture(camera_hal_interface *h, camera_capture_cb callback, void *user_data); -int camera_hal_interface_stop_capture(camera_hal_interface *h); -int camera_hal_interface_set_video_stream_format(camera_hal_interface *h, camera_format_t *format); -int camera_hal_interface_get_video_stream_format(camera_hal_interface *h, camera_format_t *format); -int camera_hal_interface_start_record(camera_hal_interface *h, camera_video_frame_cb callback, void *user_data); -int camera_hal_interface_release_video_buffer(camera_hal_interface *h, int buffer_index); -int camera_hal_interface_stop_record(camera_hal_interface *h); -int camera_hal_interface_set_command(camera_hal_interface *h, int64_t command, void *value); -int camera_hal_interface_get_command(camera_hal_interface *h, int64_t command, void *value); -int camera_hal_interface_set_batch_command(camera_hal_interface *h, camera_batch_command_control_t *batch_command, int64_t *error_command); -- 2.7.4 From 728becfdd53adedd2fdd5cd80a3721fb464f8d67 Mon Sep 17 00:00:00 2001 From: SeokHoon Lee Date: Thu, 26 Apr 2018 13:10:37 +0900 Subject: [PATCH 15/16] Change malloc to g_malloc - malloc has changed to g_malloc - add null check routine Signed-off-by: SeokHoon Lee Change-Id: Idb2eea4312092f519e35be167a9292d5ae462b1f --- wfdmanager/wfdsrc/gstwfdsrc.c | 105 ++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 70 deletions(-) diff --git a/wfdmanager/wfdsrc/gstwfdsrc.c b/wfdmanager/wfdsrc/gstwfdsrc.c index b45cb87..7ff2b46 100644 --- a/wfdmanager/wfdsrc/gstwfdsrc.c +++ b/wfdmanager/wfdsrc/gstwfdsrc.c @@ -1050,13 +1050,14 @@ gst_wfd_src_prepare_tcp (GstWFDBaseSrc *bsrc, gint rtpport) static GstFlowReturn gst_wfd_src_loop_tcp (GstWFDSrc *src) { +#define RTSP_HEADER_SIZE 4 GstRTSPResult res; GstPad *outpad = NULL; GstFlowReturn ret = GST_FLOW_OK; - guint8 *sizedata, *datatmp; - gint message_size_length = 2, message_size; + guint8 *rtsp_message; + gint message_size; + guint8 rtsp_header[RTSP_HEADER_SIZE]; GstBuffer *buf; - GstMapInfo map; GTimeVal tv_timeout; if (!src->tcp_connection) @@ -1071,86 +1072,50 @@ gst_wfd_src_loop_tcp (GstWFDSrc *src) tv_timeout.tv_sec, tv_timeout.tv_usec); } - /* Read 2 bytes message type in begining */ - sizedata = (guint8 *)malloc (message_size_length); - if((res = gst_rtsp_connection_read (src->tcp_connection,sizedata, message_size_length, &tv_timeout)) - !=GST_RTSP_OK){ - ret = GST_FLOW_ERROR; - switch (res) { - case GST_RTSP_EINTR: - { - GST_ERROR ("Got interrupted\n"); - if (src->tcp_connection) - gst_rtsp_connection_flush (src->tcp_connection, FALSE); - break; - } - default: - { - GST_ERROR ("Got error %d\n", res); - break; - } + /* Read 2 bytes message type + 2 bytes message size in begining */ + res = gst_rtsp_connection_read (src->tcp_connection, rtsp_header, RTSP_HEADER_SIZE, &tv_timeout); + + if (res != GST_RTSP_OK) { + + if (res == GST_RTSP_EINTR) { + GST_ERROR ("Got interrupted\n"); + gst_rtsp_connection_flush (src->tcp_connection, FALSE); } - g_free(sizedata); - return ret; + + GST_ERROR ("Got error %d\n", res); + return GST_FLOW_ERROR; } - /*In rtp message over TCP the first 2 bytes are message size. - * * So firtstly read rtp message size.*/ - if((res = gst_rtsp_connection_read (src->tcp_connection,sizedata, message_size_length, &tv_timeout)) - !=GST_RTSP_OK){ - ret = GST_FLOW_ERROR; - switch (res) { - case GST_RTSP_EINTR: - { - GST_ERROR ("Got interrupted\n"); - if (src->tcp_connection) - gst_rtsp_connection_flush (src->tcp_connection, FALSE); - break; - } - default: - { - GST_ERROR ("Got error %d\n", res); - break; - } - } - g_free(sizedata); - return ret; + + message_size = ((guint)rtsp_header[2] << 8) | rtsp_header[3]; + + rtsp_message = g_malloc (message_size); + if (rtsp_message == NULL) { + GST_ERROR ("Out of memory for rtsp_message, size = %d\n", message_size); + return GST_FLOW_ERROR; } - message_size = ((guint)sizedata[0] << 8) | sizedata[1]; - datatmp = (guint8 *) malloc (message_size); - g_free(sizedata); - if((res = gst_rtsp_connection_read (src->tcp_connection,datatmp,message_size, &tv_timeout)) - !=GST_RTSP_OK){ - ret = GST_FLOW_ERROR; - switch (res) { - case GST_RTSP_EINTR: - { - GST_ERROR ("Got interrupted\n"); - if (src->tcp_connection) - gst_rtsp_connection_flush (src->tcp_connection, FALSE); - break; - } - default: - { - GST_ERROR ("Got error %d\n", res); - break; - } + res = gst_rtsp_connection_read (src->tcp_connection, rtsp_message, message_size, &tv_timeout); + + if (res != GST_RTSP_OK) { + + if (res == GST_RTSP_EINTR) { + GST_ERROR ("Got interrupted\n"); + gst_rtsp_connection_flush (src->tcp_connection, FALSE); } - g_free(datatmp); - return ret; + + GST_ERROR ("Got error %d\n", res); + g_free(rtsp_message); + return GST_FLOW_ERROR; } /*first byte of data is type of payload * * 200 is rtcp type then we need other pad*/ - if(datatmp[0] == 200) + if (rtsp_message[0] == 200) outpad = src->channelpad[1]; else outpad = src->channelpad[0]; - buf = gst_buffer_new_wrapped(datatmp, message_size); - gst_buffer_map(buf, &map, GST_MAP_READ); - - gst_buffer_unmap(buf, &map); + buf = gst_buffer_new_wrapped (rtsp_message, message_size); if (src->discont) { GstClockTime now; -- 2.7.4 From b79d4b3c0b4bea1d99f8e9a241362b3d12756aaf Mon Sep 17 00:00:00 2001 From: Hyunil Date: Thu, 3 May 2018 15:28:49 +0900 Subject: [PATCH 16/16] tizenwlsink: wlbuffer point check for mapping sub surface (fix coverity issue) Change-Id: I40aac6a686da3dd36de77c9bb1c6228320434035 Signed-off-by: Hyunil --- tizenwlsink/src/wlwindow.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tizenwlsink/src/wlwindow.c b/tizenwlsink/src/wlwindow.c index c8333e6..b2b934a 100644 --- a/tizenwlsink/src/wlwindow.c +++ b/tizenwlsink/src/wlwindow.c @@ -145,9 +145,15 @@ gst_wl_window_map_sub_surface (GstWlDisplay * display, GstWlWindow * window, gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE); *((guint32 *) mapinfo.data) = 0; /* paint it black */ gst_buffer_unmap (buf, &mapinfo); + wlbuf = gst_tizen_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0), display, info); + if (G_UNLIKELY (!wlbuf)) { + GST_ERROR ("could not create wl_buffer"); + gst_buffer_unref (buf); + return; + } gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display); gst_wl_buffer_attach (gwlbuf, window->area_surface); -- 2.7.4