summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongmo Yang <jm80.yang@samsung.com>2017-08-17 16:07:58 +0900
committerJeongmo Yang <jm80.yang@samsung.com>2017-08-17 16:11:47 +0900
commit3aaa3dcd087e79230b6ba1894ab0ac9a9971b3a1 (patch)
treefa61e3d8073a6285dfa50e3b8b9205a5a5ded729
parent0256378c32c32155ddd89addb1f7c98e5fb4f8eb (diff)
parenta598a58d1798e098826b090c905660393fa0b7c7 (diff)
downloadcamera-3aaa3dcd087e79230b6ba1894ab0ac9a9971b3a1.tar.gz
camera-3aaa3dcd087e79230b6ba1894ab0ac9a9971b3a1.tar.bz2
camera-3aaa3dcd087e79230b6ba1894ab0ac9a9971b3a1.zip
Merge branch 'tizen' into tizen_line_coverage
Change-Id: I879e8ad7021fe3942aaa2e02d320d8e3880fe4d7 Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r--include/camera.h49
-rw-r--r--include/camera_private.h1
-rw-r--r--packaging/capi-media-camera.spec2
-rw-r--r--src/camera.c98
-rw-r--r--test/camera_test.c86
5 files changed, 192 insertions, 44 deletions
diff --git a/include/camera.h b/include/camera.h
index 5a8933c..a221fa1 100644
--- a/include/camera.h
+++ b/include/camera.h
@@ -549,6 +549,7 @@ typedef void (*camera_device_state_changed_cb)(camera_device_e device, camera_de
/**
* @brief Called when the camera is interrupted by policy.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @remarks This callback is called after interrupt handling is completed.
* @param[in] policy The policy that interrupted the camera
* @param[in] previous The previous state of the camera
* @param[in] current The current state of the camera
@@ -558,6 +559,17 @@ typedef void (*camera_device_state_changed_cb)(camera_device_e device, camera_de
typedef void (*camera_interrupted_cb)(camera_policy_e policy, camera_state_e previous, camera_state_e current, void *user_data);
/**
+ * @brief Called when the camera interrupt is started by policy.
+ * @since_tizen 4.0
+ * @remarks This callback is called before interrupt handling is started.
+ * @param[in] policy The policy that is interrupting the camera
+ * @param[in] state The current state of the camera
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see camera_set_interrupt_started_cb()
+ */
+typedef void (*camera_interrupt_started_cb)(camera_policy_e policy, camera_state_e state, void *user_data);
+
+/**
* @brief Called when the camera focus state is changed.
* @details When the camera auto focus completes or a change to the focus state occurs,
* this callback is invoked. \n \n
@@ -1719,7 +1731,9 @@ bool camera_is_supported_media_packet_preview_cb(camera_h camera);
* @brief Registers a callback function to be called once per frame when previewing.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
* @remarks This callback does not work in the video recorder mode.\n
- * This function should be called before previewing (see camera_start_preview()).\n
+ * Before 4.0, the only allowed state for calling this function was #CAMERA_STATE_CREATED.\n
+ * Since 4.0, #CAMERA_STATE_PREVIEW has been added as an allowed state,\n
+ * so that this function could be called before previewing or even while previewing.\n
* A registered callback is called on the internal thread of the camera.\n
* A video frame can be retrieved using a registered callback,\n
* and the buffer is only available in a registered callback.\n
@@ -1736,9 +1750,10 @@ bool camera_is_supported_media_packet_preview_cb(camera_h camera);
* @retval #CAMERA_ERROR_PERMISSION_DENIED The access to the resources can not be granted
* @retval #CAMERA_ERROR_NOT_SUPPORTED The feature is not supported
* @retval #CAMERA_ERROR_SERVICE_DISCONNECTED The socket to multimedia server is disconnected
- * @pre The camera's state must be set to #CAMERA_STATE_CREATED.
+ * @pre Before 4.0 : The camera state must be set to #CAMERA_STATE_CREATED.\n
+ * Since 4.0 : The camera state must be set to #CAMERA_STATE_CREATED or #CAMERA_STATE_PREVIEW.
* @see camera_start_preview()
- * @see camera_unset_preview_cb()
+ * @see camera_unset_preview_cb()
* @see camera_preview_cb()
*/
int camera_set_preview_cb(camera_h camera, camera_preview_cb callback, void *user_data);
@@ -1844,8 +1859,7 @@ int camera_unset_state_changed_cb(camera_h camera);
* @see camera_unset_interrupted_cb()
* @see camera_interrupted_cb()
*/
-int camera_set_interrupted_cb(camera_h camera, camera_interrupted_cb callback,
- void *user_data);
+int camera_set_interrupted_cb(camera_h camera, camera_interrupted_cb callback, void *user_data);
/**
* @brief Unregisters the callback function.
@@ -1862,6 +1876,31 @@ int camera_set_interrupted_cb(camera_h camera, camera_interrupted_cb callback,
int camera_unset_interrupted_cb(camera_h camera);
/**
+ * @brief Registers a callback function to be called when the camera interrupt is started by policy.
+ * @since_tizen 4.0
+ * @param[in] camera The handle to the camera
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #CAMERA_ERROR_NONE Successful
+ * @retval #CAMERA_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see camera_unset_interrupt_started_cb()
+ * @see camera_interrupt_started_cb()
+ */
+int camera_set_interrupt_started_cb(camera_h camera, camera_interrupt_started_cb callback, void *user_data);
+
+/**
+ * @brief Unregisters the callback function.
+ * @since_tizen 4.0
+ * @param[in] camera The handle to the camera
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #CAMERA_ERROR_NONE Successful
+ * @retval #CAMERA_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see camera_set_interrupt_started_cb()
+ */
+int camera_unset_interrupt_started_cb(camera_h camera);
+
+/**
* @brief Registers a callback function to be called when the auto-focus state changes.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
* @param[in] camera The handle to the camera
diff --git a/include/camera_private.h b/include/camera_private.h
index 0fa2f77..582d3d3 100644
--- a/include/camera_private.h
+++ b/include/camera_private.h
@@ -147,6 +147,7 @@ typedef struct _camera_cb_info_s {
/* preview callback flag */
int preview_cb_flag;
+ GMutex preview_cb_mutex;
/* evas surface */
#ifdef TIZEN_FEATURE_EVAS_RENDERER
diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec
index 2a3b0e4..8df44b2 100644
--- a/packaging/capi-media-camera.spec
+++ b/packaging/capi-media-camera.spec
@@ -1,6 +1,6 @@
Name: capi-media-camera
Summary: A Camera API
-Version: 0.3.0
+Version: 0.3.3
Release: 0
Group: Multimedia/API
License: Apache-2.0
diff --git a/src/camera.c b/src/camera.c
index 8f063b1..e61714c 100644
--- a/src/camera.c
+++ b/src/camera.c
@@ -1248,6 +1248,8 @@ static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_m
}
/* call preview callback */
+ g_mutex_lock(&cb_info->preview_cb_mutex);
+
if (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW]) {
_camera_preview_frame_create(stream, num_buffer_key, buffer_bo_handle, &data_bo_handle, &frame);
@@ -1255,6 +1257,8 @@ static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_m
cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_PREVIEW]);
}
+ g_mutex_unlock(&cb_info->preview_cb_mutex);
+
if (CHECK_PREVIEW_CB(cb_info, PREVIEW_CB_TYPE_EVAS)) {
#ifdef TIZEN_FEATURE_EVAS_RENDERER
ret = _camera_media_packet_data_create(tbm_key, num_buffer_key, bo, buffer_bo, data_bo, &mp_data);
@@ -1360,6 +1364,27 @@ static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_m
(camera_state_e)previous, (camera_state_e)current, cb_info->user_data[event]);
}
break;
+ case MUSE_CAMERA_EVENT_TYPE_INTERRUPT_STARTED:
+ {
+ int policy = 0;
+ int state = 0;
+
+ muse_camera_msg_get(policy, recv_msg);
+ muse_camera_msg_get(state, recv_msg);
+
+ LOGW("INTERRUPT_STARTED - policy %d, state %d", policy, state);
+
+ if (policy == CAMERA_POLICY_SOUND)
+ LOGW("DEPRECATION WARNING: CAMERA_POLICY_SOUND is deprecated and will be removed from next release.");
+ else if (policy == CAMERA_POLICY_SOUND_BY_CALL)
+ LOGW("DEPRECATION WARNING: CAMERA_POLICY_SOUND_BY_CALL is deprecated and will be removed from next release.");
+ else if (policy == CAMERA_POLICY_SOUND_BY_ALARM)
+ LOGW("DEPRECATION WARNING: CAMERA_POLICY_SOUND_BY_ALARM is deprecated and will be removed from next release.");
+
+ ((camera_interrupt_started_cb)cb_info->user_cb[event])((camera_policy_e)policy,
+ (camera_state_e)state, cb_info->user_data[event]);
+ }
+ break;
case MUSE_CAMERA_EVENT_TYPE_FACE_DETECTION:
{
int count = 0;
@@ -1575,8 +1600,8 @@ static void _camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_m
LOGD("return buffer done");
}
break;
- default: /* MUSE_CAMERA_EVENT_TYPE_VIDEO_FRAME_RENDER_ERROR */
- LOGE("render error");
+ default:
+ LOGW("unhandled event %d", event);
break;
}
@@ -2234,6 +2259,7 @@ static camera_cb_info_s *_camera_client_callback_new(gint sockfd)
g_mutex_init(&cb_info->idle_event_mutex);
g_cond_init(&cb_info->idle_event_cond);
g_mutex_init(&cb_info->mp_data_mutex);
+ g_mutex_init(&cb_info->preview_cb_mutex);
#ifdef TIZEN_FEATURE_EVAS_RENDERER
g_mutex_init(&cb_info->evas_mutex);
#endif /* TIZEN_FEATURE_EVAS_RENDERER */
@@ -2288,6 +2314,7 @@ ErrorExit:
g_mutex_clear(&cb_info->idle_event_mutex);
g_cond_clear(&cb_info->idle_event_cond);
g_mutex_clear(&cb_info->mp_data_mutex);
+ g_mutex_clear(&cb_info->preview_cb_mutex);
#ifdef TIZEN_FEATURE_EVAS_RENDERER
g_mutex_clear(&cb_info->evas_mutex);
#endif /* TIZEN_FEATURE_EVAS_RENDERER */
@@ -2327,6 +2354,7 @@ static void _camera_client_callback_destroy(camera_cb_info_s *cb_info)
g_mutex_clear(&cb_info->idle_event_mutex);
g_cond_clear(&cb_info->idle_event_cond);
g_mutex_clear(&cb_info->mp_data_mutex);
+ g_mutex_clear(&cb_info->preview_cb_mutex);
#ifdef TIZEN_FEATURE_EVAS_RENDERER
g_mutex_clear(&cb_info->evas_mutex);
#endif /* TIZEN_FEATURE_EVAS_RENDERER */
@@ -2581,7 +2609,7 @@ int camera_create(camera_device_e device, camera_h *camera)
LOGD("cb info : %d", pc->cb_info->fd);
- ret = _camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_NO_TIMEOUT);
+ ret = _camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT);
pc->cb_info->api_waiting[MUSE_CAMERA_API_CREATE] = 0;
@@ -2711,7 +2739,7 @@ int camera_start_preview(camera_h camera)
LOGD("Enter");
- _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
+ _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_NO_TIMEOUT);
if (ret == CAMERA_ERROR_NONE && CHECK_PREVIEW_CB(pc->cb_info, PREVIEW_CB_TYPE_EVAS)) {
ret = _camera_start_evas_rendering(camera);
if (ret != CAMERA_ERROR_NONE) {
@@ -3791,8 +3819,13 @@ int camera_set_preview_cb(camera_h camera, camera_preview_cb callback, void *use
_camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
if (ret == CAMERA_ERROR_NONE) {
+ g_mutex_lock(&pc->cb_info->preview_cb_mutex);
+
pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW] = callback;
pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_PREVIEW] = user_data;
+
+ g_mutex_unlock(&pc->cb_info->preview_cb_mutex);
+
SET_PREVIEW_CB_TYPE(pc->cb_info, PREVIEW_CB_TYPE_USER);
}
@@ -3818,8 +3851,13 @@ int camera_unset_preview_cb(camera_h camera)
_camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
if (ret == CAMERA_ERROR_NONE) {
+ g_mutex_lock(&pc->cb_info->preview_cb_mutex);
+
pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW] = NULL;
pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_PREVIEW] = NULL;
+
+ g_mutex_unlock(&pc->cb_info->preview_cb_mutex);
+
UNSET_PREVIEW_CB_TYPE(pc->cb_info, PREVIEW_CB_TYPE_USER);
}
@@ -3995,6 +4033,58 @@ int camera_unset_interrupted_cb(camera_h camera)
}
+int camera_set_interrupt_started_cb(camera_h camera, camera_interrupt_started_cb callback, void *user_data)
+{
+ int ret = CAMERA_ERROR_NONE;
+ camera_cli_s *pc = (camera_cli_s *)camera;
+ muse_camera_api_e api = MUSE_CAMERA_API_SET_INTERRUPT_STARTED_CB;
+
+ if (!pc || !pc->cb_info || !callback) {
+ LOGE("NULL pointer %p %p", pc, callback);
+ return CAMERA_ERROR_INVALID_PARAMETER;
+ }
+
+ LOGD("Enter");
+
+ _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
+
+ if (ret == CAMERA_ERROR_NONE) {
+ pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_INTERRUPT_STARTED] = callback;
+ pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_INTERRUPT_STARTED] = user_data;
+ }
+
+ LOGD("ret : 0x%x", ret);
+
+ return ret;
+}
+
+
+int camera_unset_interrupt_started_cb(camera_h camera)
+{
+ int ret = CAMERA_ERROR_NONE;
+ camera_cli_s *pc = (camera_cli_s *)camera;
+ muse_camera_api_e api = MUSE_CAMERA_API_UNSET_INTERRUPT_STARTED_CB;
+
+ if (!pc || !pc->cb_info) {
+ LOGE("NULL handle");
+ return CAMERA_ERROR_INVALID_PARAMETER;
+ }
+
+ LOGD("Enter");
+
+ _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
+
+ if (ret == CAMERA_ERROR_NONE) {
+ pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_INTERRUPT_STARTED] = NULL;
+ pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_INTERRUPT_STARTED] = NULL;
+ }
+
+ LOGD("ret : 0x%x", ret);
+
+ return ret;
+}
+
+
int camera_set_focus_changed_cb(camera_h camera, camera_focus_changed_cb callback, void *user_data)
{
int ret = CAMERA_ERROR_NONE;
diff --git a/test/camera_test.c b/test/camera_test.c
index 022074c..d872bb4 100644
--- a/test/camera_test.c
+++ b/test/camera_test.c
@@ -451,6 +451,48 @@ static void _camera_interrupted_cb(camera_policy_e policy, camera_state_e previo
return;
}
+static void _camera_interrupt_started_cb(camera_policy_e policy, camera_state_e state, void *user_data)
+{
+ g_print("\ncamera interrupt started callback called[state %d, policy %d]\n", state, policy);
+ return;
+}
+
+void _camera_preview_cb(camera_preview_data_s *frame, void *user_data)
+{
+#if 0
+ FILE *fp = fopen("/opt/usr/media/test.yuv", "a");
+ if (fp == NULL) {
+ g_print("\n============ file open failed ===========================\n");
+ return;
+ }
+
+ switch (frame->num_of_planes) {
+ case 1:
+ fwrite(frame->data.single_plane.yuv, 1, frame->data.single_plane.size, fp);
+ case 2:
+ fwrite(frame->data.double_plane.y, 1, frame->data.double_plane.y_size, fp);
+ fwrite(frame->data.double_plane.uv, 1, frame->data.double_plane.uv_size, fp);
+ case 3:
+ fwrite(frame->data.triple_plane.y, 1, frame->data.triple_plane.y_size, fp);
+ fwrite(frame->data.triple_plane.u, 1, frame->data.triple_plane.u_size, fp);
+ fwrite(frame->data.triple_plane.v, 1, frame->data.triple_plane.v_size, fp);
+ default:
+ break;
+ }
+
+ g_print("file write done ---\n");
+
+ fclose(fp);
+ fp = NULL;
+#else
+ g_print("----- preview callback - format %d, %dx%d, num plane %d\n",
+ frame->format, frame->width, frame->height, frame->num_of_planes);
+#endif
+
+ return;
+}
+
+
static bool preview_resolution_cb(int width, int height, void *user_data)
{
resolution_stack *data = (resolution_stack *)user_data;
@@ -658,6 +700,8 @@ static void print_menu()
g_print("\t '2' Multishot test\n");
g_print("\t '3' Setting\n");
g_print("\t '4' Change device (Rear <-> Front)\n");
+ g_print("\t '5' Add preview callback\n");
+ g_print("\t '6' Remove preview callback\n");
g_print("\t 'b' back\n");
g_print("\t=======================================\n");
break;
@@ -763,11 +807,18 @@ static void main_menu(gchar buf)
camera_set_error_cb(hcamcorder->camera, _camera_error_cb, NULL);
camera_set_state_changed_cb(hcamcorder->camera, _camera_state_changed_cb, NULL);
camera_set_interrupted_cb(hcamcorder->camera, _camera_interrupted_cb, NULL);
+ camera_set_interrupt_started_cb(hcamcorder->camera, _camera_interrupt_started_cb, NULL);
camera_set_display_mode(hcamcorder->camera, CAMERA_DISPLAY_MODE_LETTER_BOX);
camera_start_preview(hcamcorder->camera);
break;
+ case '5':
+ camera_set_preview_cb(hcamcorder->camera, _camera_preview_cb, hcamcorder->camera);
+ break;
+ case '6':
+ camera_unset_preview_cb(hcamcorder->camera);
+ break;
case 'b': /* back */
camera_stop_preview(hcamcorder->camera);
camera_destroy(hcamcorder->camera);
@@ -1309,40 +1360,6 @@ static gboolean init_handle()
return TRUE;
}
-void _preview_cb(camera_preview_data_s *frame, void *user_data)
-{
-#if 0
- FILE *fp = fopen("/opt/usr/media/test.yuv", "a");
- if (fp == NULL) {
- g_print("\n============ file open failed ===========================\n");
- return;
- }
-
- switch (frame->num_of_planes) {
- case 1:
- fwrite(frame->data.single_plane.yuv, 1, frame->data.single_plane.size, fp);
- case 2:
- fwrite(frame->data.double_plane.y, 1, frame->data.double_plane.y_size, fp);
- fwrite(frame->data.double_plane.uv, 1, frame->data.double_plane.uv_size, fp);
- case 3:
- fwrite(frame->data.triple_plane.y, 1, frame->data.triple_plane.y_size, fp);
- fwrite(frame->data.triple_plane.u, 1, frame->data.triple_plane.u_size, fp);
- fwrite(frame->data.triple_plane.v, 1, frame->data.triple_plane.v_size, fp);
- default:
- break;
- }
-
- g_print("file write done ---\n");
-
- fclose(fp);
- fp = NULL;
-#else
- g_print("----- preview callback - format %d, %dx%d, num plane %d\n",
- frame->format, frame->width, frame->height, frame->num_of_planes);
-#endif
-
- return;
-}
/**
* This function is to change camcorder mode.
@@ -1446,6 +1463,7 @@ static gboolean mode_change(gchar buf)
camera_set_error_cb(hcamcorder->camera, _camera_error_cb, NULL);
camera_set_state_changed_cb(hcamcorder->camera, _camera_state_changed_cb, NULL);
camera_set_interrupted_cb(hcamcorder->camera, _camera_interrupted_cb, NULL);
+ camera_set_interrupt_started_cb(hcamcorder->camera, _camera_interrupt_started_cb, NULL);
camera_set_display_mode(hcamcorder->camera, CAMERA_DISPLAY_MODE_LETTER_BOX);
/*camera_set_display_rotation(hcamcorder->camera, CAMERA_ROTATION_90);*/
/*camera_set_display_flip(hcamcorder->camera, CAMERA_FLIP_VERTICAL);*/