Enable resource manager commonization 58/318858/3 accepted/tizen_9.0_unified accepted/tizen_unified accepted/tizen_unified_toolchain accepted/tizen_unified_x accepted/tizen_unified_x_asan tizen tizen_9.0 accepted/tizen/9.0/unified/20241030.233717 accepted/tizen/unified/20241016.160056 accepted/tizen/unified/toolchain/20241022.122409 accepted/tizen/unified/toolchain/20241022.122850 accepted/tizen/unified/x/20241017.030737 accepted/tizen/unified/x/asan/20241022.113433 tizen_9.0_m2_release
authorYoungHun Kim <yh8004.kim@samsung.com>
Thu, 10 Oct 2024 04:46:17 +0000 (13:46 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Fri, 11 Oct 2024 05:10:19 +0000 (14:10 +0900)
[Version] 0.1.0
[Issue Type] Update

Change-Id: I7faa4dbb952f9fec820fdec03bb43a3733e9efbd

CMakeLists.txt
include/media_editor_private.h
packaging/capi-media-editor.spec
src/media_editor_ini.c
src/media_editor_private.c
src/media_editor_resource.c

index 89e8b59d35553ef7f32437fb39d259e60059daf7..d4d5dee7c18ace50cdd2ef2b0cd003128c8a275d 100644 (file)
@@ -14,7 +14,7 @@ SET(dependents "glib-2.0 gio-2.0 dlog iniparser capi-base-common mm-common mm-di
 SET(pc_dependents "capi-base-common")
 
 IF(NOT TIZEN_PROFILE_TV)
-    SET(dependents "${dependents} mm-resource-manager")
+    SET(dependents "${dependents} resource-manager resource-information resource-center-api")
 ELSE()
     ADD_DEFINITIONS("-DTIZEN_TV")
 ENDIF()
index 518ccd32d3fc96652fe6c33fcfffc9db80ee5c29..fb25bdfb7b182641431b87508348351ba80f4baf 100644 (file)
@@ -26,7 +26,7 @@
 #include <iniparser.h>
 #include <mm_display_interface.h>
 #ifndef TIZEN_TV
-#include <mm_resource_manager.h>
+#include <rm_api.h>
 #endif
 
 #ifdef __cplusplus
@@ -200,13 +200,18 @@ do { \
 #define AUTOCLEAN_LOCKER(x) g_autoptr(GMutexLocker) locker = g_mutex_locker_new(x);
 
 #ifndef TIZEN_TV
-#define RESOURCE_TYPE_MAX MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER + 1
+typedef enum {
+    RES_TYPE_VIDEO_DECODER,     /**< ID of video decoder resource type */
+    RES_TYPE_VIDEO_ENCODER,     /**< ID of video encoder resource type */
+    RES_TYPE_MAX,               /**< Used to iterate on resource types only */
+} res_type_e;
 
 typedef struct _mediaeditor_resource_s {
-    mm_resource_manager_h mgr;
-    mm_resource_manager_res_h res[RESOURCE_TYPE_MAX];
-    gboolean need_to_acquire[RESOURCE_TYPE_MAX];
-    gboolean release_cb_is_calling;
+    int rm_h;
+    rm_device_return_s devices[RES_TYPE_MAX];
+    rm_consumer_info rci;
+    GMutex callback_lock;
+    GMutex control_lock;
 } mediaeditor_resource_s;
 #endif
 
@@ -350,7 +355,7 @@ int _get_track(mediaeditor_s *editor, track_type_e track_type, GESTrack **track)
 #ifndef TIZEN_TV
 /* media_editor_resource */
 int _create_resource_manager(mediaeditor_s *editor);
-int _acquire_resource_for_type(mediaeditor_s *editor, mm_resource_manager_res_type_e type);
+int _acquire_resource_for_type(mediaeditor_s *editor, res_type_e type);
 int _release_all_resources(mediaeditor_s *editor);
 int _destroy_resource_manager(mediaeditor_s *editor);
 #endif
index 39433e70232b6452602b1e4be7f0bcca68dc044a..61d3e91ed6c86df620a4293e13758a2115c8f09b 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-editor
 Summary:    A Tizen Media Editor API
-Version:    0.0.19
+Version:    0.1.0
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
@@ -32,7 +32,9 @@ BuildRequires:  gtest
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
 %if "%{tizen_profile_name}" != "tv"
-BuildRequires:  pkgconfig(mm-resource-manager)
+BuildRequires:  pkgconfig(resource-manager)
+BuildRequires:  pkgconfig(resource-information)
+BuildRequires:  pkgconfig(resource-center-api)
 %endif
 
 %description
index 3f3bc16755d80a9a107ff69363b3ebc4f493dd9e..2033e7e9240dac8d71c45c90946eeebfab450d23 100644 (file)
@@ -107,8 +107,8 @@ static void __dump_ini(mediaeditor_ini_s *ini)
     __dump_item(INI_ITEM_VIDEO_HW_DECODER, INI_ITEM_TYPE_STRING, (void *)ini->decoder.video_hw_decoder);
 
     LOG_INFO("[%s]", INI_CATEGORY_RESOURCE_ACQUISITION);
-    __dump_item(INI_ITEM_RESOURCE_VIDEO_ENCODER, INI_ITEM_TYPE_STRING, (void *)ini->resource_acquisition.video_encoder);
-    __dump_item(INI_ITEM_RESOURCE_VIDEO_DECODER, INI_ITEM_TYPE_STRING, (void *)ini->resource_acquisition.video_decoder);
+    __dump_item(INI_ITEM_RESOURCE_VIDEO_ENCODER, INI_ITEM_TYPE_STRING, (void *)&ini->resource_acquisition.video_encoder);
+    __dump_item(INI_ITEM_RESOURCE_VIDEO_DECODER, INI_ITEM_TYPE_STRING, (void *)&ini->resource_acquisition.video_decoder);
 }
 
 static const char* __get_delimiter(const char *ini_path)
index fede6247c225dba1292fbf65d06bdee681094cf7..d3374b23b79d1874884f502fb660d662090fc62e 100644 (file)
@@ -310,8 +310,10 @@ static gboolean __bus_cb(GstBus *bus, GstMessage *message, gpointer *data)
         __invoke_render_completed_cb(editor);
 
 #ifndef TIZEN_TV
-        ret = _release_all_resources(editor);
-        RET_VAL_IF(ret != MEDIAEDITOR_ERROR_NONE, ret, "failed to release all resources");
+        if (_is_resource_required(&editor->ini)) {
+            ret = _release_all_resources(editor);
+            RET_VAL_IF(ret != MEDIAEDITOR_ERROR_NONE, ret, "failed to release all resources");
+        }
 #endif
 
         editor->state = MEDIAEDITOR_STATE_IDLE;
@@ -612,12 +614,12 @@ int _mediaeditor_start_render(mediaeditor_s *editor, const char* path)
 
 #ifndef TIZEN_TV
     if (editor->ini.resource_acquisition.video_decoder) {
-        ret = _acquire_resource_for_type(editor, MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER);
+        ret = _acquire_resource_for_type(editor, RES_TYPE_VIDEO_DECODER);
         RET_VAL_IF(ret != MEDIAEDITOR_ERROR_NONE, ret, "failed to acquire video decoder resource");
     }
 
     if (editor->ini.resource_acquisition.video_encoder) {
-        ret = _acquire_resource_for_type(editor, MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER);
+        ret = _acquire_resource_for_type(editor, RES_TYPE_VIDEO_ENCODER);
         RET_VAL_IF(ret != MEDIAEDITOR_ERROR_NONE, ret, "failed to acquire video encoder resource");
     }
 #endif
index c09ac3554665045e780cf924ed90252a7167524f..2ad22a83d6bbaaaf67cb7ee04b011e77ae48f857 100644 (file)
 
 #include "media_editor.h"
 #include "media_editor_private.h"
+#include <rm_type.h>
+#include <resource_center.h>
 
-//LCOV_EXCL_START
 #ifndef TIZEN_TV
-static int __resource_release_cb(mm_resource_manager_h mgr,
-        mm_resource_manager_res_h res, void *user_data)
+//LCOV_EXCL_START
+static int __get_appid_by_pid(int pid, char *name, size_t size)
 {
-    int ret = true;
-    mediaeditor_s *editor = (mediaeditor_s *)user_data;
+    g_autofree gchar *cmdline = NULL;
+    g_autofree gchar *contents = NULL;
+    g_autofree gchar *base = NULL;
+    g_autoptr(GError) error = NULL;
 
-    RET_VAL_IF(editor == NULL, false, "editor is NULL");
+    RET_VAL_IF(name == NULL, MEDIAEDITOR_ERROR_INVALID_PARAMETER, "name is NULL");
+    RET_VAL_IF(size == 0, MEDIAEDITOR_ERROR_INVALID_PARAMETER, "size is 0");
 
-    editor->resource.release_cb_is_calling = true;
+    cmdline = g_strdup_printf("/proc/%d/cmdline", pid);
 
-    for (int i = 0; i < RESOURCE_TYPE_MAX; i++) {
-        if (editor->resource.res[i] == res) {
-            LOG_INFO("type[%d] resource was released by resource manager", i);
-            editor->resource.res[i] = NULL;
-        }
+    if (!g_file_get_contents(cmdline, &contents, NULL, &error)) {
+        LOG_ERROR("error : %s", error->message);
+        return MEDIAEDITOR_ERROR_INVALID_OPERATION;
     }
 
-    if (_mediaeditor_stop(editor) != MEDIAEDITOR_ERROR_NONE)
-        ret = false;
+    base = g_path_get_basename(contents);
 
-    _post_error_cb_in_idle(editor, MEDIAEDITOR_ERROR_RESOURCE_CONFLICT);
+    if (g_strlcpy(name, base, size) >= size) {
+        LOG_ERROR("string truncated");
+        return MEDIAEDITOR_ERROR_INVALID_OPERATION;
+    }
 
-    editor->resource.release_cb_is_calling = false;
+    return MEDIAEDITOR_ERROR_NONE;
+}
 
-    return ret;
+static void __resource_release(mediaeditor_s *editor)
+{
+    RET_IF(editor == NULL, "editor is NULL");
+
+    if (_mediaeditor_stop(editor) != MEDIAEDITOR_ERROR_NONE) {
+        LOG_ERROR("_mediaeditor_stop is failed");
+        return;
+    }
+
+    _post_error_cb_in_idle(editor, MEDIAEDITOR_ERROR_RESOURCE_CONFLICT);
 }
-//LCOV_EXCL_STOP
 
-static bool __is_valid_resource_type(mm_resource_manager_res_type_e type)
+static rm_cb_result __rm_callback(int handle, rm_callback_type event_src,
+    rm_device_request_s *info, void *cb_data)
 {
-    if (type < MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER || type >= RESOURCE_TYPE_MAX) {
-        LOG_ERROR("Type[%d] is a invalid resource type", type);
-        return false;
+    mediaeditor_s *editor = (mediaeditor_s *)cb_data;
+    g_autoptr(GMutexLocker) locker = NULL;
+
+    RET_VAL_IF(editor == NULL, RM_CB_RESULT_ERROR, "editor is NULL");
+
+    locker = g_mutex_locker_new(&editor->resource.callback_lock);
+
+    LOG_INFO("editor[%p] rm handle[%d] event_src[%d]", editor, handle, event_src);
+
+    switch (event_src) {
+    case RM_CALLBACK_TYPE_RESOURCE_CONFLICT:
+    case RM_CALLBACK_TYPE_RESOURCE_CONFLICT_UD:
+        __resource_release(editor);
+        break;
+    default:
+        break;
     }
-    return true;
+
+    LOG_DEBUG_LEAVE();
+
+    return RM_CB_RESULT_OK;
 }
+//LCOV_EXCL_STOP
 
 int _create_resource_manager(mediaeditor_s *editor)
 {
+    int ret = 0;
     NULL_PARAM_CHECK(editor);
 
-    if (mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
-                __resource_release_cb, editor,
-                &editor->resource.mgr) != MM_RESOURCE_MANAGER_ERROR_NONE) {
-        LOG_ERROR("Failed to init resource manager for media");
+    g_mutex_init(&editor->resource.control_lock);
+    g_mutex_init(&editor->resource.callback_lock);
+
+    memset(&editor->resource.rci, 0x00, sizeof(rm_consumer_info));
+
+    editor->resource.rci.app_pid = (int)getpid();
+
+    if (__get_appid_by_pid(editor->resource.rci.app_pid,
+                        editor->resource.rci.app_id,
+                        sizeof(editor->resource.rci.app_id)) != MEDIAEDITOR_ERROR_NONE) {
+        LOGE("__get_appid_by_pid is failed");
+        return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
+    }
+
+    ret = rm_register((rm_resource_cb)__rm_callback,
+                        (void *)editor,
+                        &(editor->resource.rm_h),
+                        (editor->resource.rci.app_id[0] != '\0') ? &editor->resource.rci : NULL);
+
+    if (ret != RM_OK) {
+        LOG_ERROR("rm_register fail %d", ret);
         return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
     }
 
+    LOG_INFO("app pid %d app id %s resource h %d", editor->resource.rci.app_pid, editor->resource.rci.app_id, editor->resource.rm_h);
+
     return MEDIAEDITOR_ERROR_NONE;
 }
 
-int _acquire_resource_for_type(mediaeditor_s *editor, mm_resource_manager_res_type_e type)
+int _acquire_resource_for_type(mediaeditor_s *editor, res_type_e type)
 {
-    int ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-
     NULL_PARAM_CHECK(editor);
 
-    if (!editor->resource.mgr) {
-        LOG_DEBUG("There's no acquired hw encoder, decoder resources");
-        return MEDIAEDITOR_ERROR_NONE;
-    }
-
-    RET_VAL_IF(!__is_valid_resource_type(type), MEDIAEDITOR_ERROR_INVALID_PARAMETER,
-            "type is wrong");
+    int ret = RM_OK;
+    int idx = 0;
+    int category_option = 0;
+    rm_rsc_category_e category_id = RM_CATEGORY_NONE;
+    rm_requests_resource_state_e state;
+    rm_category_request_s request_resources;
+    rm_device_return_s *device;
+    g_autoptr(GMutexLocker) locker = NULL;
+
+    RET_VAL_IF(editor == NULL, MEDIAEDITOR_ERROR_INVALID_PARAMETER, "editor is NULL");
+    RET_VAL_IF(type >= RES_TYPE_MAX, MEDIAEDITOR_ERROR_INVALID_PARAMETER, "invalid type(%d)", type);
+
+    locker = g_mutex_locker_new(&editor->resource.control_lock);
+
+    LOG_INFO("app id : %s type %d", editor->resource.rci.app_id, type);
+    memset(&request_resources, 0x0, sizeof(rm_category_request_s));
+
+    device = &editor->resource.devices[type];
+    memset(device, 0x0, sizeof(rm_device_return_s));
+
+    switch (type) {
+    case RES_TYPE_VIDEO_DECODER:
+        state = RM_STATE_EXCLUSIVE;
+        category_id = RM_CATEGORY_VIDEO_DECODER;
+        break;
+    case RES_TYPE_VIDEO_ENCODER:
+        state = RM_STATE_EXCLUSIVE;
+        category_id = RM_CATEGORY_VIDEO_ENCODER;
+        break;
+    default:
+        LOG_ERROR("category id can't set");
 
-    if (editor->resource.res[type] != NULL) {
-        LOG_ERROR("type[%d] resource was already acquired", type);
         return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
     }
 
-    LOG_DEBUG("mark for acquire type[%d] resource", type);
-    ret = mm_resource_manager_mark_for_acquire(editor->resource.mgr, type,
-                MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &editor->resource.res[type]);
-    if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-        LOG_ERROR("failed to mark resource for acquire, ret[0x%x]", ret);
-        return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
-    }
+    category_option = rc_get_capable_category_id(editor->resource.rm_h, editor->resource.rci.app_id, category_id);
+
+    request_resources.request_num = 1;
+    request_resources.state[0] = state;
+    request_resources.category_id[0] = category_id;
+    request_resources.category_option[0] = category_option;
+    LOG_INFO("state %d category id 0x%x category option %d", state, category_id, category_option);
 
-    LOG_DEBUG("commit type[%d] resource", type);
-    ret = mm_resource_manager_commit(editor->resource.mgr);
-    if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-        LOG_ERROR("failed to commit of resource, ret([0x%x]", ret);
+    ret = rm_allocate_resources(editor->resource.rm_h, &request_resources, device);
+    if (ret != RM_OK) {
+        LOG_ERROR("Resource allocation request failed ret %d [error type %d]", ret, device->error_type);
         return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
     }
 
+    for (idx = 0; idx < device->allocated_num; idx++)
+        LOG_INFO("#%d / %d [%p] device %d %s %s", idx, device->allocated_num, device,
+            device->device_id[idx], device->device_node[idx],
+            device->device_name[idx]);
+
     return MEDIAEDITOR_ERROR_NONE;
 }
 
 int _release_all_resources(mediaeditor_s *editor)
 {
-    int ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-
     NULL_PARAM_CHECK(editor);
 
-    if (!editor->resource.mgr) {
-        LOG_DEBUG("There's no acquired hw encoder, decoder resources");
-        return MEDIAEDITOR_ERROR_NONE;
-    }
+    int rm_ret = RM_OK;
+    int idx = 0;
+    rm_device_request_s requested;
+    rm_device_return_s *devices;
+    res_type_e type;
+    g_autoptr(GMutexLocker) locker = NULL;
 
-    if (editor->resource.release_cb_is_calling) {
-        LOG_INFO("__resource_release_cb is calling, so skip");
-        return MEDIAEDITOR_ERROR_NONE;
-    }
+    RET_VAL_IF(editor == NULL, MEDIAEDITOR_ERROR_INVALID_PARAMETER, "editor is NULL");
+    RET_VAL_IF(editor->resource.rm_h == 0, MEDIAEDITOR_ERROR_RESOURCE_FAILED, "editor resource handle is NULL");
 
-    ret = mm_resource_manager_mark_all_for_release(editor->resource.mgr);
-    if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-        LOG_ERROR("failed to mark all for release, ret[0x%x]", ret);
-        return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
-    }
+    locker = g_mutex_locker_new(&editor->resource.control_lock);
 
-    ret = mm_resource_manager_commit(editor->resource.mgr);
-    if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-        LOG_ERROR("failed to commit resource, ret[0x%x]", ret);
-        return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
-    }
-    LOG_DEBUG("all resources were released by resource manager");
+    for (type = RES_TYPE_VIDEO_DECODER; type < RES_TYPE_MAX; type++) {
+        devices = &editor->resource.devices[type];
+
+        LOG_INFO("[%p] #%d (type %d) alloc num %d", devices, idx, type, devices->allocated_num);
+
+        if (devices->allocated_num > 0) {
+            memset(&requested, 0x0, sizeof(rm_device_request_s));
+            requested.request_num = devices->allocated_num;
+            for (idx = 0; idx < requested.request_num; idx++) {
+                requested.device_id[idx] = devices->device_id[idx];
+                LOG_INFO("[device id %d] [device name %s]", devices->device_id[idx], devices->device_name[idx]);
+            }
 
-    for (int i = 0; i < RESOURCE_TYPE_MAX; i++) {
-        editor->resource.need_to_acquire[i] = false;
-        editor->resource.res[i] = NULL;
+            rm_ret = rm_deallocate_resources(editor->resource.rm_h, &requested);
+            if (rm_ret != RM_OK) {
+                LOG_ERROR("Resource deallocation request failed [%d] [request num %d]", rm_ret, requested.request_num);
+                return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
+            }
+        }
+
+        for (idx = 0; idx < devices->allocated_num; idx++) {
+            if (devices->device_node[idx]) {
+                free(devices->device_node[idx]);
+                devices->device_node[idx] = NULL;
+            }
+
+            if (devices->omx_comp_name[idx]) {
+                free(devices->omx_comp_name[idx]);
+                devices->omx_comp_name[idx] = NULL;
+            }
+        }
     }
 
     return MEDIAEDITOR_ERROR_NONE;
@@ -146,22 +236,21 @@ int _release_all_resources(mediaeditor_s *editor)
 
 int _destroy_resource_manager(mediaeditor_s *editor)
 {
-    int ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+    int ret = MEDIAEDITOR_ERROR_NONE;
 
     NULL_PARAM_CHECK(editor);
 
-    if (!editor->resource.mgr) {
-        LOG_DEBUG("There's no acquired hw encoder, decoder resources");
-        return MEDIAEDITOR_ERROR_NONE;
-    }
+    RET_VAL_IF(editor == NULL, MEDIAEDITOR_ERROR_INVALID_PARAMETER, "editor is NULL");
+    RET_VAL_IF(editor->resource.rm_h == 0, MEDIAEDITOR_ERROR_RESOURCE_FAILED, "editor resource handle is NULL");
 
-    ret = mm_resource_manager_destroy(editor->resource.mgr);
-    if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-        LOG_ERROR("failed to destroy resource manager, ret[0x%x]", ret);
+    ret = rm_unregister(editor->resource.rm_h);
+    if (ret != RM_OK) {
+        LOGE("rm_unregister fail %d", ret);
         return MEDIAEDITOR_ERROR_RESOURCE_FAILED;
     }
 
-    editor->resource.mgr = NULL;
+    g_mutex_clear(&editor->resource.control_lock);
+
     LOG_DEBUG("destroyed resource manager");
 
     return MEDIAEDITOR_ERROR_NONE;