From: Jeongmo Yang Date: Wed, 26 Apr 2017 08:58:50 +0000 (+0900) Subject: Add video encoder resource conflict handling X-Git-Tag: submit/tizen/20170502.041616~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F53%2F127153%2F4;p=platform%2Fcore%2Fmultimedia%2Flibmm-camcorder.git Add video encoder resource conflict handling [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 --- diff --git a/packaging/libmm-camcorder.spec b/packaging/libmm-camcorder.spec index 03568ec..ecb71f7 100644 --- a/packaging/libmm-camcorder.spec +++ b/packaging/libmm-camcorder.spec @@ -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 diff --git a/src/include/mm_camcorder_internal.h b/src/include/mm_camcorder_internal.h index 9406224..5117b99 100644 --- a/src/include/mm_camcorder_internal.h +++ b/src/include/mm_camcorder_internal.h @@ -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 */ diff --git a/src/include/mm_camcorder_resource.h b/src/include/mm_camcorder_resource.h index b7d9c9b..492eb2e 100644 --- a/src/include/mm_camcorder_resource.h +++ b/src/include/mm_camcorder_resource.h @@ -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); diff --git a/src/mm_camcorder_internal.c b/src/mm_camcorder_internal.c index 7eda99a..855f456 100644 --- a/src/mm_camcorder_internal.c +++ b/src/mm_camcorder_internal.c @@ -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 */ diff --git a/src/mm_camcorder_resource.c b/src/mm_camcorder_resource.c index c95918e..5ee6847 100644 --- a/src/mm_camcorder_resource.c +++ b/src/mm_camcorder_resource.c @@ -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); diff --git a/src/mm_camcorder_videorec.c b/src/mm_camcorder_videorec.c index e80d0e2..70badfc 100644 --- a/src/mm_camcorder_videorec.c +++ b/src/mm_camcorder_videorec.c @@ -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;