Support new APIs for media bridge 86/256086/6 accepted/tizen/unified/20210412.012057 submit/tizen/20210408.091908
authorJeongmo Yang <jm80.yang@samsung.com>
Mon, 29 Mar 2021 07:31:10 +0000 (16:31 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Wed, 7 Apr 2021 06:54:12 +0000 (15:54 +0900)
- MUSE_CAMERA_API_SET_MEDIA_BRIDGE, MUSE_CAMERA_API_UNSET_MEDIA_BRIDGE
- Minor change
 : Correct the condition to wait for preview callback return signal.
 : Revise preview callback related code.

[Version] 0.3.41
[Issue Type] New feature

Change-Id: Iefcd19f04fed02271f00d0c9653615f9d881295d
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
legacy/include/legacy_camera.h
legacy/src/legacy_camera.c
muse/include/muse_camera.h
muse/include/muse_camera_internal.h
muse/src/muse_camera_dispatcher.c
packaging/mmsvc-camera.spec

index 213e725..0111f64 100644 (file)
@@ -776,7 +776,6 @@ int legacy_camera_create(camera_device_e device, camera_h *camera);
  *          display handle will be reused and last frame on display can be kept even though camera device is changed.
  * @param[in] camera The handle to the camera
  * @param[in] device The hardware camera to access
- * @param[in] is_evas The current display type
  * @return @c 0 on success, otherwise a negative error value
  * @retval #CAMERA_ERROR_NONE Successful
  * @retval #CAMERA_ERROR_INVALID_PARAMETER Invalid parameter
@@ -790,7 +789,7 @@ int legacy_camera_create(camera_device_e device, camera_h *camera);
  * @see legacy_camera_set_display_reuse_hint()
  * @see legacy_camera_get_display_reuse_hint()
  */
-int legacy_camera_change_device(camera_h *camera, camera_device_e device, bool is_evas);
+int legacy_camera_change_device(camera_h *camera, camera_device_e device);
 
 /**
  * @brief Destroys the camera handle and releases all its resources.
index d18a31f..2933c13 100644 (file)
@@ -666,7 +666,7 @@ int legacy_camera_create(camera_device_e device, camera_h *camera)
 }
 
 
-int legacy_camera_change_device(camera_h *camera, camera_device_e device, bool is_evas)
+int legacy_camera_change_device(camera_h *camera, camera_device_e device)
 {
        int ret = MM_ERROR_NONE;
        int pid = 0;
@@ -761,10 +761,11 @@ int legacy_camera_change_device(camera_h *camera, camera_device_e device, bool i
        new_handle->user_cb[_CAMERA_EVENT_TYPE_STATE_CHANGE] = old_handle->user_cb[_CAMERA_EVENT_TYPE_STATE_CHANGE];
        new_handle->user_data[_CAMERA_EVENT_TYPE_STATE_CHANGE] = old_handle->user_data[_CAMERA_EVENT_TYPE_STATE_CHANGE];
 
-       /* set preview callback for EVAS */
-       if (is_evas) {
+       /* set preview callback */
+       if (old_handle->user_cb[_CAMERA_EVENT_TYPE_PREVIEW]) {
                ret = legacy_camera_set_preview_cb((camera_h)new_handle,
-                       (camera_preview_cb)old_handle->user_cb[_CAMERA_EVENT_TYPE_PREVIEW], old_handle->user_data[_CAMERA_EVENT_TYPE_PREVIEW]);
+                       (camera_preview_cb)old_handle->user_cb[_CAMERA_EVENT_TYPE_PREVIEW],
+                       old_handle->user_data[_CAMERA_EVENT_TYPE_PREVIEW]);
                if (ret != CAMERA_ERROR_NONE) {
                        CAM_LOG_ERROR("legacy_camera_set_preview_cb failed[0x%x]", ret);
                        goto _CHANGE_DEVICE_FAILED;
index 18c3ff8..81e6807 100644 (file)
@@ -190,9 +190,11 @@ typedef enum {
        MUSE_CAMERA_API_ATTR_SET_HUE,
        MUSE_CAMERA_API_ATTR_GET_HUE,
        MUSE_CAMERA_API_ATTR_GET_HUE_RANGE,
-       MUSE_CAMERA_API_ATTR_SET_FLASH_BRIGHTNESS,
+       MUSE_CAMERA_API_ATTR_SET_FLASH_BRIGHTNESS, /* 155 */
        MUSE_CAMERA_API_ATTR_GET_FLASH_BRIGHTNESS,
        MUSE_CAMERA_API_ATTR_GET_FLASH_BRIGHTNESS_RANGE,
+       MUSE_CAMERA_API_SET_MEDIA_BRIDGE,
+       MUSE_CAMERA_API_UNSET_MEDIA_BRIDGE,
        MUSE_CAMERA_API_MAX
 } muse_camera_api_e;
 
index 8e9a8c0..be995b5 100644 (file)
@@ -30,9 +30,11 @@ extern "C" {
 #include <muse_camera.h>
 #include <legacy_camera_internal.h>
 
-#define PREVIEW_CB_TYPE_USER            0x0000000F
+#define PREVIEW_CB_TYPE_NONE            0x00000000
+#define PREVIEW_CB_TYPE_NORMAL          0x0000000F
 #define PREVIEW_CB_TYPE_EVAS            0x000000F0
 #define PREVIEW_CB_TYPE_MEDIA_PACKET    0x00000F00
+#define PREVIEW_CB_TYPE_MEDIA_BRIDGE    0x0000F000
 
 #define CHECK_PREVIEW_CB(muse_camera, cb_type) ((muse_camera)->preview_cb_flag & cb_type)
 #define SET_PREVIEW_CB_TYPE(muse_camera, cb_type) ((muse_camera)->preview_cb_flag |= cb_type)
@@ -69,6 +71,7 @@ typedef struct {
        GMutex preview_cb_lock;
        GCond preview_cb_cond;
        guint preview_cb_flag;
+       gboolean preview_cb_returned;
        camera_window_info_s window_info;
        GThread *task_thread;
        GMutex task_lock;
index 39cd7f3..ec6ab11 100644 (file)
                } \
        } while (0)
 
+
+static int __camera_dispatcher_set_preview_cb_flag(muse_camera_handle_s *muse_camera, guint flag);
+static int __camera_dispatcher_unset_preview_cb_flag(muse_camera_handle_s *muse_camera, guint flag);
+
+
 static muse_camera_export_data *__camera_export_data_new(void)
 {
        int i = 0;
@@ -902,6 +907,7 @@ void _camera_dispatcher_preview_cb(MMCamcorderVideoStreamDataType *stream, void
 {
        int send_ret = 0;
        char *send_message = NULL;
+       gint64 end_time = 0;
        muse_camera_handle_s *muse_camera = NULL;
        muse_camera_export_data *export_data = NULL;
        muse_module_h module = (muse_module_h)user_data;
@@ -931,6 +937,9 @@ void _camera_dispatcher_preview_cb(MMCamcorderVideoStreamDataType *stream, void
 
        g_mutex_lock(&muse_camera->preview_cb_lock);
 
+       /* reset flag */
+       muse_camera->preview_cb_returned = FALSE;
+
        /* send message */
        send_message = muse_core_msg_new(MUSE_CAMERA_CB_EVENT,
                MUSE_TYPE_INT, PARAM_EVENT, MUSE_CAMERA_EVENT_TYPE_PREVIEW,
@@ -943,12 +952,22 @@ void _camera_dispatcher_preview_cb(MMCamcorderVideoStreamDataType *stream, void
 
        muse_core_msg_free(send_message);
 
-       if (stream->bo[0] && send_ret > 0 &&
-               CHECK_PREVIEW_CB(muse_camera, PREVIEW_CB_TYPE_USER) &&
-               CHECK_PREVIEW_CB(muse_camera, PREVIEW_CB_TYPE_MEDIA_PACKET)) {
-               gint64 end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND;
-               if (!g_cond_wait_until(&muse_camera->preview_cb_cond, &muse_camera->preview_cb_lock, end_time))
-                       CAM_LOG_WARNING("preview callback return message timeout");
+       /* wait for PREVIEW_CB_RETURN signal if zero copy buffer is used(stream->bo[0] is not NULL)
+          and preview callback(normal or media packet) is set. */
+       if (send_ret > 0 && stream->bo[0] &&
+               (CHECK_PREVIEW_CB(muse_camera, PREVIEW_CB_TYPE_NORMAL) ||
+                CHECK_PREVIEW_CB(muse_camera, PREVIEW_CB_TYPE_MEDIA_PACKET))) {
+               CAM_LOG_DEBUG("wait for PREVIEW_CB_RETURN signal");
+               end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND;
+               do {
+                       if (!g_cond_wait_until(&muse_camera->preview_cb_cond, &muse_camera->preview_cb_lock, end_time)) {
+                               CAM_LOG_WARNING("PREVIEW_CB_RETURN timeout");
+                               break;
+                       } else {
+                               CAM_LOG_DEBUG("PREVIEW_CB_RETURN signal received[flag:%d]",
+                                       muse_camera->preview_cb_returned);
+                       }
+               } while (!muse_camera->preview_cb_returned);
        }
 
        g_mutex_unlock(&muse_camera->preview_cb_lock);
@@ -1166,30 +1185,22 @@ static void __camera_task_process_job(muse_camera_handle_s *muse_camera, muse_ca
                        (camera_attr_hdr_mode_e)job->value);
                break;
        case MUSE_CAMERA_API_SET_PREVIEW_CB:
-               ret = legacy_camera_set_preview_cb(muse_camera->camera_handle, \
-                       (camera_preview_cb)_camera_dispatcher_preview_cb,
-                       (void *)muse_camera->module);
-
-               if (ret == CAMERA_ERROR_NONE)
-                       SET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_USER);
+               ret = __camera_dispatcher_set_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_NORMAL);
                break;
        case MUSE_CAMERA_API_UNSET_PREVIEW_CB:
-               UNSET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_USER);
-               if (CHECK_PREVIEW_CB(muse_camera, PREVIEW_CB_TYPE_EVAS))
-                       CAM_LOG_WARNING("Preview callback for evas surface is remained.");
-               else
-                       ret = legacy_camera_unset_preview_cb(muse_camera->camera_handle);
+               ret = __camera_dispatcher_unset_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_NORMAL);
                break;
        case MUSE_CAMERA_API_SET_MEDIA_PACKET_PREVIEW_CB:
-               ret = legacy_camera_set_media_packet_preview_cb(muse_camera->camera_handle,
-                       (camera_preview_cb)_camera_dispatcher_preview_cb,
-                       (void *)muse_camera->module);
-               if (ret == CAMERA_ERROR_NONE)
-                       SET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_MEDIA_PACKET);
+               ret = __camera_dispatcher_set_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_MEDIA_PACKET);
                break;
        case MUSE_CAMERA_API_UNSET_MEDIA_PACKET_PREVIEW_CB:
-               UNSET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_MEDIA_PACKET);
-               ret = legacy_camera_unset_media_packet_preview_cb(muse_camera->camera_handle);
+               ret = __camera_dispatcher_unset_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_MEDIA_PACKET);
+               break;
+       case MUSE_CAMERA_API_SET_MEDIA_BRIDGE:
+               ret = __camera_dispatcher_set_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_MEDIA_BRIDGE);
+               break;
+       case MUSE_CAMERA_API_UNSET_MEDIA_BRIDGE:
+               ret = __camera_dispatcher_unset_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_MEDIA_BRIDGE);
                break;
        default:
                CAM_LOG_ERROR("unhandled task - api[%d]", job->api);
@@ -1208,6 +1219,72 @@ _PROCESS_DONE:
 }
 
 
+static int __camera_dispatcher_set_preview_cb_flag(muse_camera_handle_s *muse_camera, guint flag)
+{
+       int ret = CAMERA_ERROR_NONE;
+
+       camera_return_val_if_fail(muse_camera, CAMERA_ERROR_INVALID_PARAMETER);
+       camera_return_val_if_fail(flag != PREVIEW_CB_TYPE_NONE, CAMERA_ERROR_INVALID_PARAMETER);
+
+       g_mutex_lock(&muse_camera->preview_cb_lock);
+
+       CAM_LOG_INFO("current flag[0x%x] - set[0x%x]",
+               muse_camera->preview_cb_flag, flag);
+
+       if (muse_camera->preview_cb_flag == PREVIEW_CB_TYPE_NONE) {
+               ret = legacy_camera_set_preview_cb(muse_camera->camera_handle, \
+                       (camera_preview_cb)_camera_dispatcher_preview_cb,
+                       (void *)muse_camera->module);
+               if (ret != CAMERA_ERROR_NONE)
+                       CAM_LOG_ERROR("set preview cb failed[0x%x]", ret);
+       }
+
+       if (ret == CAMERA_ERROR_NONE)
+               SET_PREVIEW_CB_TYPE(muse_camera, flag);
+
+       g_mutex_unlock(&muse_camera->preview_cb_lock);
+
+       return ret;
+}
+
+
+static int __camera_dispatcher_unset_preview_cb_flag(muse_camera_handle_s *muse_camera, guint flag)
+{
+       int ret = CAMERA_ERROR_NONE;
+       guint current_flag = 0x0;
+
+       camera_return_val_if_fail(muse_camera, CAMERA_ERROR_INVALID_PARAMETER);
+
+       g_mutex_lock(&muse_camera->preview_cb_lock);
+
+       CAM_LOG_INFO("current flag[0x%x] - unset[0x%x]",
+               muse_camera->preview_cb_flag, flag);
+
+       /* backup current flag */
+       current_flag = muse_camera->preview_cb_flag;
+
+       UNSET_PREVIEW_CB_TYPE(muse_camera, flag);
+
+       if (muse_camera->preview_cb_flag == PREVIEW_CB_TYPE_NONE) {
+               g_mutex_unlock(&muse_camera->preview_cb_lock);
+
+               ret = legacy_camera_unset_preview_cb(muse_camera->camera_handle);
+
+               g_mutex_lock(&muse_camera->preview_cb_lock);
+
+               if (ret != CAMERA_ERROR_NONE) {
+                       CAM_LOG_ERROR("unset preview cb failed[0x%x]", ret);
+                       /* restore flag */
+                       muse_camera->preview_cb_flag = current_flag;
+               }
+       }
+
+       g_mutex_unlock(&muse_camera->preview_cb_lock);
+
+       return ret;
+}
+
+
 static void *_camera_dispatcher_task_func(gpointer data)
 {
        muse_camera_handle_s *muse_camera = (muse_camera_handle_s *)data;
@@ -1443,7 +1520,7 @@ int camera_dispatcher_create(muse_module_h module)
        g_cond_init(&muse_camera->camera_data.cond);
        g_mutex_init(&muse_camera->preview_cb_lock);
        g_cond_init(&muse_camera->preview_cb_cond);
-       muse_camera->preview_cb_flag = 0;
+       muse_camera->preview_cb_flag = PREVIEW_CB_TYPE_NONE;
        muse_camera->module = module;
 
        CAM_LOG_INFO("handle[%p], user buffer[%d]", muse_camera, user_buffer_supported);
@@ -1507,8 +1584,7 @@ int camera_dispatcher_change_device(muse_module_h module)
 
        CAM_LOG_INFO("change device to [%d]", device);
 
-       ret = legacy_camera_change_device(&muse_camera->camera_handle, device,
-               CHECK_PREVIEW_CB(muse_camera, PREVIEW_CB_TYPE_EVAS));
+       ret = legacy_camera_change_device(&muse_camera->camera_handle, device);
 
        muse_camera_msg_return(api, class, ret, module);
 
@@ -1929,15 +2005,21 @@ int camera_dispatcher_set_display(muse_module_h module)
        switch (dp_info.type) {
        case CAMERA_DISPLAY_TYPE_OVERLAY:
        case CAMERA_DISPLAY_TYPE_OVERLAY_EXT:
+               ret = __camera_dispatcher_unset_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_EVAS);
+               if (ret != CAMERA_ERROR_NONE) {
+                       CAM_LOG_ERROR("unset preview cb flag for evas failed[0x%x]", ret);
+                       break;
+               }
                CAM_LOG_INFO("wayland global surface id[%d]", muse_camera->window_info.surface_id);
                ret = legacy_camera_set_display(muse_camera->camera_handle,
                        CAMERA_DISPLAY_TYPE_OVERLAY, (void *)&muse_camera->window_info);
                break;
        case CAMERA_DISPLAY_TYPE_EVAS:
-               ret = legacy_camera_set_preview_cb(muse_camera->camera_handle,
-                       (camera_preview_cb)_camera_dispatcher_preview_cb, (void *)module);
-               if (ret == CAMERA_ERROR_NONE)
-                       SET_PREVIEW_CB_TYPE(muse_camera, PREVIEW_CB_TYPE_EVAS);
+               ret = __camera_dispatcher_set_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_EVAS);
+               if (ret != CAMERA_ERROR_NONE) {
+                       CAM_LOG_ERROR("set preview cb flag for evas failed[0x%x]", ret);
+                       break;
+               }
                /* fall through */
        default:
                CAM_LOG_INFO("NOT overlay type. set NONE type.");
@@ -4966,14 +5048,16 @@ int camera_dispatcher_preview_cb_return(muse_module_h module)
                return MUSE_CAMERA_ERROR_NONE;
        }
 
-       /*CAM_LOG_INFO("ENTER");*/
+       CAM_LOG_DEBUG("send PREVIEW_CB_RETURN signal");
 
        g_mutex_lock(&muse_camera->preview_cb_lock);
+
+       muse_camera->preview_cb_returned = TRUE;
        g_cond_signal(&muse_camera->preview_cb_cond);
-       /*CAM_LOG_INFO("send signal for preview callback");*/
+
        g_mutex_unlock(&muse_camera->preview_cb_lock);
 
-       /*CAM_LOG_INFO("DONE");*/
+       CAM_LOG_DEBUG("done");
 
        return MUSE_CAMERA_ERROR_NONE;
 }
@@ -5163,6 +5247,36 @@ int camera_dispatcher_attr_get_flash_brightness_range(muse_module_h module)
 }
 
 
+int camera_dispatcher_set_media_bridge(muse_module_h module)
+{
+       muse_camera_handle_s *muse_camera = NULL;
+
+       muse_camera = (muse_camera_handle_s *)muse_server_ipc_get_handle(module);
+
+       CAM_LOG_INFO("handle[%p]", muse_camera);
+
+       _camera_task_add_job(muse_camera, MUSE_CAMERA_API_SET_MEDIA_BRIDGE,
+               MUSE_CAMERA_API_CLASS_IMMEDIATE, 0);
+
+       return MUSE_CAMERA_ERROR_NONE;
+}
+
+
+int camera_dispatcher_unset_media_bridge(muse_module_h module)
+{
+       muse_camera_handle_s *muse_camera = NULL;
+
+       muse_camera = (muse_camera_handle_s *)muse_server_ipc_get_handle(module);
+
+       CAM_LOG_INFO("handle[%p]", muse_camera);
+
+       _camera_task_add_job(muse_camera, MUSE_CAMERA_API_UNSET_MEDIA_BRIDGE,
+               MUSE_CAMERA_API_CLASS_IMMEDIATE, 0);
+
+       return MUSE_CAMERA_ERROR_NONE;
+}
+
+
 static tbm_bo __camera_normal_buffer_bo_new(MMCamcorderVideoStreamDataType *stream, tbm_bufmgr bufmgr)
 {
        int data_size[3] = {0, 0, 0};
@@ -5505,7 +5619,9 @@ int (*dispatcher[MUSE_CAMERA_API_MAX]) (muse_module_h module) = {
        camera_dispatcher_attr_get_hue_range, /* MUSE_CAMERA_API_ATTR_GET_HUE_RANGE */
        camera_dispatcher_attr_set_flash_brightness, /* MUSE_CAMERA_API_ATTR_SET_FLASH_BRIGHTNESS */
        camera_dispatcher_attr_get_flash_brightness, /* MUSE_CAMERA_API_ATTR_GET_FLASH_BRIGHTNESS */
-       camera_dispatcher_attr_get_flash_brightness_range /* MUSE_CAMERA_API_ATTR_GET_FLASH_BRIGHTNESS_RANGE */
+       camera_dispatcher_attr_get_flash_brightness_range, /* MUSE_CAMERA_API_ATTR_GET_FLASH_BRIGHTNESS_RANGE */
+       camera_dispatcher_set_media_bridge, /* MUSE_CAMERA_API_SET_MEDIA_BRIDGE */
+       camera_dispatcher_unset_media_bridge /* MUSE_CAMERA_API_UNSET_MEDIA_BRIDGE */
 };
 
 
index 3d4aa4d..bc145a2 100644 (file)
@@ -1,6 +1,6 @@
 Name:       mmsvc-camera
 Summary:    A Camera module for muse server
-Version:    0.3.40
+Version:    0.3.41
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0