From 3686f60a6d0cec33476acd3becd12226f9238b54 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Tue, 6 Apr 2021 11:52:27 +0900 Subject: [PATCH] Revise code for fd and tbm bo management - Additional minor change : Correct the condition to send message for preview callback return. : Add log to trace fd and buffer. : Add menu for writing preview data in preview callback in camera_test. [Version] 0.4.51 [Issue Type] Revise Change-Id: Ic04c7d77743331a6eb7ce2114fc436f15bfbc64b Signed-off-by: Jeongmo Yang --- include/camera_private.h | 3 + packaging/capi-media-camera.spec | 2 +- src/camera.c | 148 ++++++++++++++++++++++----------------- test/camera_test.c | 83 +++++++++++----------- 4 files changed, 129 insertions(+), 107 deletions(-) diff --git a/include/camera_private.h b/include/camera_private.h index fe6eb16..814978e 100644 --- a/include/camera_private.h +++ b/include/camera_private.h @@ -32,6 +32,9 @@ extern "C" { #define CAMERA_CB_TIMEOUT 4 #define CAMERA_CB_NO_TIMEOUT 0 +#define CAMERA_FD_INIT -1 + +#define CAMERA_IS_FD_VALID(fd) (fd > CAMERA_FD_INIT) #define CAMERA_MSG_PARAM_SET(param, msg_type, set_value) { \ param.type = MUSE_TYPE_##msg_type; \ diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec index 46eefa0..2c6d174 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.50 +Version: 0.4.51 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/camera.c b/src/camera.c index d29e654..0a1d6aa 100644 --- a/src/camera.c +++ b/src/camera.c @@ -162,9 +162,9 @@ static void __camera_release_preview_buffer(camera_h camera) break; } - if (cb_info->fds[i] >= 0) { + if (CAMERA_IS_FD_VALID(cb_info->fds[i])) { close(cb_info->fds[i]); - cb_info->fds[i] = -1; + cb_info->fds[i] = CAMERA_FD_INIT; } } @@ -241,8 +241,8 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv { int i = 0; int ret = 0; - int ret_fd = -1; - int preview_fd = -1; + int ret_fd = CAMERA_FD_INIT; + int preview_fd = CAMERA_FD_INIT; int num_buffer_fd = 0; unsigned char *buf_pos = NULL; @@ -289,7 +289,7 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv goto _PREVIEW_CB_HANDLER_DONE; } - if (num_buffer_fd == 0 && tfd[1] >= 0) { + if (num_buffer_fd == 0 && CAMERA_IS_FD_VALID(tfd[1])) { /* import tbm data_bo and get virtual address */ if (!__camera_import_tbm_fd(cb_info->bufmgr, tfd[1], &data_bo, &data_bo_handle)) { CAM_LOG_ERROR("failed to import data fd %d", tfd[1]); @@ -367,9 +367,11 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv } _PREVIEW_CB_HANDLER_DONE: - /* send message for preview callback return */ - if (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW] || - cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_MEDIA_PACKET_PREVIEW]) + /* send PREVIEW_CB_RETURN message if zero copy buffer is used(num_buffer_fd is bigger than 0) + and preview callback(normal or media packet) is set. */ + if (num_buffer_fd > 0 && + (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW] || + cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_MEDIA_PACKET_PREVIEW])) _camera_msg_send(MUSE_CAMERA_API_PREVIEW_CB_RETURN, NULL, cb_info, NULL, 0); if (pkt) { @@ -382,19 +384,17 @@ _PREVIEW_CB_HANDLER_DONE: CAM_LOG_DEBUG("return buffer Done[tfd:%d, ret fd:%d]", tfd[0], ret_fd); - /* release imported bo */ - for (i = 0 ; i < num_buffer_fd && i < BUFFER_MAX_PLANE_NUM ; i++) - __camera_release_imported_bo(&buffer_bo[i]); - - /* unmap and unref tbm bo */ + /* release imported bo and fd */ __camera_release_imported_bo(&data_bo); __camera_release_imported_bo(&bo); - /* close imported fd */ + for (i = 0 ; i < num_buffer_fd && i < BUFFER_MAX_PLANE_NUM ; i++) + __camera_release_imported_bo(&buffer_bo[i]); + for (i = 0 ; i < MUSE_NUM_FD ; i++) { - if (tfd[i] >= 0) { + if (CAMERA_IS_FD_VALID(tfd[i])) { close(tfd[i]); - tfd[i] = -1; + tfd[i] = CAMERA_FD_INIT; } else { break; } @@ -464,7 +464,7 @@ static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv CAM_LOG_INFO("image info %dx%d, size %d, EXIF info %p, size %d", rImage->width, rImage->height, rImage->size, rImage->exif, rImage->exif_size); - if (capture_fd_post >= 0) { + if (CAMERA_IS_FD_VALID(capture_fd_post)) { /* import tbm bo and get virtual address */ tfd_index++; if (__camera_import_tbm_fd(cb_info->bufmgr, tfd[tfd_index], &bo_post, &bo_post_handle)) { @@ -477,7 +477,7 @@ static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv } } - if (capture_fd_thumb >= 0) { + if (CAMERA_IS_FD_VALID(capture_fd_thumb)) { /* import tbm bo and get virtual address */ tfd_index++; if (__camera_import_tbm_fd(cb_info->bufmgr, tfd[tfd_index], &bo_thumb, &bo_thumb_handle)) { @@ -495,26 +495,26 @@ static void __camera_event_handler_capture(camera_cb_info_s *cb_info, char *recv _CAPTURE_CB_HANDLER_DONE: /* return buffer */ - if (capture_fd_main >= 0) { + if (CAMERA_IS_FD_VALID(capture_fd_main)) { __camera_release_imported_bo(&bo_main); _camera_msg_return_buffer(capture_fd_main, cb_info); } - if (capture_fd_post >= 0) { + if (CAMERA_IS_FD_VALID(capture_fd_post)) { __camera_release_imported_bo(&bo_post); _camera_msg_return_buffer(capture_fd_post, cb_info); } - if (capture_fd_thumb >= 0) { + if (CAMERA_IS_FD_VALID(capture_fd_thumb)) { __camera_release_imported_bo(&bo_thumb); _camera_msg_return_buffer(capture_fd_thumb, cb_info); } for (i = 0 ; i < MUSE_NUM_FD ; i++) { - if (tfd[i] >= 0) { - CAM_LOG_INFO("close %d", tfd[i]); + if (CAMERA_IS_FD_VALID(tfd[i])) { + CAM_LOG_INFO("close tfd[%d] %d", i, tfd[i]); close(tfd[i]); - tfd[i] = -1; + tfd[i] = CAMERA_FD_INIT; } else { break; } @@ -527,7 +527,7 @@ _CAPTURE_CB_HANDLER_DONE: static void __camera_event_handler_face_detection(camera_cb_info_s *cb_info, char *recv_msg, int *tfd) { int count = 0; - int face_fd = -1; + int face_fd = CAMERA_FD_INIT; camera_detected_face_s *faces = NULL; tbm_bo bo = NULL; @@ -544,14 +544,14 @@ static void __camera_event_handler_face_detection(camera_cb_info_s *cb_info, cha if (count >= 0 && cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_FACE_DETECTION]) { CAM_LOG_INFO("FACE_DETECTION - count %d, fd %d", count, tfd[0]); - if (tfd[0] >= 0) { + if (CAMERA_IS_FD_VALID(tfd[0])) { if (__camera_import_tbm_fd(cb_info->bufmgr, tfd[0], &bo, &bo_handle)) { /* set face info */ faces = bo_handle.ptr; } close(tfd[0]); - tfd[0] = -1; + tfd[0] = CAMERA_FD_INIT; } ((camera_face_detected_cb)cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_FACE_DETECTION])(faces, @@ -1013,6 +1013,11 @@ static int __camera_media_packet_data_create(int ret_fd, int *tfd, int num_buffe CAM_LOG_VERBOSE(" [%d] bo[%p], fd[%d]", i, new_mp_data->buffer_bo[i], new_mp_data->buffer_fd[i]); } + + for (i = num_buffer_fd ; i < MUSE_NUM_FD ; i++) + new_mp_data->buffer_fd[i] = CAMERA_FD_INIT; + + new_mp_data->data_fd = CAMERA_FD_INIT; } *mp_data = new_mp_data; @@ -1033,26 +1038,39 @@ static void __camera_media_packet_data_release(camera_media_packet_data *mp_data CAM_LOG_VERBOSE("tfd[%d], ret fd[%d]", mp_data->fd, mp_data->ret_fd); - /* release imported bo and close imported fd */ + /* release imported bo and close fd */ for (i = 0 ; i < mp_data->num_buffer_fd ; i++) { + CAM_LOG_VERBOSE(" release buffer[%d] fd[%d],bo[%p]", + i, mp_data->buffer_fd[i], mp_data->buffer_bo[i]); + tbm_bo_unref(mp_data->buffer_bo[i]); - mp_data->buffer_bo[i] = NULL; - close(mp_data->buffer_fd[i]); - mp_data->buffer_fd[i] = -1; + if (CAMERA_IS_FD_VALID(mp_data->buffer_fd[i])) + close(mp_data->buffer_fd[i]); + else + CAM_LOG_WARNING("invalid fd[%d] for buffer[%d]", mp_data->buffer_fd[i], i); } - /* unref tbm bo and close imported fd */ - close(mp_data->fd); - mp_data->fd = -1; + if (mp_data->data_bo) { + CAM_LOG_VERBOSE("release data_fd[%d],data_bo[%p]", + mp_data->data_fd, mp_data->data_bo); - __camera_release_imported_bo(&mp_data->bo); + tbm_bo_unref(mp_data->data_bo); - if (mp_data->data_bo && mp_data->data_fd >= 0) { - close(mp_data->data_fd); - mp_data->data_fd = -1; + if (CAMERA_IS_FD_VALID(mp_data->data_fd)) + close(mp_data->data_fd); + else + CAM_LOG_WARNING("invalid data_fd[%d]", mp_data->data_fd); } - __camera_release_imported_bo(&mp_data->data_bo); + + CAM_LOG_VERBOSE("release fd[%d],bo[%p]", mp_data->fd, mp_data->bo); + + tbm_bo_unref(mp_data->bo); + + if (CAMERA_IS_FD_VALID(mp_data->fd)) + close(mp_data->fd); + else + CAM_LOG_WARNING("invalid fd[%d]", mp_data->fd); /* return buffer */ _camera_msg_return_buffer(mp_data->ret_fd, cb_info); @@ -1243,6 +1261,8 @@ static int __camera_media_packet_create(camera_cb_info_s *cb_info, camera_stream if (media_packet_set_pts(pkt, (uint64_t)(stream->timestamp) * 1000000) != MEDIA_PACKET_ERROR_NONE) CAM_LOG_WARNING("media_packet_set_pts failed"); + CAM_LOG_VERBOSE("new media packet[%p], tbm surface[%p]", pkt, tsurf); + *packet = pkt; return CAMERA_ERROR_NONE; @@ -1274,23 +1294,19 @@ void _camera_media_packet_dispose(media_packet_h pkt, void *user_data) return; } - CAM_LOG_VERBOSE("mp_data[%p]", mp_data); + ret = media_packet_get_tbm_surface(pkt, &tsurf); + if (ret != MEDIA_PACKET_ERROR_NONE) + CAM_LOG_ERROR("get tbm_surface failed 0x%x", ret); - g_mutex_lock(&cb_info->mp_data_mutex); + CAM_LOG_VERBOSE("media packet[%p] - mp_data[%p],tsurf[%p]", + pkt, mp_data, tsurf); + g_mutex_lock(&cb_info->mp_data_mutex); __camera_media_packet_data_release(mp_data, cb_info); - mp_data = NULL; - g_mutex_unlock(&cb_info->mp_data_mutex); - ret = media_packet_get_tbm_surface(pkt, &tsurf); - if (ret != MEDIA_PACKET_ERROR_NONE) - CAM_LOG_ERROR("get tbm_surface failed 0x%x", ret); - - if (tsurf) { + if (tsurf) tbm_surface_destroy(tsurf); - tsurf = NULL; - } } static void __camera_client_user_callback(camera_cb_info_s *cb_info, char *recv_msg, muse_camera_event_e event, int *tfd) @@ -1729,7 +1745,7 @@ static void __camera_add_msg_to_queue(camera_cb_info_s *cb_info, int api, int ev cam_msg->event = event; cam_msg->event_class = event_class; - if (tfd && tfd[0] >= 0) + if (tfd && CAMERA_IS_FD_VALID(tfd[0])) memcpy(cam_msg->tfd, tfd, sizeof(cam_msg->tfd)); strncpy(cam_msg->recv_msg, msg, sizeof(cam_msg->recv_msg) - 1); @@ -1882,7 +1898,7 @@ static gpointer __camera_msg_recv_func(gpointer data) { int i = 0; int recv_length = 0; - int tfd[MUSE_NUM_FD] = {-1, -1, -1, -1}; + int tfd[MUSE_NUM_FD] = {CAMERA_FD_INIT, CAMERA_FD_INIT, CAMERA_FD_INIT, CAMERA_FD_INIT}; char *recv_msg = NULL; camera_cb_info_s *cb_info = (camera_cb_info_s *)data; @@ -1897,7 +1913,7 @@ static gpointer __camera_msg_recv_func(gpointer data) while (g_atomic_int_get(&cb_info->msg_recv_running)) { for (i = 0 ; i < MUSE_NUM_FD ; i++) - tfd[i] = -1; + tfd[i] = CAMERA_FD_INIT; recv_length = muse_core_msg_recv_fd(cb_info->fd, recv_msg, MUSE_MSG_MAX_LENGTH, tfd); if (recv_length <= 0) { @@ -1906,7 +1922,7 @@ static gpointer __camera_msg_recv_func(gpointer data) break; } - if (tfd[0] >= 0) + if (CAMERA_IS_FD_VALID(tfd[0])) CAM_LOG_DEBUG("tfd[%d/%d/%d/%d]", tfd[0], tfd[1], tfd[2], tfd[3]); recv_msg[recv_length] = '\0'; @@ -2098,7 +2114,7 @@ static camera_cb_info_s *__camera_client_callback_new(gint sockfd) /* initialize fd */ for (i = 0 ; i < MUSE_NUM_FD ; i++) - cb_info->fds[i] = -1; + cb_info->fds[i] = CAMERA_FD_INIT; cb_info->is_server_connected = TRUE; @@ -2158,9 +2174,9 @@ static void __camera_client_callback_destroy(camera_cb_info_s *cb_info) g_cond_clear(&cb_info->api_cond[i]); } - if (cb_info->fd > -1) { + if (CAMERA_IS_FD_VALID(cb_info->fd)) { muse_client_close(cb_info->fd); - cb_info->fd = -1; + cb_info->fd = CAMERA_FD_INIT; } if (cb_info->bufmgr) { @@ -2241,7 +2257,7 @@ int _camera_stop_evas_rendering(camera_h camera, bool keep_screen) int _camera_independent_request(int api, int device_type, const char *key, int *value) { int ret = CAMERA_ERROR_NONE; - int sock_fd = -1; + int sock_fd = CAMERA_FD_INIT; int module_index = -1; char *msg = NULL; char recv_msg[MUSE_CAMERA_MSG_MAX_LENGTH] = {'\0',}; @@ -2304,9 +2320,9 @@ int _camera_independent_request(int api, int device_type, const char *key, int * CAM_LOG_INFO("api %d - value %d", api, *value); _REQUEST_EXIT: - if (sock_fd > -1) { + if (CAMERA_IS_FD_VALID(sock_fd)) { muse_client_close(sock_fd); - sock_fd = -1; + sock_fd = CAMERA_FD_INIT; } return ret; @@ -2315,7 +2331,7 @@ _REQUEST_EXIT: int _camera_create_private(camera_device_e device, bool is_network, camera_h *camera) { - int sock_fd = -1; + int sock_fd = CAMERA_FD_INIT; char *send_msg = NULL; int send_ret = 0; int ret = CAMERA_ERROR_NONE; @@ -2390,7 +2406,7 @@ int _camera_create_private(camera_device_e device, bool is_network, camera_h *ca goto ErrorExit; } - sock_fd = -1; + sock_fd = CAMERA_FD_INIT; CAM_LOG_INFO("cb info : %d", pc->cb_info->fd); @@ -2442,9 +2458,9 @@ ErrorExit: bufmgr = NULL; } - if (sock_fd > -1) { + if (CAMERA_IS_FD_VALID(sock_fd)) { muse_client_close(sock_fd); - sock_fd = -1; + sock_fd = CAMERA_FD_INIT; } if (pc) { @@ -2454,8 +2470,8 @@ ErrorExit: /* pc->cb_info->fd should be closed, because g_thread_join for msg_recv_thread is not returned in __camera_client_callback_destroy. */ - if (temp_fd > -1) { - pc->cb_info->fd = -1; + if (CAMERA_IS_FD_VALID(temp_fd)) { + pc->cb_info->fd = CAMERA_FD_INIT; muse_client_close(temp_fd); } diff --git a/test/camera_test.c b/test/camera_test.c index e311c35..87ef1a6 100644 --- a/test/camera_test.c +++ b/test/camera_test.c @@ -65,6 +65,7 @@ static camera_device_e camera_device; static GTimer *timer; static int g_camera_device_state_changed_cb_id; static int g_camera_device_list_changed_cb_id; +static int g_camera_preview_cb_file_write; static struct timeval previous_time; static struct timeval current_time; @@ -485,49 +486,51 @@ static void _camera_interrupt_started_cb(camera_policy_e policy, camera_state_e void _camera_preview_cb(camera_preview_data_s *frame, void *user_data) { -#if 1 - char preview_dump[MAX_FILE_NAME_LENGTH] = {'\0',}; - FILE *fp = NULL; + if (g_camera_preview_cb_file_write) { + char preview_dump[MAX_FILE_NAME_LENGTH] = {'\0',}; + FILE *fp = NULL; - snprintf(preview_dump, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, PREVIEW_CB_DUMP_FILE_NAME); + snprintf(preview_dump, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, PREVIEW_CB_DUMP_FILE_NAME); - fp = fopen(preview_dump, "a"); - if (fp == NULL) { - g_print("\n==== file[%s] open failed ====\n", preview_dump); - return; - } + fp = fopen(preview_dump, "a"); + if (fp == NULL) { + g_print("\n==== file[%s] open failed ====\n", preview_dump); + return; + } - if (frame->format == CAMERA_PIXEL_FORMAT_RGBA || - frame->format == CAMERA_PIXEL_FORMAT_ARGB) { - fwrite(frame->data.rgb_plane.data, 1, frame->data.rgb_plane.size, fp); - } else if (frame->format == CAMERA_PIXEL_FORMAT_INVZ) { - fwrite(frame->data.depth_plane.data, 1, frame->data.depth_plane.size, fp); - } else if (frame->format == CAMERA_PIXEL_FORMAT_MJPEG) { - fwrite(frame->data.encoded_plane.data, 1, frame->data.encoded_plane.size, fp); - } else { - switch (frame->num_of_planes) { - case 1: - fwrite(frame->data.single_plane.yuv, 1, frame->data.single_plane.size, fp); - break; - case 2: - fwrite(frame->data.double_plane.y, 1, frame->data.double_plane.y_size, fp); - fwrite(frame->data.double_plane.uv, 1, frame->data.double_plane.uv_size, fp); - break; - case 3: - fwrite(frame->data.triple_plane.y, 1, frame->data.triple_plane.y_size, fp); - fwrite(frame->data.triple_plane.u, 1, frame->data.triple_plane.u_size, fp); - fwrite(frame->data.triple_plane.v, 1, frame->data.triple_plane.v_size, fp); - break; - default: - break; + if (frame->format == CAMERA_PIXEL_FORMAT_RGBA || + frame->format == CAMERA_PIXEL_FORMAT_ARGB) { + fwrite(frame->data.rgb_plane.data, 1, frame->data.rgb_plane.size, fp); + } else if (frame->format == CAMERA_PIXEL_FORMAT_INVZ) { + fwrite(frame->data.depth_plane.data, 1, frame->data.depth_plane.size, fp); + } else if (frame->format == CAMERA_PIXEL_FORMAT_MJPEG) { + fwrite(frame->data.encoded_plane.data, 1, frame->data.encoded_plane.size, fp); + } else { + switch (frame->num_of_planes) { + case 1: + fwrite(frame->data.single_plane.yuv, 1, frame->data.single_plane.size, fp); + break; + case 2: + fwrite(frame->data.double_plane.y, 1, frame->data.double_plane.y_size, fp); + fwrite(frame->data.double_plane.uv, 1, frame->data.double_plane.uv_size, fp); + break; + case 3: + fwrite(frame->data.triple_plane.y, 1, frame->data.triple_plane.y_size, fp); + fwrite(frame->data.triple_plane.u, 1, frame->data.triple_plane.u_size, fp); + fwrite(frame->data.triple_plane.v, 1, frame->data.triple_plane.v_size, fp); + break; + default: + break; + } } - } - g_print("==== file[%s] write done ====\n", preview_dump); + g_print("==== file[%s] write done ====\n", preview_dump); + + fclose(fp); + + return; + } - fclose(fp); - fp = NULL; -#else g_print("----- preview callback - format %d, %dx%d, num plane %d\n", frame->format, frame->width, frame->height, frame->num_of_planes); if (frame->num_of_planes == 1) { @@ -545,9 +548,6 @@ void _camera_preview_cb(camera_preview_data_s *frame, void *user_data) } else { g_print("invalid num of planes %d\n", frame->num_of_planes); } -#endif - - return; } @@ -911,6 +911,9 @@ static void main_menu(gchar buf) camera_start_preview(hcamcorder->camera); break; case '5': + g_print("\n\tWrite preview data to file(0:NO, Others:YES) : "); + err = scanf("%d", &g_camera_preview_cb_file_write); + flush_stdin(); camera_set_preview_cb(hcamcorder->camera, _camera_preview_cb, hcamcorder->camera); break; case '6': -- 2.7.4