summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongmo Yang <jm80.yang@samsung.com>2015-10-16 18:12:21 +0900
committerJeongmo Yang <jm80.yang@samsung.com>2015-10-16 20:02:46 +0900
commitc3b2665009a29267aa0b5d3b2ac1efd7a88ed89a (patch)
tree8df8055e681b0b4114f8325ab92af0266aae533f
parent5df3cec20d9e7ee21d070866212823aaf96e4b32 (diff)
downloadcamera-c3b2665009a29267aa0b5d3b2ac1efd7a88ed89a.tar.gz
camera-c3b2665009a29267aa0b5d3b2ac1efd7a88ed89a.tar.bz2
camera-c3b2665009a29267aa0b5d3b2ac1efd7a88ed89a.zip
1. Add new thread for event callback Change-Id: I237b1666960f253e75acca73c434f3860f59f997 Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r--include/camera_private.h14
-rw-r--r--packaging/capi-media-camera.spec2
-rwxr-xr-xsrc/camera.c183
3 files changed, 176 insertions, 23 deletions
diff --git a/include/camera_private.h b/include/camera_private.h
index a3d156f..d279dab 100644
--- a/include/camera_private.h
+++ b/include/camera_private.h
@@ -54,8 +54,10 @@ typedef struct _camera_cb_data {
} camera_cb_data;
typedef struct _callback_cb_info {
- GThread *thread;
- gint running;
+ GThread *msg_rcv_thread;
+ GThread *event_thread;
+ gint rcv_thread_running;
+ gint event_thread_running;
gint fd;
gint id;
gpointer user_cb[MUSE_CAMERA_EVENT_TYPE_NUM];
@@ -66,10 +68,18 @@ typedef struct _callback_cb_info {
gchar recvEventMsg[MUSE_CAMERA_MSG_MAX_LENGTH];
GCond *pCond;
GMutex *pMutex;
+ GCond event_cond;
+ GMutex event_mutex;
gint *activating;
tbm_bufmgr bufmgr;
+ GQueue *event_queue;
} callback_cb_info_s;
+typedef struct _event_info_s {
+ gchar recvMsg[MUSE_CAMERA_MSG_MAX_LENGTH];
+ muse_camera_event_e event;
+} event_info_s;
+
typedef struct _camera_cli_s {
intptr_t remote_handle;
MMHandleType client_handle;
diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec
index e3b8ea3..2b93b63 100644
--- a/packaging/capi-media-camera.spec
+++ b/packaging/capi-media-camera.spec
@@ -3,7 +3,7 @@
Name: capi-media-camera
Summary: A Camera API
-Version: 0.2.13
+Version: 0.2.14
Release: 0
Group: Multimedia/API
License: Apache-2.0
diff --git a/src/camera.c b/src/camera.c
index 7f76495..3a570b1 100755
--- a/src/camera.c
+++ b/src/camera.c
@@ -81,10 +81,17 @@ static int client_wait_for_cb_return(muse_camera_api_e api, callback_cb_info_s *
return ret;
}
-static void _client_user_callback(callback_cb_info_s * cb_info, muse_camera_event_e event )
+static void _client_user_callback(callback_cb_info_s *cb_info, char *recvMsg, muse_camera_event_e event)
{
- char *recvMsg = cb_info->recvMsg;
- int param, param1, param2;
+ int param = 0;
+ int param1 = 0;
+ int param2 = 0;
+
+ if (recvMsg == NULL) {
+ LOGE("NULL message for event %d", event);
+ return;
+ }
+
LOGD("get event %d", event);
switch (event) {
@@ -318,7 +325,6 @@ static void _client_user_callback(callback_cb_info_s * cb_info, muse_camera_even
break;
case MUSE_CAMERA_EVENT_TYPE_CAPTURE:
{
- int ret = CAMERA_ERROR_NONE;
camera_image_data_s *rImage = NULL;
camera_image_data_s *rPostview = NULL;
camera_image_data_s *rThumbnail = NULL;
@@ -384,9 +390,12 @@ static void _client_user_callback(callback_cb_info_s * cb_info, muse_camera_even
}
/* return buffer */
- muse_camera_msg_send1(MUSE_CAMERA_API_RETURN_BUFFER, cb_info->fd, cb_info, ret, INT, tbm_key);
+ muse_camera_msg_send1_no_return(MUSE_CAMERA_API_RETURN_BUFFER,
+ cb_info->fd,
+ cb_info,
+ INT, tbm_key);
- LOGD("return buffer result : 0x%x", ret);
+ LOGD("return buffer done");
/* unmap and unref tbm bo */
tbm_bo_unmap(bo);
@@ -402,6 +411,68 @@ static void _client_user_callback(callback_cb_info_s * cb_info, muse_camera_even
LOGE("Unknonw event : %d", event);
break;
}
+
+ return;
+}
+
+static void *_event_handler(gpointer data)
+{
+ event_info_s *e_info = NULL;
+ callback_cb_info_s *cb_info = (callback_cb_info_s *)data;
+
+ if (cb_info == NULL) {
+ LOGE("cb_info NULL");
+ return NULL;
+ }
+
+ LOGD("start");
+
+ g_mutex_lock(&cb_info->event_mutex);
+
+ while (g_atomic_int_get(&cb_info->event_thread_running)) {
+ if (g_queue_is_empty(cb_info->event_queue)) {
+ LOGD("signal wait...");
+ g_cond_wait(&cb_info->event_cond, &cb_info->event_mutex);
+ LOGD("signal received");
+
+ if (g_atomic_int_get(&cb_info->event_thread_running) == 0) {
+ LOGD("stop event thread");
+ break;
+ }
+ }
+
+ e_info = (event_info_s *)g_queue_pop_head(cb_info->event_queue);
+
+ g_mutex_unlock(&cb_info->event_mutex);
+
+ if (e_info) {
+ _client_user_callback(cb_info, e_info->recvMsg, e_info->event);
+ free(e_info);
+ e_info = NULL;
+ } else {
+ LOGW("NULL event info");
+ }
+
+ g_mutex_lock(&cb_info->event_mutex);
+ }
+
+ /* remove remained event */
+ while (!g_queue_is_empty(cb_info->event_queue)) {
+ e_info = (event_info_s *)g_queue_pop_head(cb_info->event_queue);
+ if (e_info) {
+ LOGD("remove event info %p", e_info);
+ free(e_info);
+ e_info = NULL;
+ } else {
+ LOGW("NULL event info");
+ }
+ }
+
+ g_mutex_unlock(&cb_info->event_mutex);
+
+ LOGD("return");
+
+ return NULL;
}
static void *client_cb_handler(gpointer data)
@@ -412,11 +483,20 @@ static void *client_cb_handler(gpointer data)
int i = 0;
int str_pos = 0;
int prev_pos = 0;
- callback_cb_info_s *cb_info = data;
- char *recvMsg = cb_info->recvMsg;
+ callback_cb_info_s *cb_info = (callback_cb_info_s *)data;
+ char *recvMsg = NULL;
char parseStr[CAMERA_PARSE_STRING_SIZE][MUSE_CAMERA_MSG_MAX_LENGTH] = {{0,0},};
- while (g_atomic_int_get(&cb_info->running)) {
+ if (cb_info == NULL) {
+ LOGE("cb_info NULL");
+ return NULL;
+ }
+
+ LOGD("start");
+
+ recvMsg = cb_info->recvMsg;
+
+ while (g_atomic_int_get(&cb_info->rcv_thread_running)) {
ret = muse_core_ipc_recv_msg(cb_info->fd, recvMsg);
if (ret <= 0)
break;
@@ -463,7 +543,7 @@ static void *client_cb_handler(gpointer data)
if (api == MUSE_CAMERA_API_CREATE) {
if (muse_camera_msg_get(ret, cb_info->recvApiMsg)) {
if (ret != CAMERA_ERROR_NONE) {
- g_atomic_int_set(&cb_info->running, 0);
+ g_atomic_int_set(&cb_info->rcv_thread_running, 0);
LOGE("camera create error. close client cb handler");
}
} else {
@@ -472,7 +552,7 @@ static void *client_cb_handler(gpointer data)
} else if (api == MUSE_CAMERA_API_DESTROY) {
if (muse_camera_msg_get(ret, cb_info->recvApiMsg)) {
if (ret == CAMERA_ERROR_NONE) {
- g_atomic_int_set(&cb_info->running, 0);
+ g_atomic_int_set(&cb_info->rcv_thread_running, 0);
LOGD("camera destroy done. close client cb handler");
}
} else {
@@ -482,8 +562,44 @@ static void *client_cb_handler(gpointer data)
} else if(api == MUSE_CAMERA_CB_EVENT) {
int event;
if (muse_camera_msg_get(event, &(parseStr[i][0]))) {
- LOGD("go callback : %d", event);
- _client_user_callback(cb_info, event);
+ event_info_s *e_info = NULL;
+
+ switch (event) {
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_PREVIEW_RESOLUTION:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_CAPTURE_RESOLUTION:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_THEATER_MODE:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_CAPTURE_FORMAT:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_PREVIEW_FORMAT:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_AF_MODE:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_EXPOSURE_MODE:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_ISO:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_WHITEBALANCE:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_EFFECT:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_SCENE_MODE:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_FLASH_MODE:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_FPS:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_FPS_BY_RESOLUTION:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_STREAM_FLIP:
+ case MUSE_CAMERA_EVENT_TYPE_FOREACH_SUPPORTED_STREAM_ROTATION:
+ _client_user_callback(cb_info, recvMsg, event);
+ break;
+ default:
+ e_info = (event_info_s *)malloc(sizeof(event_info_s));
+ if (e_info) {
+ LOGD("add event to queue : %d", event);
+ g_mutex_lock(&cb_info->event_mutex);
+
+ e_info->event = event;
+ memcpy(e_info->recvMsg, recvMsg, sizeof(e_info->recvMsg));
+ g_queue_push_tail(cb_info->event_queue, (gpointer)e_info);
+
+ g_cond_signal(&cb_info->event_cond);
+ g_mutex_unlock(&cb_info->event_mutex);
+ } else {
+ LOGE("e_info alloc failed");
+ }
+ break;
+ }
}
} else {
LOGW("unknown api : %d", api);
@@ -494,6 +610,7 @@ static void *client_cb_handler(gpointer data)
}
}
+
LOGD("client cb exit");
return NULL;
@@ -512,14 +629,18 @@ static callback_cb_info_s *client_callback_new(gint sockfd)
camera_mutex = g_new0(GMutex, MUSE_CAMERA_API_MAX);
camera_activ = g_new0(gint, MUSE_CAMERA_API_MAX);
- g_atomic_int_set(&cb_info->running, 1);
+ g_atomic_int_set(&cb_info->rcv_thread_running, 1);
cb_info->fd = sockfd;
cb_info->pCond = camera_cond;
cb_info->pMutex = camera_mutex;
cb_info->activating = camera_activ;
- cb_info->thread =
- g_thread_new("callback_thread", client_cb_handler,
- (gpointer) cb_info);
+ cb_info->msg_rcv_thread = g_thread_new("msg_rcv_thread", client_cb_handler, (gpointer)cb_info);
+
+ g_atomic_int_set(&cb_info->event_thread_running, 1);
+ g_mutex_init(&cb_info->event_mutex);
+ g_cond_init(&cb_info->event_cond);
+ cb_info->event_queue = g_queue_new();
+ cb_info->event_thread = g_thread_new("event_thread", _event_handler, (gpointer)cb_info);
return cb_info;
}
@@ -528,10 +649,29 @@ static void client_callback_destroy(callback_cb_info_s * cb_info)
{
g_return_if_fail(cb_info != NULL);
- LOGI("%p Callback destroyed", cb_info->thread);
+ LOGI("MSG receive thread[%p] destroy", cb_info->msg_rcv_thread);
+
+ g_thread_join(cb_info->msg_rcv_thread);
+ g_thread_unref(cb_info->msg_rcv_thread);
+ cb_info->msg_rcv_thread = NULL;
- g_thread_join(cb_info->thread);
- g_thread_unref(cb_info->thread);
+ LOGD("msg thread removed");
+
+ g_mutex_lock(&cb_info->event_mutex);
+ g_atomic_int_set(&cb_info->event_thread_running, 0);
+ g_cond_signal(&cb_info->event_cond);
+ g_mutex_unlock(&cb_info->event_mutex);
+
+ g_thread_join(cb_info->event_thread);
+ g_thread_unref(cb_info->event_thread);
+ cb_info->event_thread = NULL;
+
+ g_queue_free(cb_info->event_queue);
+ cb_info->event_queue = NULL;
+ g_mutex_clear(&cb_info->event_mutex);
+ g_cond_clear(&cb_info->event_cond);
+
+ LOGD("event thread removed");
if (cb_info->bufmgr) {
tbm_bufmgr_deinit(cb_info->bufmgr);
@@ -547,7 +687,10 @@ static void client_callback_destroy(callback_cb_info_s * cb_info)
if (cb_info->activating) {
g_free(cb_info->activating);
}
+
g_free(cb_info);
+
+ return;
}
int camera_create(camera_device_e device, camera_h* camera)