Add video encoder resource conflict handling 53/127153/4
authorJeongmo Yang <jm80.yang@samsung.com>
Wed, 26 Apr 2017 08:58:50 +0000 (17:58 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Tue, 2 May 2017 01:17:39 +0000 (10:17 +0900)
[Version] 0.10.117
[Profile] Common
[Issue Type] Update
[Dependency module] N/A
[Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-unified_20170421.3]

Change-Id: I727d84086d96ff7553b2f85ad4634cdeeec2815a
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/libmm-camcorder.spec
src/include/mm_camcorder_internal.h
src/include/mm_camcorder_resource.h
src/mm_camcorder_internal.c
src/mm_camcorder_resource.c
src/mm_camcorder_videorec.c

index 03568ec..ecb71f7 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-camcorder
 Summary:    Camera and recorder library
-Version:    0.10.116
+Version:    0.10.117
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index 9406224..5117b99 100644 (file)
@@ -777,7 +777,7 @@ typedef struct mmf_camcorder {
 #ifdef _MMCAMCORDER_MURPHY_SUPPORT
        /* resource manager for H/W resources */
        MMCamcorderResourceManager resource_manager;
-       gboolean resource_release_cb_calling;
+       MMCamcorderResourceManager resource_manager_sub;
 #endif /* _MMCAMCORDER_MURPHY_SUPPORT */
 
        /* gdbus */
index b7d9c9b..492eb2e 100644 (file)
@@ -33,21 +33,30 @@ extern "C" {
 typedef enum {
        MM_CAMCORDER_RESOURCE_TYPE_CAMERA,
        MM_CAMCORDER_RESOURCE_TYPE_VIDEO_OVERLAY,
+       MM_CAMCORDER_RESOURCE_TYPE_VIDEO_ENCODER,
        MM_CAMCORDER_RESOURCE_MAX
 } MMCamcorderResourceType;
 
+typedef enum {
+       MM_CAMCORDER_RESOURCE_ID_MAIN,
+       MM_CAMCORDER_RESOURCE_ID_SUB
+} MMCamcorderResourceID;
+
 typedef struct {
+       MMCamcorderResourceID id;
        mrp_mainloop_t *mloop;
        mrp_res_context_t *context;
        mrp_res_resource_set_t *rset;
-       bool is_connected;
-       void *user_data;
+       gboolean is_connected;
+       gboolean is_release_cb_calling;
        int acquire_count;
        int acquire_remain;
+       void *hcamcorder;
 } MMCamcorderResourceManager;
 
-int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager, void *user_data);
-int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resource_manager, void *hcamcorder);
+int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager);
+int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resource_manager);
+int _mmcamcorder_resource_check_connection(MMCamcorderResourceManager *resource_manager);
 int _mmcamcorder_resource_create_resource_set(MMCamcorderResourceManager *resource_manager);
 int _mmcamcorder_resource_manager_prepare(MMCamcorderResourceManager *resource_manager, MMCamcorderResourceType resource_type);
 int _mmcamcorder_resource_manager_acquire(MMCamcorderResourceManager *resource_manager);
index 7eda99a..855f456 100644 (file)
@@ -396,13 +396,26 @@ int _mmcamcorder_create(MMHandleType *handle, MMCamPreset *info)
                }
 
 #ifdef _MMCAMCORDER_MURPHY_SUPPORT
+               /* set camcorder handle */
+               hcamcorder->resource_manager.id = MM_CAMCORDER_RESOURCE_ID_MAIN;
+               hcamcorder->resource_manager.hcamcorder = hcamcorder;
+               hcamcorder->resource_manager_sub.id = MM_CAMCORDER_RESOURCE_ID_SUB;
+               hcamcorder->resource_manager_sub.hcamcorder = hcamcorder;
+
                /* initialize resource manager */
-               ret = _mmcamcorder_resource_manager_init(&hcamcorder->resource_manager, (void *)hcamcorder);
+               ret = _mmcamcorder_resource_manager_init(&hcamcorder->resource_manager);
                if (ret != MM_ERROR_NONE) {
                        _mmcam_dbg_err("failed to initialize resource manager");
                        ret = MM_ERROR_CAMCORDER_INTERNAL;
                        goto _ERR_DEFAULT_VALUE_INIT;
                }
+
+               ret = _mmcamcorder_resource_manager_init(&hcamcorder->resource_manager_sub);
+               if (ret != MM_ERROR_NONE) {
+                       _mmcam_dbg_err("failed to initialize resource manager sub");
+                       ret = MM_ERROR_CAMCORDER_INTERNAL;
+                       goto _ERR_DEFAULT_VALUE_INIT;
+               }
 #endif /* _MMCAMCORDER_MURPHY_SUPPORT */
        } else {
                _mmcamcorder_conf_get_value_int((MMHandleType)hcamcorder, hcamcorder->conf_main,
@@ -488,7 +501,13 @@ int _mmcamcorder_create(MMHandleType *handle, MMCamPreset *info)
 
 #ifdef _MMCAMCORDER_MURPHY_SUPPORT
        if (info->videodev_type != MM_VIDEO_DEVICE_NONE) {
-               ret = _mmcamcorder_resource_wait_for_connection(&hcamcorder->resource_manager, (void *)hcamcorder);
+               ret = _mmcamcorder_resource_wait_for_connection(&hcamcorder->resource_manager);
+               if (ret != MM_ERROR_NONE) {
+                       _mmcam_dbg_err("failed to connect resource manager");
+                       goto _ERR_DEFAULT_VALUE_INIT;
+               }
+
+               ret = _mmcamcorder_resource_wait_for_connection(&hcamcorder->resource_manager_sub);
                if (ret != MM_ERROR_NONE) {
                        _mmcam_dbg_err("failed to connect resource manager");
                        goto _ERR_DEFAULT_VALUE_INIT;
@@ -508,6 +527,7 @@ int _mmcamcorder_create(MMHandleType *handle, MMCamPreset *info)
 _ERR_DEFAULT_VALUE_INIT:
 #ifdef _MMCAMCORDER_MURPHY_SUPPORT
        /* de-initialize resource manager */
+       _mmcamcorder_resource_manager_deinit(&hcamcorder->resource_manager_sub);
        _mmcamcorder_resource_manager_deinit(&hcamcorder->resource_manager);
 #endif /* _MMCAMCORDER_MURPHY_SUPPORT */
 
@@ -673,6 +693,10 @@ int _mmcamcorder_destroy(MMHandleType handle)
        if (ret != MM_ERROR_NONE)
                _mmcam_dbg_err("failed to de-initialize resource manager 0x%x", ret);
 
+       ret = _mmcamcorder_resource_manager_deinit(&hcamcorder->resource_manager_sub);
+       if (ret != MM_ERROR_NONE)
+               _mmcam_dbg_err("failed to de-initialize resource manager sub 0x%x", ret);
+
        _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
 #endif /* _MMCAMCORDER_MURPHY_SUPPORT */
 
@@ -1059,27 +1083,11 @@ int _mmcamcorder_realize(MMHandleType handle)
 
 #ifdef _MMCAMCORDER_MURPHY_SUPPORT
                /* check connection */
-               if (hcamcorder->resource_manager.is_connected == FALSE) {
-                       _mmcam_dbg_warn("resource manager disconnected before, try to reconnect");
-
-                       /* release remained resource */
-                       _mmcamcorder_resource_manager_deinit(&hcamcorder->resource_manager);
-
-                       /* init resource manager and wait for connection */
-                       ret = _mmcamcorder_resource_manager_init(&hcamcorder->resource_manager, (void *)hcamcorder);
-                       if (ret != MM_ERROR_NONE) {
-                               _mmcam_dbg_err("failed to initialize resource manager");
-                               ret = MM_ERROR_CAMCORDER_INTERNAL;
-                               goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
-                       }
-
-                       ret = _mmcamcorder_resource_wait_for_connection(&hcamcorder->resource_manager, (void *)hcamcorder);
-                       if (ret != MM_ERROR_NONE) {
-                               _mmcam_dbg_err("failed to connect resource manager");
-                               goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
-                       }
-               }
+               ret = _mmcamcorder_resource_check_connection(&hcamcorder->resource_manager);
+               if (ret != MM_ERROR_NONE)
+                       goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
 
+               /* create resource set */
                ret = _mmcamcorder_resource_create_resource_set(&hcamcorder->resource_manager);
                if (ret != MM_ERROR_NONE) {
                        goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
@@ -1351,13 +1359,13 @@ int _mmcamcorder_unrealize(MMHandleType handle)
        }
 
 #ifdef _MMCAMCORDER_MURPHY_SUPPORT
-       _mmcam_dbg_warn("lock resource - cb calling %d", hcamcorder->resource_release_cb_calling);
+       _mmcam_dbg_warn("lock resource - cb calling %d", hcamcorder->resource_manager.is_release_cb_calling);
 
        _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
 
        if (hcamcorder->type == MM_CAMCORDER_MODE_VIDEO_CAPTURE &&
                hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_RM &&
-               hcamcorder->resource_release_cb_calling == FALSE) {
+               hcamcorder->resource_manager.is_release_cb_calling == FALSE) {
                gint64 end_time = 0;
 
                /* release resource */
index c95918e..5ee6847 100644 (file)
@@ -27,7 +27,8 @@
 
 const char* mm_camcorder_resource_str[MM_CAMCORDER_RESOURCE_MAX] = {
        "camera",
-       "video_overlay"
+       "video_overlay",
+       "video_encoder"
 };
 
 #define MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(x_camcorder_resource_manager) \
@@ -79,16 +80,19 @@ static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mr
        int i = 0;
        const mrp_res_resource_set_t *rset;
        mrp_res_resource_t *resource;
-       mmf_camcorder_t* camcorder = NULL;
+       mmf_camcorder_t *hcamcorder = NULL;
+       MMCamcorderResourceManager *resource_manager = (MMCamcorderResourceManager *)user_data;
 
-       camcorder = (mmf_camcorder_t*)user_data;
-
-       mmf_return_if_fail((MMHandleType)camcorder);
        mmf_return_if_fail(context);
+       mmf_return_if_fail(resource_manager);
+
+       hcamcorder = (mmf_camcorder_t *)resource_manager->hcamcorder;
+
+       mmf_return_if_fail(hcamcorder);
 
        _mmcam_dbg_warn("enter - state %d", context->state);
 
-       _MMCAMCORDER_LOCK_RESOURCE(camcorder);
+       _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
 
        switch (context->state) {
        case MRP_RES_CONNECTED:
@@ -98,7 +102,7 @@ static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mr
                        resource_names = mrp_res_list_resource_names(rset);
                        if (!resource_names) {
                                _mmcam_dbg_err(" - no resources available");
-                               _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
+                               _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
                                return;
                        }
                        for (i = 0; i < resource_names->num_strings; i++) {
@@ -108,37 +112,37 @@ static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mr
                        }
                        mrp_res_free_string_array(resource_names);
                }
-               camcorder->resource_manager.is_connected = TRUE;
-               _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
+               resource_manager->is_connected = TRUE;
+               _MMCAMCORDER_RESOURCE_SIGNAL(hcamcorder);
                break;
        case MRP_RES_DISCONNECTED:
-               _mmcam_dbg_err(" - disconnected from Murphy : stop camera");
+               _mmcam_dbg_err(" - disconnected from Murphy : stop camcorder");
 
-               if (camcorder->resource_manager.rset) {
-                       mrp_res_delete_resource_set(camcorder->resource_manager.rset);
-                       camcorder->resource_manager.rset = NULL;
+               if (resource_manager->rset) {
+                       mrp_res_delete_resource_set(resource_manager->rset);
+                       resource_manager->rset = NULL;
                }
 
-               if (camcorder->resource_manager.context) {
-                       mrp_res_destroy(camcorder->resource_manager.context);
-                       camcorder->resource_manager.context = NULL;
-                       camcorder->resource_manager.is_connected = FALSE;
+               if (resource_manager->context) {
+                       mrp_res_destroy(resource_manager->context);
+                       resource_manager->context = NULL;
+                       resource_manager->is_connected = FALSE;
                }
 
-               _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
+               _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
 
-               _MMCAMCORDER_LOCK_ASM(camcorder);
+               _MMCAMCORDER_LOCK_ASM(hcamcorder);
 
                /* Stop the camera */
-               __mmcamcorder_force_stop(camcorder, _MMCAMCORDER_STATE_CHANGE_BY_RM);
+               __mmcamcorder_force_stop(hcamcorder, _MMCAMCORDER_STATE_CHANGE_BY_RM);
 
-               _MMCAMCORDER_UNLOCK_ASM(camcorder);
+               _MMCAMCORDER_UNLOCK_ASM(hcamcorder);
 
-               _MMCAMCORDER_LOCK_RESOURCE(camcorder);
+               _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
                break;
        }
 
-       _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
+       _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
 
        _mmcam_dbg_warn("leave");
 
@@ -149,21 +153,25 @@ static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mr
 static void __mmcamcorder_resource_set_state_callback(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
 {
        int i = 0;
-       mmf_camcorder_t *camcorder = (mmf_camcorder_t *)user_data;
-       mrp_res_resource_t *res;
+       mmf_camcorder_t *hcamcorder = NULL;
+       MMCamcorderResourceManager *resource_manager = (MMCamcorderResourceManager *)user_data;
+       mrp_res_resource_t *res = NULL;
 
-       mmf_return_if_fail((MMHandleType)camcorder);
+       mmf_return_if_fail(resource_manager && resource_manager->hcamcorder);
 
-       _MMCAMCORDER_LOCK_RESOURCE(camcorder);
+       hcamcorder = (mmf_camcorder_t *)resource_manager->hcamcorder;
 
-       if (!mrp_res_equal_resource_set(rs, camcorder->resource_manager.rset)) {
-               _mmcam_dbg_warn("- resource set(%p) is not same as this camcorder handle's(%p)", rs, camcorder->resource_manager.rset);
-               _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
+       _mmcam_dbg_warn("start");
+
+       _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+
+       if (!mrp_res_equal_resource_set(rs, resource_manager->rset)) {
+               _mmcam_dbg_warn("- resource set(%p) is not same as this handle's(%p)", rs, resource_manager->rset);
+               _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
                return;
        }
 
-       _mmcam_dbg_log(" - resource set state of camcorder(%p) is changed to [%s]",
-               camcorder, __mmcamcorder_resource_state_to_str(rs->state));
+       _mmcam_dbg_log(" - resource set state is changed to [%s]", __mmcamcorder_resource_state_to_str(rs->state));
 
        for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
                res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
@@ -174,40 +182,41 @@ static void __mmcamcorder_resource_set_state_callback(mrp_res_context_t *cx, con
                                res->name, __mmcamcorder_resource_state_to_str(res->state));
 
                        if (res->state == MRP_RES_RESOURCE_ACQUIRED) {
-                               camcorder->resource_manager.acquire_remain--;
+                               resource_manager->acquire_remain--;
 
-                               if (camcorder->resource_manager.acquire_remain <= 0) {
+                               if (resource_manager->acquire_remain <= 0) {
                                        _mmcam_dbg_warn("send signal - resource acquire done");
-                                       _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
+                                       _MMCAMCORDER_RESOURCE_SIGNAL(hcamcorder);
                                } else {
                                        _mmcam_dbg_warn("remained acquire count %d",
-                                               camcorder->resource_manager.acquire_remain);
+                                               resource_manager->acquire_remain);
                                }
                        } else if (res->state == MRP_RES_RESOURCE_LOST) {
-                               camcorder->resource_manager.acquire_remain++;
+                               resource_manager->acquire_remain++;
 
-                               if (camcorder->resource_manager.acquire_remain >= camcorder->resource_manager.acquire_count) {
+                               if (resource_manager->acquire_remain >= resource_manager->acquire_count) {
                                        _mmcam_dbg_warn("resource release done");
 
-                                       if (camcorder->state > MM_CAMCORDER_STATE_NULL) {
+                                       if (hcamcorder->state > MM_CAMCORDER_STATE_NULL) {
                                                _mmcam_dbg_warn("send resource signal");
-                                               _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
+                                               _MMCAMCORDER_RESOURCE_SIGNAL(hcamcorder);
                                        } else {
-                                               _mmcam_dbg_warn("skip resource signal - state %d", camcorder->state);
+                                               _mmcam_dbg_warn("skip resource signal - state %d", hcamcorder->state);
                                        }
                                } else {
                                        _mmcam_dbg_warn("acquired %d, lost %d",
-                                               camcorder->resource_manager.acquire_count,
-                                               camcorder->resource_manager.acquire_remain);
+                                               resource_manager->acquire_count, resource_manager->acquire_remain);
                                }
                        }
                }
        }
 
-       mrp_res_delete_resource_set(camcorder->resource_manager.rset);
-       camcorder->resource_manager.rset = mrp_res_copy_resource_set(rs);
+       mrp_res_delete_resource_set(resource_manager->rset);
+       resource_manager->rset = mrp_res_copy_resource_set(rs);
+
+       _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
 
-       _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
+       _mmcam_dbg_warn("done");
 
        return;
 }
@@ -217,33 +226,35 @@ static void __mmcamcorder_resource_release_cb(mrp_res_context_t *cx, const mrp_r
 {
        int i = 0;
        int current_state = MM_CAMCORDER_STATE_NONE;
-       mmf_camcorder_t* camcorder = (mmf_camcorder_t*)user_data;
-       mrp_res_resource_t *res;
+       mmf_camcorder_t *hcamcorder = NULL;
+       MMCamcorderResourceManager *resource_manager = (MMCamcorderResourceManager *)user_data;
+       mrp_res_resource_t *res = NULL;
+
+       mmf_return_if_fail(resource_manager && resource_manager->hcamcorder);
 
-       mmf_return_if_fail((MMHandleType)camcorder);
+       hcamcorder = (mmf_camcorder_t *)resource_manager->hcamcorder;
 
-       current_state = _mmcamcorder_get_state((MMHandleType)camcorder);
+       current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
        if (current_state <= MM_CAMCORDER_STATE_NONE ||
            current_state >= MM_CAMCORDER_STATE_NUM) {
-               _mmcam_dbg_err("Abnormal state. Or null handle. (%p, %d)", camcorder, current_state);
+               _mmcam_dbg_err("Abnormal state %d", current_state);
                return;
        }
 
        _mmcam_dbg_warn("enter");
 
-       _MMCAMCORDER_LOCK_RESOURCE(camcorder);
+       _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
 
-       if (!mrp_res_equal_resource_set(rs, camcorder->resource_manager.rset)) {
-               _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
-               _mmcam_dbg_warn("- resource set(%p) is not same as this camcorder handle's(%p)", rs, camcorder->resource_manager.rset);
+       if (!mrp_res_equal_resource_set(rs, resource_manager->rset)) {
+               _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+               _mmcam_dbg_warn("- resource set(%p) is not same as this handle's(%p)", rs, resource_manager->rset);
                return;
        }
 
        /* set flag for resource release callback */
-       camcorder->resource_release_cb_calling = TRUE;
+       resource_manager->is_release_cb_calling = TRUE;
 
-       _mmcam_dbg_log(" - resource set state of camcorder(%p) is changed to [%s]",
-               camcorder, __mmcamcorder_resource_state_to_str(rs->state));
+       _mmcam_dbg_log(" - resource set state is changed to [%s]", __mmcamcorder_resource_state_to_str(rs->state));
 
        for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
                res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
@@ -254,21 +265,29 @@ static void __mmcamcorder_resource_release_cb(mrp_res_context_t *cx, const mrp_r
                }
        }
 
-       _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
+       _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
 
-       _MMCAMCORDER_LOCK_ASM(camcorder);
+       _MMCAMCORDER_LOCK_ASM(hcamcorder);
 
-       /* Stop the camera */
-       __mmcamcorder_force_stop(camcorder, _MMCAMCORDER_STATE_CHANGE_BY_RM);
+       if (resource_manager->id == MM_CAMCORDER_RESOURCE_ID_MAIN) {
+               /* Stop camera */
+               __mmcamcorder_force_stop(hcamcorder, _MMCAMCORDER_STATE_CHANGE_BY_RM);
+       } else {
+               /* Stop video recording */
+               if (_mmcamcorder_commit((MMHandleType)hcamcorder) != MM_ERROR_NONE) {
+                       _mmcam_dbg_err("commit failed, cancel it");
+                       _mmcamcorder_cancel((MMHandleType)hcamcorder);
+               }
+       }
 
-       _MMCAMCORDER_UNLOCK_ASM(camcorder);
+       _MMCAMCORDER_UNLOCK_ASM(hcamcorder);
 
-       _MMCAMCORDER_LOCK_RESOURCE(camcorder);
+       _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
 
        /* restore flag for resource release callback */
-       camcorder->resource_release_cb_calling = FALSE;
+       resource_manager->is_release_cb_calling = FALSE;
 
-       _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
+       _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
 
        _mmcam_dbg_warn("leave");
 
@@ -284,7 +303,7 @@ int _mmcamcorder_resource_create_resource_set(MMCamcorderResourceManager *resour
        }
 
        resource_manager->rset = mrp_res_create_resource_set(resource_manager->context,
-               MRP_APP_CLASS_FOR_CAMCORDER, __mmcamcorder_resource_set_state_callback, (void*)resource_manager->user_data);
+               MRP_APP_CLASS_FOR_CAMCORDER, __mmcamcorder_resource_set_state_callback, (void *)resource_manager);
 
        if (resource_manager->rset == NULL) {
                _mmcam_dbg_err(" - could not create resource set");
@@ -326,7 +345,7 @@ static int __mmcamcorder_resource_set_release_cb(MMCamcorderResourceManager *res
        bool mrp_ret = FALSE;
 
        if (resource_manager->rset) {
-               mrp_ret = mrp_res_set_release_callback(resource_manager->rset, __mmcamcorder_resource_release_cb, resource_manager->user_data);
+               mrp_ret = mrp_res_set_release_callback(resource_manager->rset, __mmcamcorder_resource_release_cb, (void *)resource_manager);
                if (!mrp_ret) {
                        _mmcam_dbg_err(" - could not set release callback");
                        ret = MM_ERROR_RESOURCE_INTERNAL;
@@ -339,7 +358,7 @@ static int __mmcamcorder_resource_set_release_cb(MMCamcorderResourceManager *res
        return ret;
 }
 
-int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager, void *user_data)
+int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager)
 {
        GMainContext *mrp_ctx = NULL;
        GMainLoop *mrp_loop = NULL;
@@ -376,7 +395,7 @@ int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_mana
 
        _mmcam_dbg_warn("mloop %p", resource_manager->mloop);
 
-       resource_manager->context = mrp_res_create(resource_manager->mloop, __mmcamcorder_resource_state_callback, user_data);
+       resource_manager->context = mrp_res_create(resource_manager->mloop, __mmcamcorder_resource_state_callback, (void *)resource_manager);
        if (!resource_manager->context) {
                _mmcam_dbg_err("could not get context for mrp");
 
@@ -386,19 +405,20 @@ int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_mana
                return MM_ERROR_RESOURCE_INTERNAL;
        }
 
-       resource_manager->user_data = user_data;
-
        _mmcam_dbg_log("done");
 
        return MM_ERROR_NONE;
 }
 
 
-int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resource_manager, void *hcamcorder)
+int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resource_manager)
 {
        int ret = MM_ERROR_NONE;
+       void *hcamcorder = NULL;
+
+       mmf_return_val_if_fail(resource_manager && resource_manager->hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
 
-       mmf_return_val_if_fail(resource_manager && hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+       hcamcorder = resource_manager->hcamcorder;
 
        _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
 
@@ -418,7 +438,7 @@ int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resour
                        ret = MM_ERROR_RESOURCE_INTERNAL;
                }
        } else {
-               _mmcam_dbg_warn("already connected");
+               _mmcam_dbg_warn("already connected [%d]", resource_manager->id);
        }
 
        _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
@@ -427,6 +447,38 @@ int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resour
 }
 
 
+int _mmcamcorder_resource_check_connection(MMCamcorderResourceManager *resource_manager)
+{
+       int ret = MM_ERROR_NONE;
+
+       mmf_return_val_if_fail(resource_manager, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+       if (resource_manager->is_connected == FALSE) {
+               _mmcam_dbg_warn("resource manager[%d] disconnected before, try to reconnect", resource_manager->id);
+
+               /* release remained resource */
+               _mmcamcorder_resource_manager_deinit(resource_manager);
+
+               /* init resource manager and wait for connection */
+               ret = _mmcamcorder_resource_manager_init(resource_manager);
+               if (ret != MM_ERROR_NONE) {
+                       _mmcam_dbg_err("failed to initialize resource manager[%d]", resource_manager->id);
+                       return ret;
+               }
+
+               ret = _mmcamcorder_resource_wait_for_connection(resource_manager);
+               if (ret != MM_ERROR_NONE) {
+                       _mmcam_dbg_err("failed to connect resource manager[%d]", resource_manager->id);
+                       return ret;
+               }
+       }
+
+       _mmcam_dbg_warn("done[%d]", resource_manager->id);
+
+       return ret;
+}
+
+
 int _mmcamcorder_resource_manager_prepare(MMCamcorderResourceManager *resource_manager, MMCamcorderResourceType resource_type)
 {
        MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
index e80d0e2..70badfc 100644 (file)
@@ -354,6 +354,10 @@ int _mmcamcorder_remove_encode_pipeline(MMHandleType handle)
        GstPad *reqpad = NULL;
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
        _MMCamcorderSubContext *sc = NULL;
+#ifdef _MMCAMCORDER_MURPHY_SUPPORT
+       int ret = MM_ERROR_NONE;
+       MMCamcorderResourceManager *resource_manager = NULL;
+#endif /* _MMCAMCORDER_MURPHY_SUPPORT */
 
        mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
 
@@ -393,7 +397,36 @@ int _mmcamcorder_remove_encode_pipeline(MMHandleType handle)
                /* _mmcamcorder_remove_element_handle(handle, (void *)sc->encode_element,
                        _MMCAMCORDER_ENCODE_MAIN_PIPE, _MMCAMCORDER_ENCSINK_SINK); */
 
-               _mmcam_dbg_log("Encoder pipeline removed");
+               _mmcam_dbg_warn("Encoder pipeline removed");
+
+#ifdef _MMCAMCORDER_MURPHY_SUPPORT
+               resource_manager = &hcamcorder->resource_manager_sub;
+
+               _mmcam_dbg_warn("lock resource - cb calling %d", resource_manager->is_release_cb_calling);
+
+               _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+
+               if (resource_manager->is_release_cb_calling == FALSE) {
+                       gint64 end_time = 0;
+
+                       /* release resource */
+                       ret = _mmcamcorder_resource_manager_release(resource_manager);
+
+                       _mmcam_dbg_warn("release resource 0x%x", ret);
+#ifdef _MMCAMCORDER_MURPHY_WAIT_TO_RELEASE_SUB_RESOURCE
+                       if (resource_manager->acquire_remain < resource_manager->acquire_count) {
+                               /* wait for resource release */
+                               _mmcam_dbg_log("resource is not released all. wait for signal...");
+                               end_time = g_get_monotonic_time() + (__MMCAMCORDER_RESOURCE_WAIT_TIME * G_TIME_SPAN_SECOND);
+                               _MMCAMCORDER_RESOURCE_WAIT_UNTIL(hcamcorder, end_time);
+                       }
+#endif /* _MMCAMCORDER_MURPHY_WAIT_TO_RELEASE_SUB_RESOURCE */
+               }
+
+               _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+
+               _mmcam_dbg_warn("unlock resource");
+#endif /* _MMCAMCORDER_MURPHY_SUPPORT */
        }
 
        return MM_ERROR_NONE;
@@ -518,6 +551,60 @@ int _mmcamcorder_video_command(MMHandleType handle, int command)
                        /* Recording */
                        _mmcam_dbg_log("Record Start - dual stream %d", info->support_dual_stream);
 
+#ifdef _MMCAMCORDER_MURPHY_SUPPORT
+                       /* check connection */
+                       ret = _mmcamcorder_resource_check_connection(&hcamcorder->resource_manager_sub);
+                       if (ret != MM_ERROR_NONE)
+                               goto _ERR_CAMCORDER_VIDEO_COMMAND;
+
+                       /* create resource set */
+                       ret = _mmcamcorder_resource_create_resource_set(&hcamcorder->resource_manager_sub);
+                       if (ret != MM_ERROR_NONE)
+                               goto _ERR_CAMCORDER_VIDEO_COMMAND;
+
+                       hcamcorder->resource_manager_sub.acquire_count = 0;
+
+                       /* prepare resource manager for H/W encoder */
+                       ret = _mmcamcorder_resource_manager_prepare(&hcamcorder->resource_manager_sub, MM_CAMCORDER_RESOURCE_TYPE_VIDEO_ENCODER);
+                       if (ret != MM_ERROR_NONE) {
+                               _mmcam_dbg_err("could not prepare for video_encoder resource");
+                               ret = MM_ERROR_CAMCORDER_INTERNAL;
+                               goto _ERR_CAMCORDER_VIDEO_COMMAND;
+                       }
+
+                       /* acquire resources */
+                       _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
+
+                       ret = _mmcamcorder_resource_manager_acquire(&hcamcorder->resource_manager_sub);
+                       if (ret != MM_ERROR_NONE) {
+                               _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+                               _mmcam_dbg_err("could not acquire resource");
+                               goto _ERR_CAMCORDER_VIDEO_COMMAND;
+                       }
+
+                       if (hcamcorder->resource_manager_sub.acquire_remain > 0) {
+                               gint64 end_time = 0;
+
+                               _mmcam_dbg_warn("wait for resource state change");
+
+                               /* wait for resource state change */
+                               end_time = g_get_monotonic_time() + (__MMCAMCORDER_RESOURCE_WAIT_TIME * G_TIME_SPAN_SECOND);
+
+                               if (_MMCAMCORDER_RESOURCE_WAIT_UNTIL(hcamcorder, end_time)) {
+                                       _mmcam_dbg_warn("signal received");
+                               } else {
+                                       _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+                                       _mmcam_dbg_err("timeout");
+                                       ret = MM_ERROR_RESOURCE_INTERNAL;
+                                       goto _ERR_CAMCORDER_VIDEO_COMMAND;
+                               }
+                       } else {
+                               _mmcam_dbg_log("already acquired");
+                       }
+
+                       _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
+#endif /* _MMCAMCORDER_MURPHY_SUPPORT */
+
                        /* init record_dual_stream */
                        info->record_dual_stream = FALSE;