diff options
author | Jeongmo Yang <jm80.yang@samsung.com> | 2021-04-19 17:16:44 +0900 |
---|---|---|
committer | Jeongmo Yang <jm80.yang@samsung.com> | 2021-04-28 18:30:44 +0900 |
commit | 3a8027229c119e14d574db3501726daafad38188 (patch) | |
tree | 342f094cfdd953c626b766feb134e607cf102c4d | |
parent | f502f9116ff94bb06750ee247164300f4baa2242 (diff) | |
download | camera-3a8027229c119e14d574db3501726daafad38188.tar.gz camera-3a8027229c119e14d574db3501726daafad38188.tar.bz2 camera-3a8027229c119e14d574db3501726daafad38188.zip |
Add new internal APIs for extra preview
[Version] 0.4.55
[Issue Type] New feature
Change-Id: I2c48a36eb958642b99bcb7ec18ce900399868c76
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
-rw-r--r-- | include/camera_internal.h | 46 | ||||
-rw-r--r-- | packaging/capi-media-camera.spec | 2 | ||||
-rw-r--r-- | src/camera.c | 19 | ||||
-rw-r--r-- | src/camera_internal.c | 60 | ||||
-rw-r--r-- | test/camera_test.c | 170 |
5 files changed, 238 insertions, 59 deletions
diff --git a/include/camera_internal.h b/include/camera_internal.h index 46a1aae..7f37ecf 100644 --- a/include/camera_internal.h +++ b/include/camera_internal.h @@ -82,6 +82,7 @@ typedef struct _camera_stream_data_s { void *internal_buffer; /**< Internal buffer pointer */ int stride[BUFFER_MAX_PLANE_NUM]; /**< Stride of each plane */ int elevation[BUFFER_MAX_PLANE_NUM]; /**< Elevation of each plane */ + int extra_stream_id; /**< ID of extra preview stream */ } camera_stream_data_s; @@ -117,6 +118,20 @@ typedef void (*camera_device_list_changed_cb)(camera_device_list_s *list, void * /** * @internal + * @brief Called to register for notifications about delivering a copy of the new extra preview frames. + * @since_tizen 6.5 + * @param[in] frame The reference pointer to extra preview stream data + * @param[in] stream_id The id of stream + * @param[in] user_data The user data passed from the callback registration function + * @pre camera_start_preview() will invoke this callback function if you register this callback using camera_set_extra_preview_cb(). + * @see camera_start_preview() + * @see camera_set_extra_preview_cb() + * @see camera_unset_extra_preview_cb() + */ +typedef void (*camera_extra_preview_cb)(camera_preview_data_s *frame, int stream_id, void *user_data); + +/** + * @internal * @brief Start the evas rendering. * @since_tizen 3.0 * @param[in] camera The handle to the camera @@ -332,6 +347,37 @@ int camera_attr_get_flash_brightness(camera_h camera, int *level); int camera_attr_get_flash_brightness_range(camera_h camera, int *min, int *max); /** + * @internal + * @brief Registers a callback function to be called for extra preview frames. + * @since_tizen 6.5 + * @param[in] camera The handle to the camera + * @param[in] callback The callback function to be registered + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, otherwise a negative error value + * @retval #CAMERA_ERROR_NONE Successful + * @retval #CAMERA_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #CAMERA_ERROR_SERVICE_DISCONNECTED The socket to multimedia server is disconnected + * @pre The camera state must be set to #CAMERA_STATE_CREATED or #CAMERA_STATE_PREVIEW. + * @see camera_start_preview() + * @see camera_unset_extra_preview_cb() + * @see camera_extra_preview_cb() + */ +int camera_set_extra_preview_cb(camera_h camera, camera_extra_preview_cb callback, void *user_data); + +/** + * @internal + * @brief Unregisters the callback function. + * @since_tizen 6.5 + * @param[in] camera The handle to the camera + * @return @c 0 on success, otherwise a negative error value + * @retval #CAMERA_ERROR_NONE Successful + * @retval #CAMERA_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #CAMERA_ERROR_SERVICE_DISCONNECTED The socket to multimedia server is disconnected + * @see camera_set_extra_preview_cb() + */ +int camera_unset_extra_preview_cb(camera_h camera); + +/** * @} */ #ifdef __cplusplus diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec index 873a88c..9261581 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.54 +Version: 0.4.55 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/camera.c b/src/camera.c index f318ef3..258101e 100644 --- a/src/camera.c +++ b/src/camera.c @@ -317,13 +317,26 @@ static void __camera_event_handler_preview(camera_cb_info_s *cb_info, char *recv } /* preview callback */ - if (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW]) { + if (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW] || + cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW]) { camera_create_preview_frame(stream, num_buffer_fd, buffer_bo_handle, &data_bo_handle, &frame); - ((camera_preview_cb)cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW])(&frame, - cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_PREVIEW]); + if (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW] && + stream->extra_stream_id < 0) { + ((camera_preview_cb)cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW])(&frame, + cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_PREVIEW]); + } + + if (cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW] && + stream->extra_stream_id >= 0) { + ((camera_extra_preview_cb)cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW])(&frame, + stream->extra_stream_id, cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW]); + } } + if (stream->extra_stream_id >= 0) + goto _PREVIEW_CB_HANDLER_DONE; + /* make media packet with below cases. * 1. media_packet_preview_cb is set * 2. EVAS display rendering diff --git a/src/camera_internal.c b/src/camera_internal.c index 234e6a9..ab2b4f1 100644 --- a/src/camera_internal.c +++ b/src/camera_internal.c @@ -433,4 +433,64 @@ int camera_attr_get_flash_brightness_range(camera_h camera, int *min, int *max) return ret; } + + +int camera_set_extra_preview_cb(camera_h camera, camera_extra_preview_cb callback, void *user_data) +{ + int ret = CAMERA_ERROR_NONE; + camera_cli_s *pc = (camera_cli_s *)camera; + muse_camera_api_e api = MUSE_CAMERA_API_SET_EXTRA_PREVIEW_CB; + + if (!pc || !pc->cb_info || !callback) { + CAM_LOG_ERROR("NULL pointer %p %p", pc, callback); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + CAM_LOG_INFO("Enter"); + + _camera_msg_send(api, NULL, pc->cb_info, &ret, CAMERA_CB_TIMEOUT); + + if (ret == CAMERA_ERROR_NONE) { + g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW]); + + pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW] = callback; + pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW] = user_data; + + g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW]); + } + + CAM_LOG_INFO("ret : 0x%x", ret); + + return ret; +} + + +int camera_unset_extra_preview_cb(camera_h camera) +{ + int ret = CAMERA_ERROR_NONE; + camera_cli_s *pc = (camera_cli_s *)camera; + muse_camera_api_e api = MUSE_CAMERA_API_UNSET_EXTRA_PREVIEW_CB; + + if (!pc || !pc->cb_info) { + CAM_LOG_ERROR("NULL handle"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + CAM_LOG_INFO("Enter"); + + _camera_msg_send(api, NULL, pc->cb_info, &ret, CAMERA_CB_TIMEOUT); + + if (ret == CAMERA_ERROR_NONE) { + g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW]); + + pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW] = NULL; + pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW] = NULL; + + g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_CAMERA_EVENT_TYPE_EXTRA_PREVIEW]); + } + + CAM_LOG_INFO("ret : 0x%x", ret); + + return ret; +} //LCOV_EXCL_STOP diff --git a/test/camera_test.c b/test/camera_test.c index fb08d50..4cd0b99 100644 --- a/test/camera_test.c +++ b/test/camera_test.c @@ -67,8 +67,9 @@ 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 int g_camera_mp_preview_cb_file_write; +static int g_camera_preview_cb_dump; +static int g_camera_extra_preview_cb_dump; +static int g_camera_mp_preview_cb_dump; static struct timeval previous_time; static struct timeval current_time; @@ -96,6 +97,7 @@ static media_bridge_h bridge; -----------------------------------------------------------------------*/ #define DEFAULT_FILE_PATH "/home/owner/media" #define PREVIEW_CB_DUMP_FILE_NAME "preview.data" +#define EXTRA_PREVIEW_CB_DUMP_FILE_NAME "extra_preview.data" #define MP_PREVIEW_CB_DUMP_FILE_NAME "mp_preview.data" #define MAX_FILE_NAME_LENGTH 256 #define MAX_FILE_PATH_LENGTH (MAX_FILE_NAME_LENGTH - 20) @@ -499,41 +501,21 @@ static void _camera_interrupt_started_cb(camera_policy_e policy, camera_state_e return; } -void _camera_preview_cb(camera_preview_data_s *frame, void *user_data) +static void _dump_preview_data(camera_preview_data_s *frame, const char *file_name) { - char preview_dump[MAX_FILE_NAME_LENGTH] = {'\0',}; + char dump_path[MAX_FILE_NAME_LENGTH] = {'\0',}; FILE *fp = NULL; if (!frame) { - g_print("\n[PREVIEW_CB] NULL frame!\n"); + g_print("\n[DUMP_PREVIEW_DATA] NULL frame\n"); return; } - g_print("[PREVIEW_CB] preview callback - format[%d] res[%dx%d] num plane[%d] ", - frame->format, frame->width, frame->height, frame->num_of_planes); + snprintf(dump_path, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, file_name); - if (frame->num_of_planes == 1) { - g_print("size YUV[%d]\n", - frame->data.single_plane.size); - } else if (frame->num_of_planes == 2) { - g_print("size Y[%d] UV[%d]\n", - frame->data.double_plane.y_size, - frame->data.double_plane.uv_size); - } else if (frame->num_of_planes == 3) { - g_print("size Y[%d] U[%d] V[%d]\n", - frame->data.triple_plane.y_size, - frame->data.triple_plane.u_size, - frame->data.triple_plane.v_size); - } - - if (!g_camera_preview_cb_file_write) - return; - - snprintf(preview_dump, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, PREVIEW_CB_DUMP_FILE_NAME); - - fp = fopen(preview_dump, "a"); + fp = fopen(dump_path, "a"); if (fp == NULL) { - g_print("\n[PREVIEW_CB] file[%s] open failed\n", preview_dump); + g_print("\n[DUMP_PREVIEW_DATA] file[%s] open failed\n", dump_path); return; } @@ -563,11 +545,66 @@ void _camera_preview_cb(camera_preview_data_s *frame, void *user_data) } } - g_print("[PREVIEW_CB] file[%s] write done\n", preview_dump); + g_print("[DUMP_PREVIEW_DATA] file[%s] write done\n", dump_path); fclose(fp); } +static void _camera_print_preview_info(camera_preview_data_s *frame) +{ + if (!frame) { + g_print("\n[PREVIEW_CB] NULL frame!\n"); + return; + } + + g_print("format[%d] res[%dx%d] num plane[%d] ", + frame->format, frame->width, frame->height, frame->num_of_planes); + + if (frame->num_of_planes == 1) { + g_print("size [%d]\n", + frame->data.single_plane.size); + } else if (frame->num_of_planes == 2) { + g_print("size Y[%d] UV[%d]\n", + frame->data.double_plane.y_size, + frame->data.double_plane.uv_size); + } else if (frame->num_of_planes == 3) { + g_print("size Y[%d] U[%d] V[%d]\n", + frame->data.triple_plane.y_size, + frame->data.triple_plane.u_size, + frame->data.triple_plane.v_size); + } +} + +static void _camera_preview_cb(camera_preview_data_s *frame, void *user_data) +{ + if (!frame) { + g_print("\n[PREVIEW_CB] NULL frame!\n"); + return; + } + + g_print("[PREVIEW_CB] preview callback - "); + + _camera_print_preview_info(frame); + + if (g_camera_preview_cb_dump) + _dump_preview_data(frame, PREVIEW_CB_DUMP_FILE_NAME); +} + +static void _camera_extra_preview_cb(camera_preview_data_s *frame, int stream_id, void *user_data) +{ + if (!frame) { + g_print("\n[PREVIEW_CB] NULL frame!\n"); + return; + } + + g_print("[EXTRA_PREVIEW_CB][stream_id:%d] preview callback - ", stream_id); + + _camera_print_preview_info(frame); + + if (g_camera_extra_preview_cb_dump) + _dump_preview_data(frame, EXTRA_PREVIEW_CB_DUMP_FILE_NAME); +} + static void _camera_media_packet_preview_cb(media_packet_h pkt, void *user_data) { @@ -575,7 +612,7 @@ static void _camera_media_packet_preview_cb(media_packet_h pkt, void *user_data) int width = 0; int height = 0; unsigned int i = 0; - char mp_preview_dump[MAX_FILE_NAME_LENGTH] = {'\0',}; + char mp_dump_path[MAX_FILE_NAME_LENGTH] = {'\0',}; FILE *fp = NULL; media_format_h fmt = NULL; media_format_mimetype_e type = MEDIA_FORMAT_I420; @@ -616,12 +653,11 @@ static void _camera_media_packet_preview_cb(media_packet_h pkt, void *user_data) g_print(" tbm surface [%dx%d], total size[%u]\n", s_info.width, s_info.height, s_info.size); - if (g_camera_mp_preview_cb_file_write) { - snprintf(mp_preview_dump, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, MP_PREVIEW_CB_DUMP_FILE_NAME); - - fp = fopen(mp_preview_dump, "a"); + if (g_camera_mp_preview_cb_dump) { + snprintf(mp_dump_path, MAX_FILE_NAME_LENGTH, "%s/%s", DEFAULT_FILE_PATH, MP_PREVIEW_CB_DUMP_FILE_NAME); + fp = fopen(mp_dump_path, "a"); if (fp == NULL) { - g_print("\n[MP_PREVIEW_CB] file[%s] open failed ====\n", mp_preview_dump); + g_print("\n[MP_PREVIEW_CB] file[%s] open failed ====\n", mp_dump_path); goto _MEDIA_PACKET_PREVIEW_CB_OUT; } } @@ -834,10 +870,9 @@ static void print_menu() g_print("\t '2' Multishot test\n"); g_print("\t '3' Setting\n"); g_print("\t '4' Change device (CAMERA0 <-> CAMERA1)\n"); - g_print("\t '5' Set preview callback\n"); - g_print("\t '6' Unset preview callback\n"); - g_print("\t '7' Set media packet preview callback\n"); - g_print("\t '8' Unset media packet preview callback\n"); + g_print("\t '5' Set/Unset preview callback\n"); + g_print("\t '6' Set/Unset extra preview callback\n"); + g_print("\t '7' Set/Unset media packet preview callback\n"); g_print("\t 'b' back\n"); g_print("\t=======================================\n"); break; @@ -927,6 +962,7 @@ static void main_menu(gchar buf) int err = 0; int interval = 0; int count = 0; + int set_cb = 0; switch (buf) { case '1': /* Capture */ @@ -975,22 +1011,49 @@ 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); + g_print("* Preview Callback\n"); + g_print("\tUnset[0] / Set[Others] :"); + err = scanf("%d", &set_cb); flush_stdin(); - camera_set_preview_cb(hcamcorder->camera, _camera_preview_cb, hcamcorder->camera); + if (set_cb) { + g_print("\n\tDump preview data to file - NO[0], YES[Others] : "); + err = scanf("%d", &g_camera_preview_cb_dump); + flush_stdin(); + err = camera_set_preview_cb(hcamcorder->camera, _camera_preview_cb, hcamcorder->camera); + } else { + err = camera_unset_preview_cb(hcamcorder->camera); + } + g_print("\tresult[0x%x]\n\n", err); break; case '6': - camera_unset_preview_cb(hcamcorder->camera); + g_print("* Extra Preview Callback\n"); + g_print("\tUnset[0] / Set[Others] :"); + err = scanf("%d", &set_cb); + flush_stdin(); + if (set_cb) { + g_print("\n\tDump extra preview data to file - NO[0], YES[Others] : "); + err = scanf("%d", &g_camera_extra_preview_cb_dump); + flush_stdin(); + err = camera_set_extra_preview_cb(hcamcorder->camera, _camera_extra_preview_cb, hcamcorder->camera); + } else { + err = camera_unset_extra_preview_cb(hcamcorder->camera); + } + g_print("\tresult[0x%x]\n\n", err); break; case '7': - g_print("\n\tWrite preview data to file(0:NO, Others:YES) : "); - err = scanf("%d", &g_camera_mp_preview_cb_file_write); + g_print("* Media Packet Preview Callback\n"); + g_print("\tUnset[0] / Set[Others] :"); + err = scanf("%d", &set_cb); flush_stdin(); - camera_set_media_packet_preview_cb(hcamcorder->camera, _camera_media_packet_preview_cb, hcamcorder->camera); - break; - case '8': - camera_unset_media_packet_preview_cb(hcamcorder->camera); + if (set_cb) { + g_print("\n\tDump media packet preview data to file - NO[0], YES[Others] : "); + err = scanf("%d", &g_camera_mp_preview_cb_dump); + flush_stdin(); + err = camera_set_media_packet_preview_cb(hcamcorder->camera, _camera_media_packet_preview_cb, hcamcorder->camera); + } else { + err = camera_unset_media_packet_preview_cb(hcamcorder->camera); + } + g_print("\tresult[0x%x]\n\n", err); break; case 'b': /* back */ __release_media_bridge(); @@ -1473,10 +1536,10 @@ static void setting_menu(gchar buf) break; case 'm': /* media bridge */ g_print("* Media Bridge !\n"); - g_print("\tSet[1] or Unset[Others] :"); + g_print("\tUnset[0] / Set[Others] :"); err = scanf("%d", &set_bridge); flush_stdin(); - if (set_bridge == 1) { + if (set_bridge) { __release_media_bridge(); err = media_bridge_create(&bridge); @@ -1484,10 +1547,7 @@ static void setting_menu(gchar buf) } else { __release_media_bridge(); } - if (err != 0) - g_print("Failed to set/unset[%d] media bridge[%x]\n", set_bridge, err); - else - g_print("Succeed to set/unset[%d] media bridge\n", set_bridge); + g_print("\tresult[0x%x]\n\n", err); break; case 'b': /* back */ hcamcorder->menu_state = MENU_STATE_MAIN; |