From a598a58d1798e098826b090c905660393fa0b7c7 Mon Sep 17 00:00:00 2001 From: Haesu Gwon Date: Tue, 4 Jul 2017 19:52:23 +0900 Subject: [PATCH] [ACR-1013] Change API description to support set/unset preview callback in preview state. + Update comments to describe state restriction improvement more clearly. [Version] 0.3.3 [Profile] Common [Issue Type] Update [Dependency module] N/A [Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-unified_20170630.1] Change-Id: I9468bc1242bd5ccb4708a830b41f151cf725e33a Signed-off-by: Haesu Gwon --- include/camera.h | 9 +++-- include/camera_private.h | 1 + packaging/capi-media-camera.spec | 2 +- src/camera.c | 17 +++++++++ test/camera_test.c | 78 ++++++++++++++++++++++------------------ 5 files changed, 69 insertions(+), 38 deletions(-) diff --git a/include/camera.h b/include/camera.h index c102af0..a221fa1 100644 --- a/include/camera.h +++ b/include/camera.h @@ -1731,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 @@ -1748,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); 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 b5b3e54..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.2 +Version: 0.3.3 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/camera.c b/src/camera.c index 39d7d6c..5512643 100644 --- a/src/camera.c +++ b/src/camera.c @@ -1232,6 +1232,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); @@ -1239,6 +1241,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); @@ -2235,6 +2239,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 */ @@ -2289,6 +2294,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 +2333,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 */ @@ -3788,8 +3795,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); } @@ -3815,8 +3827,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); } diff --git a/test/camera_test.c b/test/camera_test.c index d5dc5e3..d872bb4 100644 --- a/test/camera_test.c +++ b/test/camera_test.c @@ -457,6 +457,42 @@ static void _camera_interrupt_started_cb(camera_policy_e policy, camera_state_e 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; @@ -664,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; @@ -775,6 +813,12 @@ static void main_menu(gchar buf) 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); @@ -1316,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. -- 2.7.4