diff options
author | Jeongmo Yang <jm80.yang@samsung.com> | 2016-08-09 16:00:40 +0900 |
---|---|---|
committer | Jeongmo Yang <jm80.yang@samsung.com> | 2016-08-09 16:00:40 +0900 |
commit | 3b9b49d27a189a7e20fa499b546f77296daba281 (patch) | |
tree | 93f27e87290e900a164db6ad965770dabf3826fd | |
parent | b99fb331c65df7c0d20773f8e9cd8027b84753c8 (diff) | |
download | camera-3b9b49d27a189a7e20fa499b546f77296daba281.tar.gz camera-3b9b49d27a189a7e20fa499b546f77296daba281.tar.bz2 camera-3b9b49d27a189a7e20fa499b546f77296daba281.zip |
[Release version 0.2.66] Add sub threads for 2.4 API compatibility
Change-Id: If6728e5132b3ce0418bf5fe27a64d51db7c0dfe8
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r-- | include/camera_private.h | 38 | ||||
-rw-r--r-- | packaging/capi-media-camera.spec | 2 | ||||
-rw-r--r-- | src/camera.c | 301 |
3 files changed, 204 insertions, 137 deletions
diff --git a/include/camera_private.h b/include/camera_private.h index 56e8ad5..32257f1 100644 --- a/include/camera_private.h +++ b/include/camera_private.h @@ -42,6 +42,11 @@ extern "C" { #define SET_PREVIEW_CB_TYPE(cb_info, cb_type) ((cb_info)->preview_cb_flag |= cb_type) #define UNSET_PREVIEW_CB_TYPE(cb_info, cb_type) ((cb_info)->preview_cb_flag &= ~cb_type) +enum { + CAMERA_MESSAGE_HANDLER_TYPE_GENERAL, + CAMERA_MESSAGE_HANDLER_TYPE_PREVIEW_CB, + CAMERA_MESSAGE_HANDLER_TYPE_CAPTURE_CB +}; typedef struct _camera_stream_data_s { union { @@ -81,15 +86,32 @@ typedef struct _camera_stream_data_s { int elevation[BUFFER_MAX_PLANE_NUM]; /**< Elevation of each plane */ } camera_stream_data_s; +typedef struct _camera_msg_handler_info_s { + int type; + void *cb_info; + int running; + GCond cond; + GMutex mutex; + GQueue *queue; + GThread *thread; +} camera_msg_handler_info_s; + typedef struct _camera_cb_info_s { gint fd; + + /* message receive thread */ GThread *msg_recv_thread; - GThread *msg_handler_thread; gint msg_recv_running; - gint msg_handler_running; - GCond msg_handler_cond; - GMutex msg_handler_mutex; - GQueue *msg_queue; + + /* general message handler info */ + camera_msg_handler_info_s msg_handler_info; + + /* preview cb message handler info */ + camera_msg_handler_info_s preview_cb_info; + + /* capture cb message handler info */ + camera_msg_handler_info_s capture_cb_info; + GList *idle_event_list; GCond idle_event_cond; GMutex idle_event_mutex; @@ -98,8 +120,8 @@ typedef struct _camera_cb_info_s { gchar recv_msg[MUSE_CAMERA_MSG_MAX_LENGTH]; GCond api_cond[MUSE_CAMERA_API_MAX]; GMutex api_mutex[MUSE_CAMERA_API_MAX]; - gint *api_activating; - gint *api_ret; + gint api_activating[MUSE_CAMERA_API_MAX]; + gint api_ret[MUSE_CAMERA_API_MAX]; tbm_bufmgr bufmgr; media_format_h pkt_fmt; int preview_cb_flag; @@ -114,6 +136,8 @@ typedef struct _camera_cb_info_s { typedef struct _camera_message_s { gchar recv_msg[MUSE_CAMERA_MSG_MAX_LENGTH]; muse_camera_api_e api; + muse_camera_event_e event; + muse_camera_event_class_e event_class; } camera_message_s; typedef struct _camera_idle_event_s { diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec index 38a3cac..2bf72be 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.2.65 +Version: 0.2.66 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/camera.c b/src/camera.c index 16620f2..402a45c 100644 --- a/src/camera.c +++ b/src/camera.c @@ -291,7 +291,6 @@ static int _client_wait_for_cb_return(muse_camera_api_e api, camera_cb_info_s *c /*LOGD("return value : 0x%x", ret);*/ } else { ret = CAMERA_ERROR_INVALID_OPERATION; - LOGE("api %d was TIMED OUT!", api); } } else { @@ -1467,94 +1466,84 @@ IDLE_EVENT_CALLBACK_DONE: static void *_camera_msg_handler_func(gpointer data) { - int ret = 0; int api = 0; - int event = 0; - int event_class = 0; + int type = 0; camera_message_s *cam_msg = NULL; camera_idle_event_s *cam_idle_event = NULL; - camera_cb_info_s *cb_info = (camera_cb_info_s *)data; + camera_msg_handler_info_s *handler_info = (camera_msg_handler_info_s *)data; + camera_cb_info_s *cb_info = NULL; - if (cb_info == NULL) { - LOGE("cb_info NULL"); + if (!handler_info || !handler_info->cb_info) { + LOGE("t:%d NULL handler %p", type, handler_info); return NULL; } - LOGD("start"); + cb_info = (camera_cb_info_s *)handler_info->cb_info; + type = handler_info->type; - g_mutex_lock(&cb_info->msg_handler_mutex); + LOGD("t:%d start", type); - while (g_atomic_int_get(&cb_info->msg_handler_running)) { - if (g_queue_is_empty(cb_info->msg_queue)) { - /*LOGD("signal wait...");*/ - g_cond_wait(&cb_info->msg_handler_cond, &cb_info->msg_handler_mutex); - /*LOGD("signal received");*/ + g_mutex_lock(&handler_info->mutex); - if (g_atomic_int_get(&cb_info->msg_handler_running) == 0) { - LOGD("stop event thread"); + while (g_atomic_int_get(&handler_info->running)) { + if (g_queue_is_empty(handler_info->queue)) { + /*LOGD("t:%d signal wait...", type);*/ + g_cond_wait(&handler_info->cond, &handler_info->mutex); + /*LOGD("t:%d signal received", type);*/ + + if (g_atomic_int_get(&handler_info->running) == 0) { + LOGD("t:%d stop event thread", type); break; } } - cam_msg = (camera_message_s *)g_queue_pop_head(cb_info->msg_queue); + cam_msg = (camera_message_s *)g_queue_pop_head(handler_info->queue); - g_mutex_unlock(&cb_info->msg_handler_mutex); + g_mutex_unlock(&handler_info->mutex); if (cam_msg == NULL) { - LOGE("NULL message"); - g_mutex_lock(&cb_info->msg_handler_mutex); + LOGE("t:%d NULL message", type); + g_mutex_lock(&handler_info->mutex); continue; } api = cam_msg->api; if (api < MUSE_CAMERA_API_MAX) { + int ret = 0; + g_mutex_lock(&cb_info->api_mutex[api]); if (muse_camera_msg_get(ret, cam_msg->recv_msg)) { cb_info->api_ret[api] = ret; cb_info->api_activating[api] = 1; - /*LOGD("camera api %d - return 0x%x", ret);*/ + /*LOGD("t:%d camera api %d - return 0x%x", type, ret);*/ g_cond_signal(&cb_info->api_cond[api]); } else { - LOGE("failed to get camera ret for api %d, msg %s", api, cam_msg->recv_msg); + LOGE("t:%d failed to get camera ret for api %d, msg %s", type, api, cam_msg->recv_msg); } g_mutex_unlock(&cb_info->api_mutex[api]); } else if (api == MUSE_CAMERA_CB_EVENT) { - event = -1; - event_class = -1; - - if (!muse_camera_msg_get(event, cam_msg->recv_msg) || - !muse_camera_msg_get(event_class, cam_msg->recv_msg)) { - LOGE("failed to get camera event %d, class %d", event, event_class); - - g_free(cam_msg); - cam_msg = NULL; - - g_mutex_lock(&cb_info->msg_handler_mutex); - continue; - } - - switch (event_class) { + switch (cam_msg->event_class) { case MUSE_CAMERA_EVENT_CLASS_THREAD_SUB: - _client_user_callback(cb_info, cam_msg->recv_msg, event); + _client_user_callback(cb_info, cam_msg->recv_msg, cam_msg->event); break; case MUSE_CAMERA_EVENT_CLASS_THREAD_MAIN: cam_idle_event = g_new0(camera_idle_event_s, 1); if (cam_idle_event == NULL) { - LOGE("cam_idle_event alloc failed"); + LOGE("t:%d cam_idle_event alloc failed", type); break; } - cam_idle_event->event = event; + cam_idle_event->event = cam_msg->event; cam_idle_event->cb_info = cb_info; g_mutex_init(&cam_idle_event->event_mutex); memcpy(cam_idle_event->recv_msg, cam_msg->recv_msg, sizeof(cam_idle_event->recv_msg)); - /*LOGD("add camera event[%d, %p] to IDLE", event, cam_idle_event);*/ + /*LOGD("t:%d add camera event[%d, %p] to IDLE", type, event, cam_idle_event);*/ g_mutex_lock(&cb_info->idle_event_mutex); cb_info->idle_event_list = g_list_append(cb_info->idle_event_list, (gpointer)cam_idle_event); @@ -1566,38 +1555,39 @@ static void *_camera_msg_handler_func(gpointer data) NULL); break; default: - LOGE("unknown camera event class %d", event_class); + LOGE("t:%d not handled event class %d", type, cam_msg->event_class); break; } } else { - LOGE("unknown camera api[%d] message[%s]", api, cam_msg->recv_msg); + LOGE("t:%d unknown camera api[%d] message[%s]", type, api, cam_msg->recv_msg); } g_free(cam_msg); cam_msg = NULL; - g_mutex_lock(&cb_info->msg_handler_mutex); + g_mutex_lock(&handler_info->mutex); } /* remove remained event */ - while (!g_queue_is_empty(cb_info->msg_queue)) { - cam_msg = (camera_message_s *)g_queue_pop_head(cb_info->msg_queue); + while (!g_queue_is_empty(handler_info->queue)) { + cam_msg = (camera_message_s *)g_queue_pop_head(handler_info->queue); if (cam_msg) { - LOGD("remove camera message %p", cam_msg); + LOGD("t:%d remove camera message %p", type, cam_msg); free(cam_msg); cam_msg = NULL; } else { - LOGW("NULL camera message"); + LOGW("t:%d NULL camera message", type); } } - g_mutex_unlock(&cb_info->msg_handler_mutex); + g_mutex_unlock(&handler_info->mutex); - LOGD("return"); + LOGD("t:%d return", type); return NULL; } + static void _camera_remove_idle_event_all(camera_cb_info_s *cb_info) { camera_idle_event_s *cam_idle_event = NULL; @@ -1674,6 +1664,8 @@ static void *_camera_msg_recv_func(gpointer data) int ret = 0; int api = 0; int api_class = 0; + int event = 0; + int event_class = 0; int num_token = 0; int str_pos = 0; int prev_pos = 0; @@ -1739,15 +1731,23 @@ static void *_camera_msg_recv_func(gpointer data) api = -1; api_class = -1; + event = -1; + event_class = -1; if (!muse_camera_msg_get(api, parse_str[i])) { LOGE("failed to get camera api"); continue; } - if (api != MUSE_CAMERA_CB_EVENT) { + if (api == MUSE_CAMERA_CB_EVENT) { + if (!muse_camera_msg_get(event, parse_str[i]) || + !muse_camera_msg_get(event_class, parse_str[i])) { + LOGE("failed to get camera event or event_class [%s]", parse_str[i]); + continue; + } + } else { if (!muse_camera_msg_get(api_class, parse_str[i])) { - LOGE("failed to get camera api_class"); + LOGE("failed to get camera api_class [%s]", parse_str[i]); continue; } } @@ -1791,14 +1791,29 @@ static void *_camera_msg_recv_func(gpointer data) } cam_msg->api = api; - memcpy(cam_msg->recv_msg, parse_str[i], sizeof(cam_msg->recv_msg)); + cam_msg->event = event; + cam_msg->event_class = event_class; - /*LOGD("add camera message to queue : api %d", api);*/ + memcpy(cam_msg->recv_msg, parse_str[i], sizeof(cam_msg->recv_msg)); - g_mutex_lock(&cb_info->msg_handler_mutex); - g_queue_push_tail(cb_info->msg_queue, (gpointer)cam_msg); - g_cond_signal(&cb_info->msg_handler_cond); - g_mutex_unlock(&cb_info->msg_handler_mutex); + /*LOGD("add camera message to queue : api %d, event %d, event_class %d", api, event, event_class);*/ + + if (event == MUSE_CAMERA_EVENT_TYPE_PREVIEW) { + g_mutex_lock(&cb_info->preview_cb_info.mutex); + g_queue_push_tail(cb_info->preview_cb_info.queue, (gpointer)cam_msg); + g_cond_signal(&cb_info->preview_cb_info.cond); + g_mutex_unlock(&cb_info->preview_cb_info.mutex); + } else if (event == MUSE_CAMERA_EVENT_TYPE_CAPTURE) { + g_mutex_lock(&cb_info->capture_cb_info.mutex); + g_queue_push_tail(cb_info->capture_cb_info.queue, (gpointer)cam_msg); + g_cond_signal(&cb_info->capture_cb_info.cond); + g_mutex_unlock(&cb_info->capture_cb_info.mutex); + } else { + g_mutex_lock(&cb_info->msg_handler_info.mutex); + g_queue_push_tail(cb_info->msg_handler_info.queue, (gpointer)cam_msg); + g_cond_signal(&cb_info->msg_handler_info.cond); + g_mutex_unlock(&cb_info->msg_handler_info.mutex); + } } else { LOGW("unknown camera api %d and api_class %d", api, api_class); } @@ -1824,11 +1839,88 @@ CB_HANDLER_EXIT: return NULL; } + +static bool __create_msg_handler_thread(camera_msg_handler_info_s *handler_info, + int type, const char *thread_name, camera_cb_info_s *cb_info) +{ + if (!handler_info || !thread_name || !cb_info) { + LOGE("t:%d NULL %p %p %p", + type, handler_info, thread_name, cb_info); + return false; + } + + LOGD("t:%d", type); + + handler_info->type = type; + handler_info->queue = g_queue_new(); + if (handler_info->queue == NULL) { + LOGE("t:%d queue failed", type); + return false; + } + + g_mutex_init(&handler_info->mutex); + g_cond_init(&handler_info->cond); + + handler_info->cb_info = (void *)cb_info; + g_atomic_int_set(&handler_info->running, 1); + + handler_info->thread = g_thread_try_new(thread_name, + _camera_msg_handler_func, (gpointer)handler_info, NULL); + if (handler_info->thread == NULL) { + LOGE("t:%d thread failed", type); + + g_mutex_clear(&handler_info->mutex); + g_cond_clear(&handler_info->cond); + g_queue_free(handler_info->queue); + handler_info->queue = NULL; + + return false; + } + + LOGD("t:%d done", type); + + return true; +} + + +static void __destroy_msg_handler_thread(camera_msg_handler_info_s *handler_info) +{ + int type = 0; + + if (!handler_info) { + LOGE("NULL handler"); + return; + } + + type = handler_info->type; + + LOGD("t:%d thread %p", type, handler_info->thread); + + if (handler_info->thread) { + g_mutex_lock(&handler_info->mutex); + g_atomic_int_set(&handler_info->running, 0); + g_cond_signal(&handler_info->cond); + g_mutex_unlock(&handler_info->mutex); + + g_thread_join(handler_info->thread); + g_thread_unref(handler_info->thread); + handler_info->thread = NULL; + + g_mutex_clear(&handler_info->mutex); + g_cond_clear(&handler_info->cond); + g_queue_free(handler_info->queue); + handler_info->queue = NULL; + } + + LOGD("t:%d done", type); + + return; +} + + static camera_cb_info_s *_client_callback_new(gint sockfd) { camera_cb_info_s *cb_info = NULL; - gint *tmp_activating = NULL; - gint *tmp_ret = NULL; gint i = 0; g_return_val_if_fail(sockfd > 0, NULL); @@ -1839,8 +1931,6 @@ static camera_cb_info_s *_client_callback_new(gint sockfd) goto ErrorExit; } - g_mutex_init(&cb_info->msg_handler_mutex); - g_cond_init(&cb_info->msg_handler_cond); g_mutex_init(&cb_info->idle_event_mutex); g_cond_init(&cb_info->idle_event_cond); g_mutex_init(&cb_info->mp_data_mutex); @@ -1853,40 +1943,34 @@ static camera_cb_info_s *_client_callback_new(gint sockfd) g_cond_init(&cb_info->api_cond[i]); } - tmp_activating = g_new0(gint, MUSE_CAMERA_API_MAX); - if (tmp_activating == NULL) { - LOGE("tmp_activating failed"); - goto ErrorExit; - } - - tmp_ret = g_new0(gint, MUSE_CAMERA_API_MAX); - if (tmp_ret == NULL) { - LOGE("tmp_ret failed"); + /* message handler thread */ + if (!__create_msg_handler_thread(&cb_info->msg_handler_info, + CAMERA_MESSAGE_HANDLER_TYPE_GENERAL, "camera_msg_handler", cb_info)) { + LOGE("msg_handler_info failed"); goto ErrorExit; } - cb_info->msg_queue = g_queue_new(); - if (cb_info->msg_queue == NULL) { - LOGE("msg_queue new failed"); + /* message handler thread for preview callback */ + if (!__create_msg_handler_thread(&cb_info->preview_cb_info, + CAMERA_MESSAGE_HANDLER_TYPE_PREVIEW_CB, "camera_msg_handler:preview_cb", cb_info)) { + LOGE("preview_cb_info failed"); goto ErrorExit; } - g_atomic_int_set(&cb_info->msg_handler_running, 1); - cb_info->msg_handler_thread = g_thread_try_new("camera_msg_handler", - _camera_msg_handler_func, (gpointer)cb_info, NULL); - if (cb_info->msg_handler_thread == NULL) { - LOGE("message handler thread creation failed"); + /* message handler thread for capture callback */ + if (!__create_msg_handler_thread(&cb_info->capture_cb_info, + CAMERA_MESSAGE_HANDLER_TYPE_CAPTURE_CB, "camera_msg_handler:capture_cb", cb_info)) { + LOGE("capture_cb_info failed"); goto ErrorExit; } cb_info->fd = sockfd; - cb_info->api_activating = tmp_activating; - cb_info->api_ret = tmp_ret; cb_info->preview_cb_flag = 0; #ifdef TIZEN_FEATURE_EVAS_RENDERER cb_info->evas_info = NULL; #endif /* TIZEN_FEATURE_EVAS_RENDERER */ + /* message receive thread */ g_atomic_int_set(&cb_info->msg_recv_running, 1); cb_info->msg_recv_thread = g_thread_try_new("camera_msg_recv", _camera_msg_recv_func, (gpointer)cb_info, NULL); @@ -1899,24 +1983,15 @@ static camera_cb_info_s *_client_callback_new(gint sockfd) ErrorExit: if (cb_info) { - if (cb_info->msg_handler_thread) { - g_mutex_lock(&cb_info->msg_handler_mutex); - g_atomic_int_set(&cb_info->msg_handler_running, 0); - g_cond_signal(&cb_info->msg_handler_cond); - g_mutex_unlock(&cb_info->msg_handler_mutex); - - g_thread_join(cb_info->msg_handler_thread); - g_thread_unref(cb_info->msg_handler_thread); - cb_info->msg_handler_thread = NULL; - } + __destroy_msg_handler_thread(&cb_info->msg_handler_info); + __destroy_msg_handler_thread(&cb_info->preview_cb_info); + __destroy_msg_handler_thread(&cb_info->capture_cb_info); for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) { g_mutex_clear(&cb_info->api_mutex[i]); g_cond_clear(&cb_info->api_cond[i]); } - g_mutex_clear(&cb_info->msg_handler_mutex); - g_cond_clear(&cb_info->msg_handler_cond); g_mutex_clear(&cb_info->idle_event_mutex); g_cond_clear(&cb_info->idle_event_cond); g_mutex_clear(&cb_info->mp_data_mutex); @@ -1924,24 +1999,10 @@ ErrorExit: g_mutex_clear(&cb_info->evas_mutex); #endif /* TIZEN_FEATURE_EVAS_RENDERER */ - if (cb_info->msg_queue) { - g_queue_free(cb_info->msg_queue); - cb_info->msg_queue = NULL; - } - g_free(cb_info); cb_info = NULL; } - if (tmp_activating) { - g_free(tmp_activating); - tmp_activating = NULL; - } - if (tmp_ret) { - g_free(tmp_ret); - tmp_ret = NULL; - } - return NULL; } @@ -1959,25 +2020,16 @@ static void _client_callback_destroy(camera_cb_info_s *cb_info) LOGD("msg thread removed"); - g_mutex_lock(&cb_info->msg_handler_mutex); - g_atomic_int_set(&cb_info->msg_handler_running, 0); - g_cond_signal(&cb_info->msg_handler_cond); - g_mutex_unlock(&cb_info->msg_handler_mutex); - - g_thread_join(cb_info->msg_handler_thread); - g_thread_unref(cb_info->msg_handler_thread); - cb_info->msg_handler_thread = NULL; - - g_queue_free(cb_info->msg_queue); - cb_info->msg_queue = NULL; + /* destroy msg handler threads */ + __destroy_msg_handler_thread(&cb_info->msg_handler_info); + __destroy_msg_handler_thread(&cb_info->preview_cb_info); + __destroy_msg_handler_thread(&cb_info->capture_cb_info); for (i = 0 ; i < MUSE_CAMERA_API_MAX ; i++) { g_mutex_clear(&cb_info->api_mutex[i]); g_cond_clear(&cb_info->api_cond[i]); } - g_mutex_clear(&cb_info->msg_handler_mutex); - g_cond_clear(&cb_info->msg_handler_cond); g_mutex_clear(&cb_info->idle_event_mutex); g_cond_clear(&cb_info->idle_event_cond); g_mutex_clear(&cb_info->mp_data_mutex); @@ -1996,14 +2048,6 @@ static void _client_callback_destroy(camera_cb_info_s *cb_info) tbm_bufmgr_deinit(cb_info->bufmgr); cb_info->bufmgr = NULL; } - if (cb_info->api_activating) { - g_free(cb_info->api_activating); - cb_info->api_activating = NULL; - } - if (cb_info->api_ret) { - g_free(cb_info->api_ret); - cb_info->api_ret = NULL; - } if (cb_info->pkt_fmt) { media_format_unref(cb_info->pkt_fmt); cb_info->pkt_fmt = NULL; @@ -5377,7 +5421,6 @@ Exit: /* release resources */ if (pc) { g_atomic_int_set(&pc->cb_info->msg_recv_running, 0); - g_atomic_int_set(&pc->cb_info->msg_handler_running, 0); _client_callback_destroy(pc->cb_info); pc->cb_info = NULL; g_free(pc); |