From 4dab1570de00a1acd1405f88598a048040f157f0 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Wed, 16 Jun 2021 21:54:28 +0900 Subject: [PATCH] Add new internal APIs for extra preview stream format [Version] 0.4.58 [Issue Type] New feature Change-Id: I9c5297d86aa230500ab8a445e09f88c821a3bfa2 Signed-off-by: Jeongmo Yang --- include/camera_internal.h | 47 +++++++++++++++++++++++ include/camera_private.h | 3 ++ packaging/capi-media-camera.spec | 2 +- src/camera.c | 56 +++++++++++++++++---------- src/camera_internal.c | 82 ++++++++++++++++++++++++++++++++++++++++ test/camera_test.c | 32 +++++++++++++++- 6 files changed, 200 insertions(+), 22 deletions(-) diff --git a/include/camera_internal.h b/include/camera_internal.h index 27e2b37..ef092a1 100644 --- a/include/camera_internal.h +++ b/include/camera_internal.h @@ -97,6 +97,7 @@ typedef struct _camera_device_s { camera_device_e index; char name[DEVICE_NAME_MAX_LENGTH]; char id[DEVICE_ID_MAX_LENGTH]; + int extra_stream_num; } camera_device_s; typedef struct _camera_device_list_s { @@ -379,6 +380,52 @@ int camera_unset_extra_preview_cb(camera_h camera); /** * @internal + * @brief Sets the extra preview stream format. + * @since_tizen 6.5 + * @param[in] camera The handle to the camera + * @param[in] stream_id The id of extra preview stream + * @param[in] pixel_format The pixel format of extra preview stream + * @param[in] width The width of extra preview stream + * @param[in] height The height of extra preview stream + * @param[in] fps The fps of extra preview stream + * @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_INVALID_STATE Invalid state + * @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_set_extra_preview_cb() + * @see camera_unset_extra_preview_cb() + * @see camera_get_extra_preview_stream_format() + */ +int camera_set_extra_preview_stream_format(camera_h camera, int stream_id, camera_pixel_format_e pixel_format, int width, int height, int fps); + +/** + * @internal + * @brief Gets the extra preview stream format. + * @since_tizen 6.5 + * @param[in] camera The handle to the camera + * @param[in] stream_id The id of extra preview stream + * @param[out] pixel_format The pixel format of extra preview stream + * @param[out] width The width of extra preview stream + * @param[out] height The height of extra preview stream + * @param[out] fps The fps of extra preview stream + * @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_INVALID_STATE Invalid state + * @retval #CAMERA_ERROR_SERVICE_DISCONNECTED The socket to multimedia server is disconnected + * @pre The camera state must be set to #CAMERA_STATE_PREVIEW. + * @see camera_start_preview() + * @see camera_set_extra_preview_cb() + * @see camera_unset_extra_preview_cb() + * @see camera_set_extra_preview_stream_format() + */ +int camera_get_extra_preview_stream_format(camera_h camera, int stream_id, camera_pixel_format_e *pixel_format, int *width, int *height, int *fps); + +/** + * @internal * @brief Sets the manual focus level. * @since_tizen 6.5 * @remarks The auto focusing will be stopped when camera_attr_set_focus_level() is called. diff --git a/include/camera_private.h b/include/camera_private.h index 00ec3e9..2e90bd0 100644 --- a/include/camera_private.h +++ b/include/camera_private.h @@ -170,6 +170,7 @@ typedef struct _camera_cb_info_s { gchar get_string[MUSE_CAMERA_GET_STRING_NUM][MUSE_CAMERA_MSG_MAX_LENGTH]; gdouble get_geotag[3]; gint get_display_roi_area[4]; + gint get_extra_preview_stream_format[4]; /* media bridge */ media_bridge_h bridge; @@ -249,6 +250,8 @@ void _camera_msg_send_param1(int api, camera_cb_info_s *cb_info, void _camera_msg_send_param2_int(int api, camera_cb_info_s *cb_info, int *ret, camera_msg_param *param0, camera_msg_param *param1, int timeout); void _camera_msg_return_buffer(int ret_fd, camera_cb_info_s *cb_info); +int _camera_client_wait_for_cb_return(muse_camera_api_e api, camera_cb_info_s *cb_info, int time_out); +void _camera_update_api_waiting(camera_cb_info_s *cb_info, int api, int value); int _camera_get_log_level(void); typedef bool (*camera_supported_cb_param1)(int param, void *user_data); diff --git a/packaging/capi-media-camera.spec b/packaging/capi-media-camera.spec index 75186ae..7119cf6 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.57 +Version: 0.4.58 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/camera.c b/src/camera.c index 258101e..bf560b0 100644 --- a/src/camera.c +++ b/src/camera.c @@ -172,7 +172,7 @@ static void __camera_release_preview_buffer(camera_h camera) } -static void __camera_update_api_waiting(camera_cb_info_s *cb_info, int api, int value) +void _camera_update_api_waiting(camera_cb_info_s *cb_info, int api, int value) { if (!cb_info || api < 0 || api >= MUSE_CAMERA_API_MAX) { @@ -645,7 +645,8 @@ static void __camera_release_imported_bo(tbm_bo *bo) *bo = NULL; } -static int __camera_client_wait_for_cb_return(muse_camera_api_e api, camera_cb_info_s *cb_info, int time_out) + +int _camera_client_wait_for_cb_return(muse_camera_api_e api, camera_cb_info_s *cb_info, int time_out) { int ret = CAMERA_ERROR_NONE; gint64 end_time; @@ -716,7 +717,7 @@ void _camera_msg_send(int api, int *fds, camera_cb_info_s *cb_info, CAM_LOG_DEBUG("send msg[%s]", msg); if (cb_info->is_server_connected) { - __camera_update_api_waiting(cb_info, api, 1); + _camera_update_api_waiting(cb_info, api, 1); g_mutex_lock(&cb_info->fd_lock); send_ret = muse_core_msg_send_fd(cb_info->fd, fds, msg); @@ -729,10 +730,10 @@ void _camera_msg_send(int api, int *fds, camera_cb_info_s *cb_info, *ret = CAMERA_ERROR_INVALID_OPERATION; } else { if (ret) - *ret = __camera_client_wait_for_cb_return(api, cb_info, timeout); + *ret = _camera_client_wait_for_cb_return(api, cb_info, timeout); } - __camera_update_api_waiting(cb_info, api, -1); + _camera_update_api_waiting(cb_info, api, -1); muse_core_msg_free(msg); } @@ -792,7 +793,7 @@ void _camera_msg_send_param1(int api, camera_cb_info_s *cb_info, CAM_LOG_DEBUG("send msg[%s]", msg); if (cb_info->is_server_connected) { - __camera_update_api_waiting(cb_info, api, 1); + _camera_update_api_waiting(cb_info, api, 1); g_mutex_lock(&cb_info->fd_lock); send_ret = muse_core_msg_send(cb_info->fd, msg); @@ -806,10 +807,10 @@ void _camera_msg_send_param1(int api, camera_cb_info_s *cb_info, *ret = CAMERA_ERROR_INVALID_OPERATION; } else { if (ret) - *ret = __camera_client_wait_for_cb_return(api, cb_info, timeout); + *ret = _camera_client_wait_for_cb_return(api, cb_info, timeout); } - __camera_update_api_waiting(cb_info, api, -1); + _camera_update_api_waiting(cb_info, api, -1); muse_core_msg_free(msg); } @@ -847,7 +848,7 @@ void _camera_msg_send_param2_int(int api, camera_cb_info_s *cb_info, CAM_LOG_DEBUG("send msg[%s]", msg); if (cb_info->is_server_connected) { - __camera_update_api_waiting(cb_info, api, 1); + _camera_update_api_waiting(cb_info, api, 1); g_mutex_lock(&cb_info->fd_lock); send_ret = muse_core_msg_send(cb_info->fd, msg); @@ -859,10 +860,10 @@ void _camera_msg_send_param2_int(int api, camera_cb_info_s *cb_info, func_ret = CAMERA_ERROR_INVALID_OPERATION; } else { - func_ret = __camera_client_wait_for_cb_return(api, cb_info, timeout); + func_ret = _camera_client_wait_for_cb_return(api, cb_info, timeout); } - __camera_update_api_waiting(cb_info, api, -1); + _camera_update_api_waiting(cb_info, api, -1); muse_core_msg_free(msg); @@ -1879,7 +1880,8 @@ static void __camera_process_msg(camera_cb_info_s *cb_info, char *msg, int *tfd) muse_core_msg_deserialize("get_value1", msg, NULL, NULL, MUSE_TYPE_INT, &cb_info->get_int_pair[get_index][1]); break; case MUSE_CAMERA_GET_TYPE_ARRAY: - if (api == MUSE_CAMERA_API_GET_DISPLAY_ROI_AREA) { + switch (api) { + case MUSE_CAMERA_API_GET_DISPLAY_ROI_AREA: muse_core_msg_deserialize("get_value", msg, NULL, NULL, MUSE_TYPE_ARRAY, cb_info->get_display_roi_area); CAM_LOG_INFO("get display roi %d,%d,%dx%d", @@ -1887,11 +1889,25 @@ static void __camera_process_msg(camera_cb_info_s *cb_info, char *msg, int *tfd) cb_info->get_display_roi_area[1], cb_info->get_display_roi_area[2], cb_info->get_display_roi_area[3]); - } else { + break; + case MUSE_CAMERA_API_ATTR_GET_GEOTAG: muse_core_msg_deserialize("get_value", msg, NULL, NULL, MUSE_TYPE_ARRAY, cb_info->get_geotag); CAM_LOG_INFO("get geotag %lf, %lf, %lf", cb_info->get_geotag[0], cb_info->get_geotag[1], cb_info->get_geotag[2]); + break; + case MUSE_CAMERA_API_GET_EXTRA_PREVIEW_STREAM_FORMAT: + muse_core_msg_deserialize("get_value", + msg, NULL, NULL, MUSE_TYPE_ARRAY, cb_info->get_extra_preview_stream_format); + CAM_LOG_INFO("get extra preview stream format %d,%dx%d,%d", + cb_info->get_extra_preview_stream_format[0], + cb_info->get_extra_preview_stream_format[1], + cb_info->get_extra_preview_stream_format[2], + cb_info->get_extra_preview_stream_format[3]); + break; + default: + CAM_LOG_WARNING("unknown api[%d]", api); + break; } break; case MUSE_CAMERA_GET_TYPE_STRING: @@ -2439,7 +2455,7 @@ int _camera_create_private(camera_device_e device, bool is_network, camera_h *ca CAM_LOG_INFO("cb info : %d", pc->cb_info->fd); - ret = __camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT); + ret = _camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT); pc->cb_info->api_waiting[MUSE_CAMERA_API_CREATE] = 0; @@ -4907,7 +4923,7 @@ int camera_attr_set_geotag(camera_h camera, double latitude, double longitude, d } if (pc->cb_info->is_server_connected) { - __camera_update_api_waiting(pc->cb_info, api, 1); + _camera_update_api_waiting(pc->cb_info, api, 1); g_mutex_lock(&pc->cb_info->fd_lock); send_ret = muse_core_msg_send(pc->cb_info->fd, msg); @@ -4918,10 +4934,10 @@ int camera_attr_set_geotag(camera_h camera, double latitude, double longitude, d CAM_LOG_ERROR("message send failed"); ret = CAMERA_ERROR_INVALID_OPERATION; } else { - ret = __camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT); + ret = _camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT); } - __camera_update_api_waiting(pc->cb_info, api, -1); + _camera_update_api_waiting(pc->cb_info, api, -1); muse_core_msg_free(msg); @@ -6545,7 +6561,7 @@ int camera_attr_set_display_roi_area(camera_h camera, int x, int y, int width, i } if (pc->cb_info->is_server_connected) { - __camera_update_api_waiting(pc->cb_info, api, 1); + _camera_update_api_waiting(pc->cb_info, api, 1); g_mutex_lock(&pc->cb_info->fd_lock); send_ret = muse_core_msg_send(pc->cb_info->fd, msg); @@ -6556,10 +6572,10 @@ int camera_attr_set_display_roi_area(camera_h camera, int x, int y, int width, i CAM_LOG_ERROR("message send failed"); ret = CAMERA_ERROR_INVALID_OPERATION; } else { - ret = __camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT); + ret = _camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT); } - __camera_update_api_waiting(pc->cb_info, api, -1); + _camera_update_api_waiting(pc->cb_info, api, -1); muse_core_msg_free(msg); diff --git a/src/camera_internal.c b/src/camera_internal.c index 1d91e36..2e6f19e 100644 --- a/src/camera_internal.c +++ b/src/camera_internal.c @@ -567,4 +567,86 @@ int camera_unset_extra_preview_cb(camera_h camera) return ret; } + + +int camera_set_extra_preview_stream_format(camera_h camera, int stream_id, camera_pixel_format_e pixel_format, int width, int height, int fps) +{ + int ret = CAMERA_ERROR_NONE; + int send_ret = 0; + int stream_format[4] = {pixel_format, width, height, fps}; + char *msg = NULL; + camera_cli_s *pc = (camera_cli_s *)camera; + muse_camera_api_e api = MUSE_CAMERA_API_SET_EXTRA_PREVIEW_STREAM_FORMAT; + + if (!pc || !pc->cb_info) { + CAM_LOG_ERROR("NULL handle"); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + CAM_LOG_INFO("Enter - stream_id[%d],[%d,%dx%d,%d]", + stream_id, pixel_format, width, height, fps); + + msg = muse_core_msg_new(api, + MUSE_TYPE_INT, "stream_id", stream_id, + MUSE_TYPE_ARRAY, "stream_format", 4, stream_format, + NULL); + if (!msg) { + CAM_LOG_ERROR("msg creation failed: api %d", api); + return CAMERA_ERROR_OUT_OF_MEMORY; + } + + if (pc->cb_info->is_server_connected) { + _camera_update_api_waiting(pc->cb_info, api, 1); + + g_mutex_lock(&pc->cb_info->fd_lock); + send_ret = muse_core_msg_send(pc->cb_info->fd, msg); + g_mutex_unlock(&pc->cb_info->fd_lock); + } + + if (send_ret < 0) { + CAM_LOG_ERROR("message send failed"); + ret = CAMERA_ERROR_INVALID_OPERATION; + } else { + ret = _camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT); + } + + _camera_update_api_waiting(pc->cb_info, api, -1); + + muse_core_msg_free(msg); + + CAM_LOG_INFO("ret : 0x%x", ret); + + return ret; +} + + +int camera_get_extra_preview_stream_format(camera_h camera, int stream_id, camera_pixel_format_e *pixel_format, int *width, int *height, int *fps) +{ + int ret = CAMERA_ERROR_NONE; + camera_cli_s *pc = (camera_cli_s *)camera; + camera_msg_param param; + muse_camera_api_e api = MUSE_CAMERA_API_GET_EXTRA_PREVIEW_STREAM_FORMAT; + + if (!pc || !pc->cb_info || !pixel_format || !width || !height || !fps) { + CAM_LOG_ERROR("NULL pointer %p %p %p %p %p", pc, pixel_format, width, height, fps); + return CAMERA_ERROR_INVALID_PARAMETER; + } + + CAM_LOG_INFO("Enter - stream_id[%d]", stream_id); + + CAMERA_MSG_PARAM_SET(param, INT, stream_id); + + _camera_msg_send_param1(api, pc->cb_info, &ret, ¶m, CAMERA_CB_TIMEOUT); + + if (ret == CAMERA_ERROR_NONE) { + *pixel_format = (camera_pixel_format_e)pc->cb_info->get_extra_preview_stream_format[0]; + *width = pc->cb_info->get_extra_preview_stream_format[1]; + *height = pc->cb_info->get_extra_preview_stream_format[2]; + *fps = pc->cb_info->get_extra_preview_stream_format[3]; + } + + 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 3d061da..3b134a6 100644 --- a/test/camera_test.c +++ b/test/camera_test.c @@ -932,6 +932,7 @@ static void print_menu() g_print("\t 'p' Picture format \n"); g_print("\t 'E' EXIF orientation \n"); g_print("\t 'F' Get facing direction of camera module\n"); + g_print("\t 's' Extra preview stream format\n"); g_print("\t >>>>>>>>>>>>>>>>>>>> [Display/Filter]\n"); g_print("\t 'v' Visible \n"); g_print("\t 'o' Output mode \n"); @@ -1099,6 +1100,9 @@ static void setting_menu(gchar buf) int height = 0; int result = 0; int set_bridge = 0; + int stream_id; + int pixel_format; + int fps; switch (buf) { /* Camera setting */ @@ -1310,7 +1314,7 @@ static void setting_menu(gchar buf) else camera_attr_set_tag_orientation(hcamcorder->camera, idx); break; - case 'F': /* Getting > Get Facing direction */ + case 'F': /* Setting > Get Facing direction */ g_print("* Get facing direction of camera module\n"); err = camera_get_facing_direction(hcamcorder->camera, (camera_facing_direction_e *)&idx); if (CAMERA_ERROR_NONE == err) @@ -1318,6 +1322,32 @@ static void setting_menu(gchar buf) else g_print("* Error : %d\n", err); break; + case 's': /* Setting > Set extra preview stream format */ + g_print("* Set extra preview stream format\n"); + + g_print("\tstream_id,pixel format[NV12:0,H264:15,VP8:18],width,height,fps : "); + err = scanf("%d,%d,%d,%d,%d", &stream_id, &pixel_format, &width, &height, &fps); + flush_stdin(); + + err = camera_set_extra_preview_stream_format(hcamcorder->camera, + stream_id, pixel_format, width, height, fps); + if (err != CAMERA_ERROR_NONE) { + g_print("* Set Error : 0x%x\n", err); + break; + } + + pixel_format = width = height = fps = -1; + + err = camera_get_extra_preview_stream_format(hcamcorder->camera, + stream_id, &pixel_format, &width, &height, &fps); + if (err != CAMERA_ERROR_NONE) { + g_print("* Get Error : 0x%x\n", err); + break; + } + + g_print("\tGet stream_id[%d],pixel format[%d],res[%dx%d],fps[%d]\n", + stream_id, pixel_format, width, height, fps); + break; /* Display / Filter setting */ case 'v': /* Display visible */ g_print("* Display visible setting !\n"); -- 2.7.4