summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongmo Yang <jm80.yang@samsung.com>2021-04-19 17:16:44 +0900
committerJeongmo Yang <jm80.yang@samsung.com>2021-04-28 18:30:44 +0900
commit3a8027229c119e14d574db3501726daafad38188 (patch)
tree342f094cfdd953c626b766feb134e607cf102c4d
parentf502f9116ff94bb06750ee247164300f4baa2242 (diff)
downloadcamera-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.h46
-rw-r--r--packaging/capi-media-camera.spec2
-rw-r--r--src/camera.c19
-rw-r--r--src/camera_internal.c60
-rw-r--r--test/camera_test.c170
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;