diff options
author | Jeongmo Yang <jm80.yang@samsung.com> | 2017-08-17 16:07:58 +0900 |
---|---|---|
committer | Jeongmo Yang <jm80.yang@samsung.com> | 2017-08-17 16:11:47 +0900 |
commit | 3aaa3dcd087e79230b6ba1894ab0ac9a9971b3a1 (patch) | |
tree | fa61e3d8073a6285dfa50e3b8b9205a5a5ded729 | |
parent | 0256378c32c32155ddd89addb1f7c98e5fb4f8eb (diff) | |
parent | a598a58d1798e098826b090c905660393fa0b7c7 (diff) | |
download | camera-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.h | 49 | ||||
-rw-r--r-- | include/camera_private.h | 1 | ||||
-rw-r--r-- | packaging/capi-media-camera.spec | 2 | ||||
-rw-r--r-- | src/camera.c | 98 | ||||
-rw-r--r-- | test/camera_test.c | 86 |
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);*/ |