From 411b1395f719d092e8ca908ee5fdca3ce743b1dc Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Tue, 29 Dec 2020 17:59:44 +0900 Subject: [PATCH] Support continuous capture [Version] 0.0.13 [Issue Type] Update Change-Id: Id61d1eab11c10c8f11dae08bf65a15061e049323 Signed-off-by: Jeongmo Yang --- packaging/camera-hal-v4l2.spec | 2 +- src/tizen_camera_v4l2.c | 133 +++++++++++++++++++++++++--------------- src/tizen_camera_v4l2_private.h | 1 + 3 files changed, 85 insertions(+), 51 deletions(-) diff --git a/packaging/camera-hal-v4l2.spec b/packaging/camera-hal-v4l2.spec index 353c6a3..61e7eee 100644 --- a/packaging/camera-hal-v4l2.spec +++ b/packaging/camera-hal-v4l2.spec @@ -1,6 +1,6 @@ Name: camera-hal-v4l2 Summary: Tizen Camera Hal for V4L2 -Version: 0.0.12 +Version: 0.0.13 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/tizen_camera_v4l2.c b/src/tizen_camera_v4l2.c index 0ade153..11c1b32 100644 --- a/src/tizen_camera_v4l2.c +++ b/src/tizen_camera_v4l2.c @@ -774,6 +774,9 @@ static void __camera_do_capture(camera_hal_handle *handle) { int ret = CAMERA_ERROR_NONE; int buffer_index = 0; + gint64 current_time = 0; + gint64 previous_time = 0; + gint64 interval_us = 0; if (!handle) { LOGE("NULL handle"); @@ -782,6 +785,9 @@ static void __camera_do_capture(camera_hal_handle *handle) LOGD("start"); + if (handle->capture_count > 1) + interval_us = handle->capture_interval_ms * 1000; + /* restart stream for capture */ if (handle->capture_restart_stream) { ret = __camera_stop_stream(handle, handle->buffer_count); @@ -801,41 +807,65 @@ static void __camera_do_capture(camera_hal_handle *handle) } } - /* get capture buffer */ - ret = __camera_v4l2_wait_frame(handle->device_fd, 5); - if (ret != CAMERA_ERROR_NONE) { - LOGE("frame wait failed for capture[0x%x]", ret); - goto _CAPTURE_DONE; - } + do { + /* get capture buffer */ + ret = __camera_v4l2_wait_frame(handle->device_fd, 5); + if (ret != CAMERA_ERROR_NONE) { + LOGE("frame wait failed for capture[0x%x]", ret); + goto _CAPTURE_DONE; + } - ret = __camera_v4l2_dqbuf(handle->device_fd, - handle->buffer_type, V4L2_MEMORY_MMAP, &buffer_index); - if (ret != CAMERA_ERROR_NONE) { - LOGE("dqbuf failed for capture[0x%x]", ret); - goto _CAPTURE_DONE; - } + ret = __camera_v4l2_dqbuf(handle->device_fd, + handle->buffer_type, V4L2_MEMORY_MMAP, &buffer_index); + if (ret != CAMERA_ERROR_NONE) { + LOGE("dqbuf failed for capture[0x%x]", ret); + goto _CAPTURE_DONE; + } - g_mutex_lock(&handle->buffer_lock); + if (handle->captured_count > 0) { + g_mutex_lock(&handle->buffer_lock); + if (handle->state != CAMERA_STATE_CAPTURING) { + LOGW("stop continuous capture"); + handle->captured_count = handle->capture_count; + g_mutex_unlock(&handle->buffer_lock); + goto _TRY_NEXT; + } + g_mutex_unlock(&handle->buffer_lock); + } - handle->captured_count++; + if (handle->capture_count > 1) { + current_time = g_get_monotonic_time(); - g_mutex_unlock(&handle->buffer_lock); + LOGI("time[prev:%"PRId64", cur:%"PRId64"] interval[%"PRId64" us]", + previous_time, current_time, interval_us); - LOGD("capture cb[%p], buffer index[%d],count[%d]", - handle->capture_cb, buffer_index, handle->captured_count); + if (current_time < previous_time + interval_us) + goto _TRY_NEXT; + } - if (handle->capture_cb) { - ((camera_capture_cb)handle->capture_cb)(&handle->camera_buffers[buffer_index], - NULL, NULL, handle->capture_cb_data); - } else { - LOGW("capture callback is NULL"); - /* Need to post error? */ - } + g_mutex_lock(&handle->buffer_lock); + handle->captured_count++; + g_mutex_unlock(&handle->buffer_lock); - ret = __camera_v4l2_qbuf(handle->device_fd, - handle->buffer_type, V4L2_MEMORY_MMAP, buffer_index); - if (ret != CAMERA_ERROR_NONE) - LOGE("qbuf failed for capture[0x%x]", ret); + LOGD("capture cb[%p], buffer index[%d],count[%d]", + handle->capture_cb, buffer_index, handle->captured_count); + + if (handle->capture_cb) { + ((camera_capture_cb)handle->capture_cb)(&handle->camera_buffers[buffer_index], + NULL, NULL, handle->capture_cb_data); + } else { + LOGW("capture callback is NULL"); + /* Need to post error? */ + } + + previous_time = current_time; + +_TRY_NEXT: + ret = __camera_v4l2_qbuf(handle->device_fd, + handle->buffer_type, V4L2_MEMORY_MMAP, buffer_index); + if (ret != CAMERA_ERROR_NONE) + LOGE("qbuf failed for capture[0x%x]", ret); + } while (handle->captured_count < handle->capture_count); g_mutex_lock(&handle->buffer_lock); @@ -875,11 +905,11 @@ static void *__camera_buffer_handler_func(gpointer data) camera_hal_handle *handle = (camera_hal_handle *)data; if (!handle) { - LOGE("NULL handle for preview handler"); + LOGE("NULL handle for buffer handler"); return NULL; } - LOGD("enter - preview handler thread"); + LOGD("enter"); /* run buffer thread */ g_mutex_lock(&handle->buffer_lock); @@ -896,7 +926,7 @@ static void *__camera_buffer_handler_func(gpointer data) g_mutex_lock(&handle->buffer_lock); if (handle->buffer_thread_run == FALSE) { - LOGW("stop preview handler thread"); + LOGW("stop buffer handler thread"); break; } @@ -931,7 +961,7 @@ static void *__camera_buffer_handler_func(gpointer data) g_mutex_unlock(&handle->buffer_lock); - LOGD("leave - preview handler thread"); + LOGD("leave"); return NULL; } @@ -1695,13 +1725,13 @@ int camera_start_capture(void *camera_handle, camera_capture_cb callback, void * /* reset captured count */ handle->captured_count = 0; + LOGD("start capture - count %u", handle->capture_count); + /* set capture request flag */ handle->capture_request = TRUE; handle->state = CAMERA_STATE_CAPTURING; - LOGD("start capture"); - g_mutex_unlock(&handle->lock); return CAMERA_ERROR_NONE; @@ -1829,11 +1859,11 @@ int camera_set_command(void *camera_handle, int64_t command, void *value) if (handle->state < CAMERA_STATE_OPENED) { LOGE("invalid state %d", handle->state); - g_mutex_unlock(&handle->lock); - return CAMERA_ERROR_INVALID_STATE; + ret = CAMERA_ERROR_INVALID_STATE; + goto _SET_COMMAND_DONE; } - LOGD("set command %"PRId64" - state %d", command, handle->state); + LOGD("set command %"PRIx64" - state %d", command, handle->state); switch (command) { case CAMERA_COMMAND_BRIGHTNESS: @@ -1849,14 +1879,11 @@ int camera_set_command(void *camera_handle, int64_t command, void *value) cid = V4L2_CID_SHARPNESS; break; case CAMERA_COMMAND_PTZ_TYPE: - g_mutex_unlock(&handle->lock); - if (set_value != CAMERA_PTZ_TYPE_ELECTRONIC) { LOGE("not supported PTZ type %d", set_value); - return CAMERA_ERROR_DEVICE_NOT_SUPPORTED; + ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED; } - - return CAMERA_ERROR_NONE; + goto _SET_COMMAND_DONE; case CAMERA_COMMAND_PAN: cid = V4L2_CID_PAN_ABSOLUTE; break; @@ -1864,18 +1891,23 @@ int camera_set_command(void *camera_handle, int64_t command, void *value) cid = V4L2_CID_TILT_ABSOLUTE; break; case CAMERA_COMMAND_FLIP: - g_mutex_unlock(&handle->lock); if (set_value != CAMERA_FLIP_NONE) { LOGE("NOT_SUPPORTED flip %d", set_value); - return CAMERA_ERROR_DEVICE_NOT_SUPPORTED; - } else { - return CAMERA_ERROR_NONE; + ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED; } - break; + goto _SET_COMMAND_DONE; + case CAMERA_COMMAND_CAPTURE_COUNT: + handle->capture_count = set_value; + LOGI("capture count %u", handle->capture_count); + goto _SET_COMMAND_DONE; + case CAMERA_COMMAND_CAPTURE_INTERVAL: + handle->capture_interval_ms = set_value; + LOGI("capture interval %u ms", handle->capture_interval_ms); + goto _SET_COMMAND_DONE; default: - LOGE("NOT_SUPPORTED %"PRId64, command); - g_mutex_unlock(&handle->lock); - return CAMERA_ERROR_DEVICE_NOT_SUPPORTED; + LOGE("NOT_SUPPORTED command %"PRIx64, command); + ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED; + goto _SET_COMMAND_DONE; } ctrl_ret = __camera_v4l2_s_ctrl(handle->device_fd, cid, set_value); @@ -1905,6 +1937,7 @@ int camera_set_command(void *camera_handle, int64_t command, void *value) } } +_SET_COMMAND_DONE: g_mutex_unlock(&handle->lock); return ret; diff --git a/src/tizen_camera_v4l2_private.h b/src/tizen_camera_v4l2_private.h index c6abc44..035316b 100644 --- a/src/tizen_camera_v4l2_private.h +++ b/src/tizen_camera_v4l2_private.h @@ -58,6 +58,7 @@ typedef struct _camera_hal_handle { camera_capture_cb capture_cb; gpointer capture_cb_data; guint32 capture_count; + guint32 capture_interval_ms; guint32 captured_count; gboolean capture_request; gboolean capture_restart_stream; -- 2.7.4