From d4fceb73984d283726a641511cd90ad8af7d86cd Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Mon, 6 Dec 2021 21:41:15 +0900 Subject: [PATCH] fix up! Remove thread for preview callback when stop preview - The deadlock is occurred with below sequence. 1. camera_start_preview() -> create thread for preview callback 2. camera_start_capture() 3. got capture_completed_cb() 4. camera_start_preview() -> create new thread for preview callback and the old one is remained. 5. camera_stop_preview() -> send signal to remove thread for preview callback, but 1 thread is remained. [Version] 0.4.68 [Issue Type] Bug fix Change-Id: Id137ef203b1e0c85f597c05ae818ecb2a1b6c679 Signed-off-by: Jeongmo Yang --- packaging/capi-media-camera.spec | 2 +- src/camera.c | 66 ++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec index 9a4d5f8..8e2032b 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.4.67 +Version: 0.4.68 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/camera.c b/src/camera.c index 2ec2d1f..578efee 100644 --- a/src/camera.c +++ b/src/camera.c @@ -2606,6 +2606,7 @@ int camera_destroy(camera_h camera) int camera_start_preview(camera_h camera) { int ret = CAMERA_ERROR_NONE; + int *fds = NULL; muse_camera_api_e api = MUSE_CAMERA_API_START_PREVIEW; camera_cli_s *pc = (camera_cli_s *)camera; camera_state_e current_state = CAMERA_STATE_NONE; @@ -2618,12 +2619,6 @@ int camera_start_preview(camera_h camera) CAM_LOG_INFO("Enter : preview format %d, display type %d", pc->cb_info->preview_format, pc->cb_info->dp_info.type); - ret = camera_get_state(camera, ¤t_state); - if (ret != CAMERA_ERROR_NONE) { - CAM_LOG_ERROR("failed to get current state 0x%x", ret); - return ret; - } - if (pc->cb_info->preview_format == CAMERA_PIXEL_FORMAT_INVZ && pc->cb_info->dp_info.type != CAMERA_DISPLAY_TYPE_NONE) { CAM_LOG_ERROR("CAMERA_DISPLAY_TYPE_NONE[current %d] should be set with INVZ format", @@ -2631,36 +2626,55 @@ int camera_start_preview(camera_h camera) return CAMERA_ERROR_INVALID_OPERATION; } - /* message handler thread for preview callback */ - if (!__create_msg_handler_thread(&pc->cb_info->preview_cb_info, - CAMERA_MESSAGE_HANDLER_TYPE_PREVIEW_CB, "camera_msg_handler:preview_cb", pc->cb_info)) { - CAM_LOG_ERROR("preview_cb_info failed"); - return CAMERA_ERROR_INVALID_OPERATION; + ret = camera_get_state(camera, ¤t_state); + if (ret != CAMERA_ERROR_NONE) { + CAM_LOG_ERROR("failed to get current state 0x%x", ret); + return ret; } - if (current_state == CAMERA_STATE_CREATED && pc->cb_info->user_buffer_supported) { - if (__camera_allocate_preview_buffer(camera)) - _camera_msg_send(api, pc->cb_info->fds, pc->cb_info, &ret, CAMERA_CB_NO_TIMEOUT); - else - ret = CAMERA_ERROR_INVALID_OPERATION; - } else { - _camera_msg_send(api, NULL, pc->cb_info, &ret, CAMERA_CB_NO_TIMEOUT); - } + if (current_state == CAMERA_STATE_CREATED) { + if (!__create_msg_handler_thread(&pc->cb_info->preview_cb_info, + CAMERA_MESSAGE_HANDLER_TYPE_PREVIEW_CB, "camera_msg_handler:preview_cb", pc->cb_info)) { + CAM_LOG_ERROR("preview_cb_info failed"); + return CAMERA_ERROR_INVALID_OPERATION; + } - if (ret == CAMERA_ERROR_NONE) { - if (pc->cb_info->is_evas_render) { - ret = _camera_start_evas_rendering(camera); - if (ret != CAMERA_ERROR_NONE) { - CAM_LOG_ERROR("stop preview because of error"); - _camera_msg_send(MUSE_CAMERA_API_STOP_PREVIEW, NULL, pc->cb_info, NULL, 0); + if (pc->cb_info->user_buffer_supported) { + if (!__camera_allocate_preview_buffer(camera)) { + ret = CAMERA_ERROR_INVALID_OPERATION; + goto _START_FAILED; } + + fds = pc->cb_info->fds; } } + _camera_msg_send(api, fds, pc->cb_info, &ret, CAMERA_CB_NO_TIMEOUT); if (ret != CAMERA_ERROR_NONE) + goto _START_FAILED; + + if (pc->cb_info->is_evas_render) { + ret = _camera_start_evas_rendering(camera); + if (ret != CAMERA_ERROR_NONE) { + CAM_LOG_ERROR("stop preview because of error"); + _camera_msg_send(MUSE_CAMERA_API_STOP_PREVIEW, NULL, pc->cb_info, NULL, 0); + goto _START_FAILED; + } + } + + CAM_LOG_INFO("done"); + + return CAMERA_ERROR_NONE; + +_START_FAILED: + if (current_state == CAMERA_STATE_CREATED) { + if (pc->cb_info->user_buffer_supported) + __camera_release_preview_buffer(camera); + __destroy_msg_handler_thread(&pc->cb_info->preview_cb_info); + } - CAM_LOG_INFO("ret : 0x%x", ret); + CAM_LOG_ERROR("failed : 0x%x", ret); return ret; } -- 2.7.4