Add new internal APIs for extra preview stream format 24/259924/6
authorJeongmo Yang <jm80.yang@samsung.com>
Wed, 16 Jun 2021 12:54:28 +0000 (21:54 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 17 Jun 2021 05:35:41 +0000 (14:35 +0900)
[Version] 0.4.58
[Issue Type] New feature

Change-Id: I9c5297d86aa230500ab8a445e09f88c821a3bfa2
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
include/camera_internal.h
include/camera_private.h
packaging/capi-media-camera.spec
src/camera.c
src/camera_internal.c
test/camera_test.c

index 27e2b37..ef092a1 100644 (file)
@@ -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.
index 00ec3e9..2e90bd0 100644 (file)
@@ -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);
index 75186ae..7119cf6 100644 (file)
@@ -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
index 258101e..bf560b0 100644 (file)
@@ -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);
 
index 1d91e36..2e6f19e 100644 (file)
@@ -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, &param, 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
index 3d061da..3b134a6 100644 (file)
@@ -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");