summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongmo Yang <jm80.yang@samsung.com>2015-11-02 19:32:42 +0900
committerJeongmo Yang <jm80.yang@samsung.com>2015-11-02 19:32:42 +0900
commit1ea45536f0c98f1cc39a57a0276fe0e0d05d7550 (patch)
tree7535eff0ebd718f13e2cd808fe7dc64faa055516
parent5db7d92cf1d114ed0b200332911de790590a41dc (diff)
downloadcamera-1ea45536f0c98f1cc39a57a0276fe0e0d05d7550.tar.gz
camera-1ea45536f0c98f1cc39a57a0276fe0e0d05d7550.tar.bz2
camera-1ea45536f0c98f1cc39a57a0276fe0e0d05d7550.zip
1. Support idle callback for 2.4 API compatibility 2. Remove unused pkgconfig - json, eom Change-Id: I59c0f84e0a26ecfd2c8f4984b591384142a2e615 Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r--include/camera.h2
-rw-r--r--include/camera_private.h14
-rw-r--r--packaging/capi-media-camera.spec4
-rwxr-xr-xsrc/camera.c236
-rw-r--r--test/multimedia_camera_test.c37
5 files changed, 220 insertions, 73 deletions
diff --git a/include/camera.h b/include/camera.h
index c08c8df..154458a 100644
--- a/include/camera.h
+++ b/include/camera.h
@@ -817,7 +817,7 @@ int camera_stop_preview(camera_h camera);
* @see camera_attr_set_image_quality()
* @see camera_attr_get_image_quality()
*/
-int camera_start_capture(camera_h camera, camera_capturing_cb capturing_cb , camera_capture_completed_cb completed_cb , void *user_data);
+int camera_start_capture(camera_h camera, camera_capturing_cb capturing_cb, camera_capture_completed_cb completed_cb, void *user_data);
/**
* @brief Starts continuously capturing still images.
diff --git a/include/camera_private.h b/include/camera_private.h
index c7daee5..3339ae8 100644
--- a/include/camera_private.h
+++ b/include/camera_private.h
@@ -70,16 +70,26 @@ typedef struct _callback_cb_info {
GMutex *pMutex;
GCond event_cond;
GMutex event_mutex;
+ GList *idle_event_list;
+ GCond idle_event_cond;
+ GMutex idle_event_mutex;
gint *activating;
tbm_bufmgr bufmgr;
GQueue *event_queue;
} callback_cb_info_s;
-typedef struct _event_info_s {
+typedef struct _camera_event_s {
callback_cb_info_s *cb_info;
gchar recvMsg[MUSE_CAMERA_MSG_MAX_LENGTH];
muse_camera_event_e event;
-} event_info_s;
+} camera_event_s;
+
+typedef struct _camera_idle_event_s {
+ callback_cb_info_s *cb_info;
+ gchar recvMsg[MUSE_CAMERA_MSG_MAX_LENGTH];
+ muse_camera_event_e event;
+ GMutex event_mutex;
+} camera_idle_event_s;
typedef struct _camera_cli_s {
intptr_t remote_handle;
diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec
index e481bf1..7a99abd 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.17
+Version: 0.2.18
Release: 0
Group: Multimedia/API
License: Apache-2.0
@@ -24,9 +24,7 @@ BuildRequires: pkgconfig(mm-camcorder)
%if %{with wayland}
BuildRequires: pkgconfig(ecore-wayland)
%endif
-BuildRequires: pkgconfig(json)
BuildRequires: pkgconfig(libtbm)
-BuildRequires: pkgconfig(eom)
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
diff --git a/src/camera.c b/src/camera.c
index 67c88de..698179f 100755
--- a/src/camera.c
+++ b/src/camera.c
@@ -89,7 +89,7 @@ static void _release_imported_bo(tbm_bo *bo)
return;
}
-static int client_wait_for_cb_return(muse_camera_api_e api, callback_cb_info_s *cb_info, int time_out)
+static int _client_wait_for_cb_return(muse_camera_api_e api, callback_cb_info_s *cb_info, int time_out)
{
int ret = CAMERA_ERROR_NONE;
gint64 end_time;
@@ -527,7 +527,7 @@ static void _client_user_callback(callback_cb_info_s *cb_info, char *recvMsg, mu
static void *_event_handler(gpointer data)
{
- event_info_s *e_info = NULL;
+ camera_event_s *cam_event = NULL;
callback_cb_info_s *cb_info = (callback_cb_info_s *)data;
if (cb_info == NULL) {
@@ -551,14 +551,14 @@ static void *_event_handler(gpointer data)
}
}
- e_info = (event_info_s *)g_queue_pop_head(cb_info->event_queue);
+ cam_event = (camera_event_s *)g_queue_pop_head(cb_info->event_queue);
g_mutex_unlock(&cb_info->event_mutex);
- if (e_info) {
- _client_user_callback(e_info->cb_info, e_info->recvMsg, e_info->event);
- free(e_info);
- e_info = NULL;
+ if (cam_event) {
+ _client_user_callback(cam_event->cb_info, cam_event->recvMsg, cam_event->event);
+ free(cam_event);
+ cam_event = NULL;
} else {
LOGW("NULL event info");
}
@@ -568,11 +568,11 @@ static void *_event_handler(gpointer data)
/* 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;
+ cam_event = (camera_event_s *)g_queue_pop_head(cb_info->event_queue);
+ if (cam_event) {
+ LOGD("remove event info %p", cam_event);
+ free(cam_event);
+ cam_event = NULL;
} else {
LOGW("NULL event info");
}
@@ -587,21 +587,119 @@ static void *_event_handler(gpointer data)
static bool _camera_idle_event_callback(void *data)
{
- event_info_s *e_info = (event_info_s *)data;
+ callback_cb_info_s *cb_info = NULL;
+ camera_idle_event_s *cam_idle_event = (camera_idle_event_s *)data;
- if (e_info == NULL) {
- LOGE("event info is NULL");
+ if (cam_idle_event == NULL) {
+ LOGE("cam_idle_event is NULL");
return false;
}
- _client_user_callback(e_info->cb_info, e_info->recvMsg, e_info->event);
- free(e_info);
- e_info = NULL;
+ /* lock event */
+ g_mutex_lock(&cam_idle_event->event_mutex);
+
+ cb_info = cam_idle_event->cb_info;
+ if (cb_info == NULL) {
+ LOGW("cb_info is NULL. event %d", cam_idle_event->event);
+ goto IDLE_EVENT_CALLBACK_DONE;
+ }
+
+ /* remove event from list */
+ g_mutex_lock(&cb_info->idle_event_mutex);
+ if (cb_info->idle_event_list) {
+ cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)cam_idle_event);
+ }
+ g_mutex_unlock(&cb_info->idle_event_mutex);
+
+ /* user callback */
+ _client_user_callback(cam_idle_event->cb_info, cam_idle_event->recvMsg, cam_idle_event->event);
+
+ /* send signal for waiting thread */
+ g_cond_signal(&cb_info->idle_event_cond);
+
+IDLE_EVENT_CALLBACK_DONE:
+ /* unlock and release event */
+ g_mutex_unlock(&cam_idle_event->event_mutex);
+ g_mutex_clear(&cam_idle_event->event_mutex);
+
+ free(cam_idle_event);
+ cam_idle_event = NULL;
return false;
}
-static void *client_cb_handler(gpointer data)
+static void _camera_remove_idle_event_all(callback_cb_info_s *cb_info)
+{
+ camera_idle_event_s *cam_idle_event = NULL;
+ gboolean ret = TRUE;
+ GList *list = NULL;
+ gint64 end_time = 0;
+
+ if (cb_info == NULL) {
+ LOGE("cb_info is NULL");
+ return;
+ }
+
+ g_mutex_lock(&cb_info->idle_event_mutex);
+
+ if (cb_info->idle_event_list) {
+ LOGD("No idle event is remained.");
+ } else {
+ list = cb_info->idle_event_list;
+
+ while (list) {
+ cam_idle_event = list->data;
+ list = g_list_next(list);
+
+ if (!cam_idle_event) {
+ LOGW("Fail to remove idle event. The event is NULL");
+ } else {
+ if (g_mutex_trylock(&cam_idle_event->event_mutex)) {
+ ret = g_idle_remove_by_data(cam_idle_event);
+
+ LOGD("remove idle event [%p], ret[%d]", cam_idle_event, ret);
+
+ if (ret == FALSE) {
+ cam_idle_event->cb_info = NULL;
+ LOGW("idle callback for event %p will be called later", cam_idle_event);
+ }
+
+ cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)cam_idle_event);
+
+ g_mutex_unlock(&cam_idle_event->event_mutex);
+
+ if (ret == TRUE) {
+ g_mutex_clear(&cam_idle_event->event_mutex);
+
+ free(cam_idle_event);
+ cam_idle_event = NULL;
+
+ LOGD("remove idle event done");
+ }
+ } else {
+ LOGW("event lock failed. it's being called...");
+
+ end_time = g_get_monotonic_time () + G_TIME_SPAN_MILLISECOND * 100;
+
+ if (g_cond_wait_until(&cb_info->idle_event_cond, &cb_info->idle_event_mutex, end_time)) {
+ LOGW("signal received");
+ } else {
+ LOGW("timeout");
+ }
+ }
+ }
+ }
+
+ g_list_free(cb_info->idle_event_list);
+ cb_info->idle_event_list = NULL;
+ }
+
+ g_mutex_unlock(&cb_info->idle_event_mutex);
+
+ return;
+}
+
+static void *_client_cb_handler(gpointer data)
{
int ret = 0;
int api = 0;
@@ -703,37 +801,60 @@ static void *client_cb_handler(gpointer data)
} else if(api == MUSE_CAMERA_CB_EVENT) {
int event = -1;
int class = -1;
+ camera_event_s *cam_event = NULL;
+ camera_idle_event_s *cam_idle_event = NULL;
- if (muse_camera_msg_get(event, parseStr[i]) &&
- muse_camera_msg_get(class, parseStr[i])) {
- event_info_s *e_info = NULL;
-
- if (class == MUSE_CAMERA_EVENT_CLASS_NORMAL ||
- class == MUSE_CAMERA_EVENT_CLASS_IDLE) {
- e_info = (event_info_s *)malloc(sizeof(event_info_s));
- if (e_info) {
- e_info->event = event;
- e_info->cb_info = cb_info;
- memcpy(e_info->recvMsg, recvMsg, sizeof(e_info->recvMsg));
-
- if (class == MUSE_CAMERA_EVENT_CLASS_NORMAL) {
- LOGD("add event to EVENT QUEUE : %d", event);
- g_mutex_lock(&cb_info->event_mutex);
- 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 {
- LOGD("add event to IDLE : %d", event);
- g_idle_add_full(G_PRIORITY_DEFAULT, (GSourceFunc)_camera_idle_event_callback, (gpointer)e_info, NULL);
- }
- } else {
- LOGE("e_info alloc failed");
- }
- } else if (class == MUSE_CAMERA_EVENT_CLASS_IMMEDIATE) {
- _client_user_callback(cb_info, recvMsg, event);
+ if (!muse_camera_msg_get(event, parseStr[i]) ||
+ !muse_camera_msg_get(class, parseStr[i])) {
+ LOGE("failed to get event %d, class %d", event, class);
+ continue;
+ }
+
+ switch (class) {
+ case MUSE_CAMERA_EVENT_CLASS_NORMAL:
+ cam_event = (camera_event_s *)malloc(sizeof(camera_event_s));
+ if (cam_event) {
+ cam_event->event = event;
+ cam_event->cb_info = cb_info;
+ memcpy(cam_event->recvMsg, recvMsg, sizeof(cam_event->recvMsg));
+
+ LOGD("add event to EVENT QUEUE : %d", event);
+ g_mutex_lock(&cb_info->event_mutex);
+ g_queue_push_tail(cb_info->event_queue, (gpointer)cam_event);
+ g_cond_signal(&cb_info->event_cond);
+ g_mutex_unlock(&cb_info->event_mutex);
+ } else {
+ LOGE("cam_event alloc failed");
+ }
+ break;
+ case MUSE_CAMERA_EVENT_CLASS_IMMEDIATE:
+ _client_user_callback(cb_info, recvMsg, event);
+ break;
+ case MUSE_CAMERA_EVENT_CLASS_IDLE:
+ cam_idle_event = (camera_idle_event_s *)malloc(sizeof(camera_idle_event_s));
+ if (cam_idle_event) {
+ cam_idle_event->event = event;
+ cam_idle_event->cb_info = cb_info;
+ g_mutex_init(&cam_idle_event->event_mutex);
+ memcpy(cam_idle_event->recvMsg, recvMsg, sizeof(cam_idle_event->recvMsg));
+
+ LOGD("add event to IDLE : %d", 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);
+ g_mutex_unlock(&cb_info->idle_event_mutex);
+
+ g_idle_add_full(G_PRIORITY_DEFAULT,
+ (GSourceFunc)_camera_idle_event_callback,
+ (gpointer)cam_idle_event,
+ NULL);
} else {
- LOGE("unknown class %d", class);
+ LOGE("cam_idle_event alloc failed");
}
+ break;
+ default:
+ LOGE("unknown class %d", class);
+ break;
}
} else {
LOGW("unknown api : %d", api);
@@ -763,7 +884,7 @@ CB_HANDLER_EXIT:
return NULL;
}
-static callback_cb_info_s *client_callback_new(gint sockfd)
+static callback_cb_info_s *_client_callback_new(gint sockfd)
{
callback_cb_info_s *cb_info;
GCond *camera_cond;
@@ -781,18 +902,20 @@ static callback_cb_info_s *client_callback_new(gint sockfd)
cb_info->pCond = camera_cond;
cb_info->pMutex = camera_mutex;
cb_info->activating = camera_activ;
- cb_info->msg_rcv_thread = g_thread_new("msg_rcv_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);
+ g_mutex_init(&cb_info->idle_event_mutex);
+ g_cond_init(&cb_info->idle_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;
}
-static void client_callback_destroy(callback_cb_info_s * cb_info)
+static void _client_callback_destroy(callback_cb_info_s * cb_info)
{
g_return_if_fail(cb_info != NULL);
@@ -817,6 +940,8 @@ static void client_callback_destroy(callback_cb_info_s * cb_info)
cb_info->event_queue = NULL;
g_mutex_clear(&cb_info->event_mutex);
g_cond_clear(&cb_info->event_cond);
+ g_mutex_clear(&cb_info->idle_event_mutex);
+ g_cond_clear(&cb_info->idle_event_cond);
LOGD("event thread removed");
@@ -888,11 +1013,11 @@ int camera_create(camera_device_e device, camera_h* camera)
goto ErrorExit;
}
- pc->cb_info = client_callback_new(sock_fd);
+ pc->cb_info = _client_callback_new(sock_fd);
LOGD("cb info : %d", pc->cb_info->fd);
- ret = client_wait_for_cb_return(api, pc->cb_info, CALLBACK_TIME_OUT);
+ ret = _client_wait_for_cb_return(api, pc->cb_info, CALLBACK_TIME_OUT);
if (ret == CAMERA_ERROR_NONE) {
intptr_t handle = 0;
muse_camera_msg_get_pointer(handle, pc->cb_info->recvMsg);
@@ -918,7 +1043,7 @@ ErrorExit:
bufmgr = NULL;
if (pc) {
- client_callback_destroy(pc->cb_info);
+ _client_callback_destroy(pc->cb_info);
pc->cb_info = NULL;
g_free(pc);
pc = NULL;
@@ -951,7 +1076,8 @@ ErrorExit:
muse_camera_msg_send(api, sock_fd, pc->cb_info, ret);
if (ret == CAMERA_ERROR_NONE) {
- client_callback_destroy(pc->cb_info);
+ _camera_remove_idle_event_all(pc->cb_info);
+ _client_callback_destroy(pc->cb_info);
g_free(pc);
pc = NULL;
} else {
@@ -1035,7 +1161,7 @@ int camera_stop_preview(camera_h camera)
return ret;
}
-int camera_start_capture(camera_h camera, camera_capturing_cb capturing_cb , camera_capture_completed_cb completed_cb , void *user_data)
+int camera_start_capture(camera_h camera, camera_capturing_cb capturing_cb, camera_capture_completed_cb completed_cb, void *user_data)
{
if (camera == NULL) {
LOGE("INVALID_PARAMETER(0x%08x)",CAMERA_ERROR_INVALID_PARAMETER);
diff --git a/test/multimedia_camera_test.c b/test/multimedia_camera_test.c
index 24d40f5..a9597bb 100644
--- a/test/multimedia_camera_test.c
+++ b/test/multimedia_camera_test.c
@@ -63,8 +63,8 @@ int camera_print_state;
int multishot_num;
static GTimer *timer = NULL;
-GTimeVal previous;
-GTimeVal current;
+GTimeVal previous_time;
+GTimeVal current_time;
GTimeVal res;
/*-----------------------------------------------------------------------
@@ -222,7 +222,7 @@ typedef struct{
/*---------------------------------------------------------------------------
| LOCAL VARIABLE DEFINITIONS: |
---------------------------------------------------------------------------*/
-static cam_handle_t *hcamcorder ;
+static cam_handle_t *hcamcorder;
const char *wb[SENSOR_WHITEBALANCE_NUM]={
"None",
@@ -437,6 +437,10 @@ static inline void flush_stdin()
while ((ch=getchar()) != EOF && ch != '\n');
}
+void _camera_state_changed_cb(camera_state_e previous, camera_state_e current,bool by_policy, void *user_data){
+ printf("camera state changed %d -> %d\n", previous , current);
+}
+
bool preview_resolution_cb(int width, int height, void *user_data)
{
resolution_stack *data = (resolution_stack*)user_data;
@@ -620,6 +624,15 @@ void capturing_cb(camera_image_data_s* image, camera_image_data_s* postview, cam
return;
}
+void capture_completed_cb(void *user_data)
+{
+ camera_start_preview(hcamcorder->camera);
+
+ print_menu();
+
+ return;
+}
+
static void print_menu()
{
switch (hcamcorder->menu_state)
@@ -701,9 +714,7 @@ static void main_menu(gchar buf)
camera_get_state(hcamcorder->camera, &capi_state);
camera_attr_set_image_quality(hcamcorder->camera, 100);
camera_set_capture_format(hcamcorder->camera, CAMERA_PIXEL_FORMAT_JPEG);
- camera_start_capture(hcamcorder->camera, capturing_cb,NULL, NULL);
- sleep(3);
- camera_start_preview(hcamcorder->camera);
+ camera_start_capture(hcamcorder->camera, capturing_cb, capture_completed_cb, hcamcorder);
break;
case '2' : //multishot Capture
@@ -727,6 +738,9 @@ static void main_menu(gchar buf)
break;
case 'b' : // back
+ camera_stop_preview(hcamcorder->camera);
+ camera_destroy(hcamcorder->camera);
+ hcamcorder->camera = NULL;
hcamcorder->menu_state = MENU_STATE_MAIN;
mode_change();
break;
@@ -735,9 +749,7 @@ static void main_menu(gchar buf)
g_print("\t Invalid input \n");
break;
}
- }
-
- else {
+ } else {
g_print("\t Invalid mode, back to upper menu \n");
hcamcorder->menu_state = MENU_STATE_MAIN;
mode_change();
@@ -1362,7 +1374,7 @@ static gboolean mode_change()
}
LOGD("camcorder_create");
- g_get_current_time(&previous);
+ g_get_current_time(&previous_time);
g_timer_reset(timer);
err = camera_create(cam_info,&hcamcorder->camera);
@@ -1376,12 +1388,13 @@ static gboolean mode_change()
}
camera_print_state = CAMERA_STATE_CREATED;
+ camera_set_state_changed_cb(hcamcorder->camera, _camera_state_changed_cb, NULL);
camera_set_display_mode(hcamcorder->camera,0 ); //MM_DISPLAY_METHOD_LETTER_BOX
camera_set_display(hcamcorder->camera,CAMERA_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(eo));
camera_start_preview(hcamcorder->camera);
- g_get_current_time(&current);
- timersub(&current, &previous, &res);
+ g_get_current_time(&current_time);
+ timersub(&current_time, &previous_time, &res);
LOGD("Camera Starting Time : %ld.%lds", res.tv_sec, res.tv_usec);
camera_print_state = CAMERA_STATE_PREVIEW;