[1.1.0] Enable resource manager commonization 74/312574/41 accepted/tizen_unified accepted/tizen_unified_dev accepted/tizen_unified_x tizen accepted/tizen/unified/20240819.043954 accepted/tizen/unified/dev/20240821.053435 accepted/tizen/unified/x/20240819.023527
authorYoungHun Kim <yh8004.kim@samsung.com>
Wed, 12 Jun 2024 00:08:26 +0000 (09:08 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Fri, 2 Aug 2024 01:29:41 +0000 (10:29 +0900)
Change-Id: I626b8ce75e1c6908ed3380811316f24c207945d9

configure.ac
packaging/libmm-player.spec
src/Makefile.am
src/include/mm_player_priv.h
src/include/mm_player_rm.h [new file with mode: 0644]
src/include/mm_player_utils.h
src/mm_player_attrs.c
src/mm_player_gst.c
src/mm_player_priv.c
src/mm_player_rm.c [new file with mode: 0644]

index 3b591e2..5bc6076 100644 (file)
@@ -99,9 +99,25 @@ PKG_CHECK_MODULES(MEDIAPACKET, capi-media-tool)
 AC_SUBST(MEDIAPACKET_CFLAGS)
 AC_SUBST(MEDIAPACKET_LIBS)
 
-PKG_CHECK_MODULES(MM_RESOURCE_MANAGER, mm-resource-manager)
-AC_SUBST(MM_RESOURCE_MANAGER_CFLAGS)
-AC_SUBST(MM_RESOURCE_MANAGER_LIBS)
+AC_ARG_ENABLE(rm-common, AC_HELP_STRING([--enable-rm-common], [enable rm common]),
+[
+  case "${enableval}" in
+    yes) RMC=yes ;;
+    no)  RMC=no ;;
+    *) AC_MSG_ERROR(bad value ${enableval} for --enable-rm-common) ;;
+  esac
+],[RMC=no])
+if test "x$RMC" = "xyes"; then
+
+PKG_CHECK_MODULES(RM, resource-manager)
+AC_SUBST(RM_CFLAGS)
+AC_SUBST(RM_LIBS)
+
+PKG_CHECK_MODULES(RC, resource-center-api)
+AC_SUBST(RC_CFLAGS)
+AC_SUBST(RC_LIBS)
+fi
+AM_CONDITIONAL([RMC], [test "x$RMC" = "xyes"])
 
 PKG_CHECK_MODULES(DLOG, dlog)
 AC_SUBST(DLOG_CFLAGS)
index c7424f0..db5a737 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    1.0.2
+Version:    1.1.0
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
@@ -22,8 +22,9 @@ BuildRequires:  pkgconfig(mmutil-common)
 BuildRequires:  pkgconfig(iniparser)
 BuildRequires:  pkgconfig(icu-i18n)
 BuildRequires:  pkgconfig(capi-media-tool)
-BuildRequires:  pkgconfig(mm-resource-manager)
 BuildRequires:  pkgconfig(capi-system-info)
+BuildRequires:  pkgconfig(resource-manager)
+BuildRequires:  pkgconfig(resource-center-api)
 BuildRequires:  pkgconfig(storage)
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(capi-media-sound-manager)
@@ -70,6 +71,7 @@ export LDFLAGS+=" -lgcov"
 %if "%{gtests}" == "1"
 --enable-tests \
 %endif
+--enable-rm-common \
 --disable-static
 
 #%__make -j1
index 68e3633..60ba3f4 100644 (file)
@@ -18,6 +18,10 @@ libmmfplayer_la_SOURCES = mm_player.c \
                          mm_player_ini.c \
                          mm_player_360.c
 
+#if RMC
+libmmfplayer_la_SOURCES += mm_player_rm.c
+#endif
+
 libmmfplayer_la_CFLAGS =  -I$(srcdir)/include \
                        $(MMCOMMON_CFLAGS) \
                        $(MMUTIL_COMMON_CFLAGS) \
@@ -25,7 +29,6 @@ libmmfplayer_la_CFLAGS =  -I$(srcdir)/include \
                        $(GST_VIDEO_CFLAGS) \
                        $(GST_APP_CFLAGS) \
                        $(MMSOUND_CFLAGS) \
-                       $(MM_RESOURCE_MANAGER_CFLAGS) \
                        $(ICU_CFLAGS) \
                        $(UTILX_CFLAGS) \
                        $(MEDIAPACKET_CFLAGS) \
@@ -35,8 +38,11 @@ libmmfplayer_la_CFLAGS =  -I$(srcdir)/include \
                        $(TZPLATFORM_CONFIG_CFLAGS) \
                        $(MEDIASOUNDMGR_CFLAGS) \
                        $(TBM_CFLAGS) \
-                       $(GST_ALLOCATORS_CFLAGS) \
+                       $(GST_ALLOCATORS_CFLAGS)
                        -Werror -Wno-deprecated -Wno-deprecated-declarations -Wno-cpp
+#if RMC
+libmmfplayer_la_CFLAGS += $(AUL_CFLAGS) $(RM_CFLAGS) $(RC_CFLAGS) $(RI_CFLAGS) -DRM_COMMON
+#endif
 
 noinst_HEADERS = include/mm_player_utils.h \
                 include/mm_player_ini.h \
@@ -46,9 +52,13 @@ noinst_HEADERS = include/mm_player_utils.h \
                 include/mm_player_tracks.h \
                 include/mm_player_streaming.h \
                 include/mm_player_es.h \
-                include/mm_player_gst.h \
+                include/mm_player_gst.h
                 include/mm_player_360.h
 
+#if RMC
+noinst_HEADERS += include/mm_player_rm.h
+#endif
+
 libmmfplayer_la_LIBADD = $(GST_LIBS) \
                $(MMCOMMON_LIBS) \
                $(GST_INTERFACE_LIBS) \
@@ -56,7 +66,6 @@ libmmfplayer_la_LIBADD = $(GST_LIBS) \
                $(GST_APP_LIBS) \
                $(INIPARSER_LIBS) \
                $(MMSOUND_LIBS) \
-               $(MM_RESOURCE_MANAGER_LIBS) \
                $(ICU_LIBS) \
                $(MEDIAPACKET_LIBS) \
                $(DLOG_LIBS) \
@@ -68,6 +77,10 @@ libmmfplayer_la_LIBADD = $(GST_LIBS) \
                $(GST_ALLOCATORS_LIBS) \
                $(MEDIASOUNDMGR_LIBS)
 
+#if RMC
+libmmfplayer_la_LIBADD += $(AUL_LIBS) $(RM_LIBS) $(RC_LIBS) $(RI_LIBS)
+#endif
+
 if IS_SDK
 libmmfplayer_la_CFLAGS += -DIS_SDK
 endif
index c5fbb44..52acdb5 100644 (file)
@@ -43,7 +43,9 @@
 #include "mm_player_audioeffect.h"
 #include "mm_message.h"
 #include "mm_player_ini.h"
-#include <mm_resource_manager.h>
+#ifdef RM_COMMON
+#include <rm_api.h>
+#endif /* RM_COMMON */
 #include "mm_player_streaming.h"
 #include "mm_player_attrs.h"
 
@@ -547,6 +549,16 @@ typedef struct {
        int  (*convert)(void *, int, void **);
 } mm_img_util_interface_t;
 
+#ifdef RM_COMMON
+typedef struct {
+       int handle;
+       rm_device_return_s devices[MMPLAYER_RESOURCE_TYPE_MAX];
+       rm_consumer_info rci;
+       GMutex control_lock;
+       GMutex callback_lock;
+} mm_resource_t;
+#endif
+
 typedef struct {
        /* STATE */
        int state;                                      // player current state
@@ -636,7 +648,7 @@ typedef struct {
        gulong video_capture_cb_probe_id;
 
        /* sound info */
-       mmplayer_sound_info_t   sound;
+       mmplayer_sound_info_t sound;
 
        /* type string */
        gchar *type_caps_str;
@@ -736,9 +748,10 @@ typedef struct {
 
        gboolean is_nv12_tiled;
 
-       /* resource manager for H/W resources */
-       mm_resource_manager_h resource_manager;
-       mm_resource_manager_res_h hw_resource[MMPLAYER_RESOURCE_TYPE_MAX];
+#ifdef RM_COMMON
+       mm_resource_t res;
+#endif
+
        gboolean interrupted_by_resource;
 
        gboolean is_subtitle_off;
@@ -756,7 +769,7 @@ typedef struct {
        gboolean sent_bos;
 
        gboolean play_subtitle;
-       gboolean is_subtitle_force_drop;        // set TRUE after bus_cb get EOS
+       gboolean is_subtitle_force_drop; // set TRUE after bus_cb get EOS
 
        /* adjust subtitle position store */
        gint64 adjust_subtitle_pos;
@@ -893,6 +906,7 @@ int _mmplayer_get_video_roi_area(MMHandleType hplayer, double *scale_x, double *
 int _mmplayer_audio_offload_is_activated(MMHandleType hplayer, bool *activated);
 int _mmplayer_is_audio_control_available(MMHandleType hplayer, mmplayer_audio_control_opt_e opt, bool *available);
 
+
 /* internal */
 void _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer);
 void _mmplayer_bus_watcher_remove(MMHandleType hplayer);
@@ -927,7 +941,8 @@ void _mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad, GstCaps *c
 gboolean _mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer data);
 void _mmplayer_pipeline_complete(GstElement *decodebin, gpointer data);
 void _mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps);
-int _mmplayer_acquire_hw_resource(mmplayer_t *player, mmplayer_resource_type_e type);
+void _mmplayer_execute_resource_release(mmplayer_t *player);
+
 
 #ifdef __cplusplus
        }
diff --git a/src/include/mm_player_rm.h b/src/include/mm_player_rm.h
new file mode 100644 (file)
index 0000000..5f1acd2
--- /dev/null
@@ -0,0 +1,37 @@
+/*\r
+ * libmm-player\r
+ *\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+#ifndef __MM_PLAYER_RM_H__\r
+#define __MM_PLAYER_RM_H__\r
+\r
+#include <mm_types.h>\r
+\r
+#ifdef RM_COMMON\r
+/*=======================================================================================\r
+| GLOBAL FUNCTION PROTOTYPES                                                           |\r
+========================================================================================*/\r
+\r
+int _mmplayer_rm_create(mmplayer_t *player);\r
+int _mmplayer_rm_allocate(mmplayer_t *player, mmplayer_resource_type_e type);\r
+int _mmplayer_rm_deallocate(mmplayer_t *player, mmplayer_resource_type_e type);\r
+int _mmplayer_rm_release(mmplayer_t *player);\r
+\r
+#endif\r
+#endif /*__MM_PLAYER_RM_H__*/\r
index 126f972..d675674 100644 (file)
@@ -67,7 +67,7 @@
 #define MMPLAYER_RECONFIGURE_LOCK(x_player)                  g_mutex_lock(&((mmplayer_t *)x_player)->reconfigure_lock)
 #define MMPLAYER_RECONFIGURE_UNLOCK(x_player)                g_mutex_unlock(&((mmplayer_t *)x_player)->reconfigure_lock)
 #define MMPLAYER_RECONFIGURE_WAIT(x_player)                  g_cond_wait(&((mmplayer_t *)x_player)->reconfigure_cond, &((mmplayer_t *)x_player)->reconfigure_lock)
-#define MMPLAYER_RECONFIGURE_SIGNAL(x_player)                g_cond_signal(&((mmplayer_t *)x_player)->reconfigure_cond);
+#define MMPLAYER_RECONFIGURE_SIGNAL(x_player)                g_cond_signal(&((mmplayer_t *)x_player)->reconfigure_cond)
 
 /* capture thread */
 #define MMPLAYER_CAPTURE_THREAD_LOCK(x_player)               g_mutex_lock(&((mmplayer_t *)x_player)->capture_thread_mutex)
                        return MM_ERROR_PLAYER_DOING_SEEK; \
                default: \
                        break; \
-               }       \
+               } \
        } while (0)
 
 /* setting element state */
 
 /* create element */
 #define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_bucket, x_player) \
-       do {\
+       do { \
                x_bin[x_id].id = x_id;\
                x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
                if (!x_bin[x_id].gst) {\
-                       LOGE("failed to create %s", x_factory);\
-                       goto ERROR;\
-               } else {\
-                       if (x_player->ini.set_dump_element_flag)\
-                               __mmplayer_add_dump_buffer_probe(x_player, x_bin[x_id].gst);\
+                       LOGE("failed to create %s", x_factory); \
+                       goto ERROR; \
+               } else { \
+                       if (x_player->ini.set_dump_element_flag) \
+                               __mmplayer_add_dump_buffer_probe(x_player, x_bin[x_id].gst); \
                } \
                x_bucket = g_list_append(x_bucket, &x_bin[x_id]);\
        } while (0);
index e28f71b..6015a8a 100644 (file)
@@ -406,7 +406,7 @@ int _mmplayer_set_attribute(MMHandleType handle, char **err_attr_name, const cha
        return MM_ERROR_NONE;
 }
 
-int _mmplayer_get_attributes_info(MMHandleType handle,  const char *attribute_name, mmplayer_attrs_info_t *dst_info)
+int _mmplayer_get_attributes_info(MMHandleType handle, const char *attribute_name, mmplayer_attrs_info_t *dst_info)
 {
        int result = MM_ERROR_NONE;
        MMHandleType attrs = NULL;
index 234170c..f74b031 100644 (file)
@@ -34,6 +34,7 @@
 #include "mm_player_attrs.h"
 #include "mm_player_utils.h"
 #include "mm_player_tracks.h"
+#include "mm_player_rm.h"
 
 /*===========================================================================================
 |                                                                                                                                                                                      |
@@ -3026,16 +3027,13 @@ __mmplayer_gst_decode_request_resource(GstElement * uridecodebin, GstStreamColle
 
        /* public does not support audio hw decoder at the moment */
 
-       if (player->hw_resource[MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER] != NULL) {
-               LOGW("video decoder resource is already acquired, skip it.");
-               return TRUE;
-       }
-
-       if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+#ifdef RM_COMMON
+       if (_mmplayer_rm_allocate(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
                LOGE("failed to acquire video decoder resource");
                return FALSE;
        }
-       player->interrupted_by_resource = FALSE;
+#endif
+
        MMPLAYER_FLEAVE();
        return TRUE;
 }
index 2481186..9b0ebf7 100644 (file)
 #include <sound_manager.h>
 #include <gst/allocators/gsttizenmemory.h>
 #include <tbm_surface_internal.h>
+#ifdef RM_COMMON
+#include <resource_center.h>
+#include "mm_player_rm.h"
+#endif
 
 /*===========================================================================================
 |                                                                                                                                                                                      |
@@ -318,7 +322,6 @@ void
 _mmplayer_set_state(mmplayer_t *player, int state)
 {
        MMMessageParamType msg = {0, };
-
        MMPLAYER_RETURN_IF_FAIL(player);
 
        if (MMPLAYER_CURRENT_STATE(player) == state) {
@@ -368,7 +371,6 @@ _mmplayer_set_state(mmplayer_t *player, int state)
                        MMPLAYER_POST_MSG(player, MM_MESSAGE_STATE_INTERRUPTED, &msg);
                else /* state changed by usecase */
                        MMPLAYER_POST_MSG(player, MM_MESSAGE_STATE_CHANGED, &msg);
-
        } else {
                LOGD("intermediate state, do nothing.");
                MMPLAYER_PRINT_STATE(player);
@@ -553,111 +555,6 @@ ALREADY_GOING:
        return MM_ERROR_PLAYER_NO_OP;
 }
 
-int _mmplayer_acquire_hw_resource(mmplayer_t *player, mmplayer_resource_type_e type)
-{
-       int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-       mm_resource_manager_res_type_e rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
-
-       switch (type) {
-               case MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER:
-                       rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER;
-                       break;
-               case MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY:
-                       rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY;
-                       break;
-               case MMPLAYER_RESOURCE_TYPE_AUDIO_OFFLOAD:
-                       rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_AUDIO_OFFLOAD;
-                       break;
-               default:
-                       LOGE("invalid mmplayer resource type %d", type);
-                       return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       if (player->hw_resource[type] != NULL) {
-               LOGD("[%d type] resource was already acquired", type);
-               return MM_ERROR_NONE;
-       }
-
-       LOGD("mark for acquire [%d type] resource", type);
-       rm_ret = mm_resource_manager_mark_for_acquire(player->resource_manager,
-                       rm_res_type, MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &player->hw_resource[type]);
-       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGE("failed to mark resource for acquire, ret(0x%x)", rm_ret);
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       LOGD("commit [%d type] resource", type);
-       rm_ret = mm_resource_manager_commit(player->resource_manager);
-       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGE("failed to commit of resource, ret(0x%x)", rm_ret);
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
-}
-
-static void __mmplayer_destroy_hw_resource(mmplayer_t *player)
-{
-       int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-
-       MMPLAYER_RETURN_IF_FAIL(player);
-       MMPLAYER_RETURN_IF_FAIL(player->resource_manager);
-
-       rm_ret = mm_resource_manager_mark_all_for_release(player->resource_manager);
-       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGW("failed to mark all for release of resource, ret(0x%x)", rm_ret);
-               goto rm_destroy;
-       }
-
-       rm_ret = mm_resource_manager_commit(player->resource_manager);
-       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE)
-               LOGW("failed to commit resource, ret(0x%x)", rm_ret);
-
-rm_destroy:
-       /* de-initialize resource manager */
-       rm_ret = mm_resource_manager_destroy(player->resource_manager);
-       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGW("failed to destroy resource manager, ret(0x%x)", rm_ret);
-               return;
-       }
-
-       player->resource_manager = NULL;
-
-       LOGD("resource manager is destroyed");
-}
-
-static int __mmplayer_release_hw_resource(mmplayer_t *player, mmplayer_resource_type_e type)
-{
-       int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-
-       MMPLAYER_FENTER();
-
-       if (player->hw_resource[type] == NULL) {
-               LOGD("there is no acquired [%d type] resource", type);
-               return MM_ERROR_NONE;
-       }
-
-       LOGD("mark for release [%d type] resource", type);
-       rm_ret = mm_resource_manager_mark_for_release(player->resource_manager, player->hw_resource[type]);
-       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGE("failed to mark resource for release, ret(0x%x)", rm_ret);
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       player->hw_resource[type] = NULL;
-
-       LOGD("commit [%d type] resource", type);
-       rm_ret = mm_resource_manager_commit(player->resource_manager);
-       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGE("failed to commit resource, ret(0x%x)", rm_ret);
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
-}
-
 static void
 __mmplayer_initialize_gapless_play(mmplayer_t *player)
 {
@@ -708,7 +605,14 @@ __mmplayer_initialize_gapless_play(mmplayer_t *player)
                player->audio_decoders = NULL;
        }
 
-       __mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER);
+#ifdef RM_COMMON
+       if (_mmplayer_rm_deallocate(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+               LOGE("[DECODER] _mmplayer_rm_deallocate failed [res handle %d]", player->res.handle);
+               return;
+       }
+
+       player->interrupted_by_resource = FALSE;
+#endif
 
        MMPLAYER_FLEAVE();
 }
@@ -1781,7 +1685,6 @@ __mmplayer_gst_create_sink_bin(GstElement *elem, GstPad *pad, GstCaps *ref_caps,
        gboolean reusing = FALSE;
        gboolean caps_ret = TRUE;
        gchar *sink_pad_name = "sink";
-
        /* check handles */
        player = (mmplayer_t *)data;
 
@@ -1833,13 +1736,13 @@ __mmplayer_gst_create_sink_bin(GstElement *elem, GstPad *pad, GstCaps *ref_caps,
                        mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
                        LOGD("display_surface_type (%d)", surface_type);
 
+#ifdef RM_COMMON
                        if ((surface_type == MM_DISPLAY_SURFACE_OVERLAY || surface_type == MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI) &&
-                               (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE)) {
+                               (_mmplayer_rm_allocate(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE)) {
                                LOGE("failed to acquire video overlay resource");
                                goto ERROR;
                        }
-
-                       player->interrupted_by_resource = FALSE;
+#endif
 
                        if (__mmplayer_gst_create_video_sink_bin(player, caps, surface_type) != MM_ERROR_NONE) {
                                LOGE("failed to create videobin. continuing without video");
@@ -2097,8 +2000,8 @@ static void __mmplayer_video_param_set_video_roi_area(mmplayer_t *player)
        MMPLAYER_RETURN_IF_FAIL(handle);
 
        gst_video_overlay_set_video_roi_area(
-                GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                player->video_roi.scale_x, player->video_roi.scale_y, player->video_roi.scale_width, player->video_roi.scale_height);
+               GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+               player->video_roi.scale_x, player->video_roi.scale_y, player->video_roi.scale_width, player->video_roi.scale_height);
        LOGD("set video param : video roi area scale value: x(%f) y(%f) width(%f) height(%f)",
                player->video_roi.scale_x, player->video_roi.scale_y, player->video_roi.scale_width, player->video_roi.scale_height);
 }
@@ -2133,8 +2036,8 @@ static void __mmplayer_video_param_set_roi_area(mmplayer_t *player)
 
        /* After setting window handle, set display roi area */
        gst_video_overlay_set_display_roi_area(
-                GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                win_roi_x, win_roi_y, win_roi_width, win_roi_height);
+               GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+               win_roi_x, win_roi_y, win_roi_width, win_roi_height);
        LOGD("set video param : roi area : x(%d) y(%d) width(%d) height(%d)",
                win_roi_x, win_roi_y, win_roi_width, win_roi_height);
 }
@@ -2262,17 +2165,22 @@ static int __mmplayer_set_disable_overlay_option(mmplayer_t *player, bool disabl
                LOGE("disable overlay");
                g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", TRUE, NULL);
 
+#ifdef RM_COMMON
                /* release overlay resource */
-               if (__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
-                       LOGE("failed to release overlay resource");
-                       return MM_ERROR_PLAYER_INTERNAL;
+               if (_mmplayer_rm_deallocate(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
+                       LOGE("[OVERLAY] _mmplayer_rm_deallocate failed [res handle %d]", player->res.handle);
+                       return MM_ERROR_RESOURCE_INTERNAL;
                }
+
+               player->interrupted_by_resource = FALSE;
+#endif
        } else {
-               if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
+#ifdef RM_COMMON
+               if (_mmplayer_rm_allocate(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
                        LOGE("failed to acquire video overlay resource");
                        return MM_ERROR_PLAYER_INTERNAL;
                }
-               player->interrupted_by_resource = FALSE;
+#endif
 
                LOGD("enable overlay");
                __mmplayer_video_param_set_display_overlay(player);
@@ -2308,10 +2216,15 @@ _mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
                __mmplayer_switch_stream(player, MM_PLAYER_TRACK_TYPE_VIDEO, INVALID_TRACK_INDEX);
 
                /* release decoder resource */
-               if (__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
-                       LOGE("failed to release video decoder resources");
-                       return MM_ERROR_PLAYER_INTERNAL;
+#ifdef RM_COMMON
+               if (_mmplayer_rm_deallocate(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+                       LOGE("[DECODER] _mmplayer_rm_deallocate failed %d", player->res.handle);
+                       return MM_ERROR_RESOURCE_INTERNAL;
                }
+
+               player->interrupted_by_resource = FALSE;
+#endif
+
                player->can_support_codec &= ~FOUND_PLUGIN_VIDEO;
        } else {
                __mmplayer_switch_stream(player, MM_PLAYER_TRACK_TYPE_VIDEO, DEFAULT_TRACK_INDEX);
@@ -3635,7 +3548,7 @@ __mmplayer_gst_create_video_filters(mmplayer_t *player, MMDisplaySurfaceType sur
        if ((surface_type != MM_DISPLAY_SURFACE_OVERLAY &&
                surface_type != MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI) ||
                player->set_mode.video_zc) {
-               LOGD("skip creating the videoconv and rotator");
+               LOGD("[surface type %d] skip creating the videoconv and rotator", surface_type);
                return MM_ERROR_NONE;
        }
 
@@ -4684,28 +4597,10 @@ _mmplayer_parse_profile(const char *uri, void *param, mmplayer_parse_profile_t *
        return ret;
 }
 
-static int
-__resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
-               void *user_data)
+void _mmplayer_execute_resource_release(mmplayer_t *player)
 {
-       mmplayer_t *player = NULL;
-       MMMessageParamType msg = {0, };
        gint64 pos = 0;
-       mmplayer_resource_type_e res_idx = MMPLAYER_RESOURCE_TYPE_MAX;
-
-       MMPLAYER_FENTER();
-
-       if (!user_data) {
-               LOGE("user_data is null");
-               return TRUE;
-       }
-
-       player = (mmplayer_t *)user_data;
-
-       if (!player->pipeline || !player->attrs) {
-               LOGW("not initialized");
-               return TRUE;
-       }
+       MMMessageParamType msg = {0,};
 
        LOGD("cmd lock player, cmd state : %d", player->cmd);
        MMPLAYER_CMD_LOCK(player);
@@ -4715,7 +4610,7 @@ __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
                || MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_NONE) {
                LOGW("player already destroyed");
                MMPLAYER_CMD_UNLOCK(player);
-               return TRUE;
+               return;
        }
 
        player->interrupted_by_resource = TRUE;
@@ -4736,13 +4631,6 @@ __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
                LOGE("failed to unrealize");
 
        MMPLAYER_CMD_UNLOCK(player);
-
-       for (res_idx = MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MMPLAYER_RESOURCE_TYPE_MAX; res_idx++) {
-               player->hw_resource[res_idx] = NULL;
-       }
-
-       MMPLAYER_FLEAVE();
-       return TRUE; /* release all the resources */
 }
 
 static void
@@ -4826,15 +4714,6 @@ _mmplayer_create_player(MMHandleType handle)
                /* do not handle as error for headless profile */
        }
 
-       /* initialize resource manager */
-       if (mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
-               __resource_release_cb, player, &player->resource_manager)
-               != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGE("failed to create resource manager");
-               ret = MM_ERROR_PLAYER_INTERNAL;
-               goto ERROR;
-       }
-
        /* create video bo lock and cond */
        g_mutex_init(&player->video_bo_mutex);
        g_cond_init(&player->video_bo_cond);
@@ -5115,7 +4994,10 @@ _mmplayer_destroy(MMHandleType handle)
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       __mmplayer_destroy_hw_resource(player);
+#ifdef RM_COMMON
+       if (_mmplayer_rm_release(player) != MM_ERROR_NONE)
+               LOGE("_mmplayer_rm_release is failed");
+#endif
 
        g_queue_free(player->bus_msg_q);
 
@@ -5169,6 +5051,14 @@ _mmplayer_realize(MMHandleType hplayer)
        /* check current state */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_REALIZE);
 
+#ifdef RM_COMMON
+       ret = _mmplayer_rm_create(player);
+       if (ret != MM_ERROR_NONE) {
+               LOGE("Resource create failed, ret : 0x%x", ret);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+#endif
+
        attrs = MMPLAYER_GET_ATTRS(player);
        if (!attrs) {
                LOGE("fail to get attributes.");
@@ -5284,12 +5174,15 @@ _mmplayer_unrealize(MMHandleType hplayer)
        ret = __mmplayer_gst_unrealize(player);
 
        for (res_idx = MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MMPLAYER_RESOURCE_TYPE_MAX; res_idx++) {
-               rm_ret = __mmplayer_release_hw_resource(player, res_idx);
-               if (rm_ret != MM_ERROR_NONE)
-                       LOGE("failed to release [%d] resources", res_idx);
-       }
+#ifdef RM_COMMON
+               if (_mmplayer_rm_deallocate(player, res_idx) != MM_ERROR_NONE) {
+                       LOGE("[%d] _mmplayer_rm_deallocate failed [res handle %d]", res_idx, player->res.handle);
+                       return MM_ERROR_RESOURCE_INTERNAL;
+               }
 
-       player->interrupted_by_resource = FALSE;
+               player->interrupted_by_resource = FALSE;
+#endif
+       }
 
        MMPLAYER_FLEAVE();
        return ret;
@@ -7265,11 +7158,13 @@ __mmplayer_can_build_audio_offload_path(mmplayer_t *player)
        }
        gst_object_unref(factory);
 
-       if (_mmplayer_acquire_hw_resource(player,
+#ifdef RM_COMMON
+       if (_mmplayer_rm_allocate(player,
                        MMPLAYER_RESOURCE_TYPE_AUDIO_OFFLOAD) != MM_ERROR_NONE) {
                LOGE("failed to acquire audio offload decoder resource");
                goto DONE;
        }
+#endif
 
        if (!__mmplayer_add_audio_device_connected_cb(player))
                goto DONE;
@@ -7281,8 +7176,16 @@ __mmplayer_can_build_audio_offload_path(mmplayer_t *player)
        ret = TRUE;
 
 DONE:
-       if (!ret)
-               __mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_AUDIO_OFFLOAD);
+       if (!ret) {
+#ifdef RM_COMMON
+               if (_mmplayer_rm_deallocate(player, MMPLAYER_RESOURCE_TYPE_AUDIO_OFFLOAD) != MM_ERROR_NONE) {
+                       LOGE("[AUDIO_OFFLOAD] _mmplayer_rm_deallocate failed %d", player->res.handle);
+                       return MM_ERROR_RESOURCE_INTERNAL;
+               }
+
+               player->interrupted_by_resource = FALSE;
+#endif
+       }
 
        MMPLAYER_FLEAVE();
        return ret;
@@ -7327,19 +7230,13 @@ __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps
                if ((strlen(player->ini.videocodec_element_hw) > 0) &&
                        (g_strrstr(factory_name, player->ini.videocodec_element_hw))) {
 
-                       /* mark video decoder for acquire */
-                       if (player->hw_resource[MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER] != NULL) {
-                               LOGW("video decoder resource is already acquired, skip it.");
-                               ret = GST_AUTOPLUG_SELECT_SKIP;
-                               goto DONE;
-                       }
-
-                       if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+#ifdef RM_COMMON
+                       if (_mmplayer_rm_allocate(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
                                LOGE("failed to acquire video decoder resource");
                                ret = GST_AUTOPLUG_SELECT_SKIP;
                                goto DONE;
                        }
-                       player->interrupted_by_resource = FALSE;
+#endif
                }
 
                /* update codec info */
@@ -7362,13 +7259,13 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
        GValueArray *new_factories = NULL;
        GValue val = { 0, };
        GstElementFactory *factory = NULL;
+       guint new_pos = DEFAULT_IDX;
+       guint rm_pos = DEFAULT_IDX;
        const gchar *klass = NULL;
        gchar *factory_name = NULL;
        guint hw_dec_idx = DEFAULT_IDX;
        guint first_sw_dec_idx = DEFAULT_IDX;
        guint last_sw_dec_idx = DEFAULT_IDX;
-       guint new_pos = DEFAULT_IDX;
-       guint rm_pos = DEFAULT_IDX;
        int audio_codec_type;
        int video_codec_type;
        mmplayer_codec_type_e codec_type = MM_PLAYER_CODEC_TYPE_DEFAULT;
@@ -7382,10 +7279,10 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
 #ifdef __DEBUG__
        LOGD("num of factory : %d, codec type %d, %d", factories->n_values, video_codec_type, audio_codec_type);
 #endif
+
        for (int i = 0 ; i < factories->n_values ; i++) {
                gchar *hw_dec_info = NULL;
                gchar (*sw_dec_info)[PLAYER_INI_MAX_STRLEN] = {NULL, };
-
                factory = g_value_get_object(g_value_array_get_nth(factories, i));
                if (!factory) {
                        LOGW("failed to get factory object");
@@ -7393,7 +7290,6 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
                }
                klass = gst_element_factory_get_klass(factory);
                factory_name = GST_OBJECT_NAME(factory);
-
 #ifdef __DEBUG__
                LOGD("Klass [%s] Factory [%s]", klass, factory_name);
 #endif
@@ -7421,7 +7317,7 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
                        hw_dec_idx = i;
                } else {
                        for (int j = 0; sw_dec_info[j][0] != '\0'; j++) {
-                               if (strstr(factory_name, sw_dec_info[j])) {
+                               if (factory_name && strstr(factory_name, sw_dec_info[j])) {
                                        last_sw_dec_idx = i;
                                        if (first_sw_dec_idx == DEFAULT_IDX) {
                                                first_sw_dec_idx = i;
@@ -7429,8 +7325,10 @@ _mmplayer_gst_decode_autoplug_sort(GstElement *bin,
                                }
                        }
 
-                       if (first_sw_dec_idx == DEFAULT_IDX)
-                               LOGW("unknown codec %s", factory_name);
+                       if (first_sw_dec_idx == DEFAULT_IDX) {
+                               if (factory_name)
+                                       LOGW("unknown codec %s", factory_name);
+                       }
                }
        }
 
@@ -7666,9 +7564,14 @@ _mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *pad,
        mainbin[MMPLAYER_M_V_CONCAT].id = 0;
        MMPLAYER_FREEIF(player->pipeline->videobin);
 
-       ret = __mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY);
-       if (ret != MM_ERROR_NONE)
-               LOGE("failed to release overlay resources");
+#ifdef RM_COMMON
+               if (_mmplayer_rm_deallocate(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
+                       LOGE("[OVERLAY] _mmplayer_rm_deallocate failed %d", player->res.handle);
+                       return;
+               }
+
+               player->interrupted_by_resource = FALSE;
+#endif
 
        player->videodec_linked = 0;
 
diff --git a/src/mm_player_rm.c b/src/mm_player_rm.c
new file mode 100644 (file)
index 0000000..3574e55
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ /*=======================================================================================
+|  INCLUDE FILES                                                                       |
+========================================================================================*/
+#ifdef RM_COMMON
+#include <rm_api.h>
+#include <rm_type.h>
+#include <resource_center.h>
+#include "mm_player_utils.h"
+#include "mm_player_gst.h"
+#include "mm_player_rm.h"
+#include <mm_error.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#define LOG_TAG "MM_PLAYER_RM"
+#endif
+
+#define STR_LEN_MAX 128
+
+static int
+__mmplayer_get_appid_by_pid(int pid, char *name, size_t size)
+{
+       g_autofree gchar *cmdline = NULL;
+       g_autofree gchar *contents = NULL;
+       g_autofree gchar *base = NULL;
+       g_autoptr(GError) error = NULL;
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(name, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(size != 0, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       cmdline = g_strdup_printf("/proc/%d/cmdline", (int)pid);
+
+       if (!g_file_get_contents(cmdline, &contents, NULL, &error)) {
+               LOGE("error : %s", error->message);
+               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+       }
+
+       base = g_path_get_basename(contents);
+
+       if (g_strlcpy(name, base, size) >= size)
+               LOGE("string truncated");
+
+       return MM_ERROR_NONE;
+}
+
+static rm_cb_result
+__mmplayer_rm_callback(int handle, rm_callback_type event_src, rm_device_request_s *info, void *cb_data)
+{
+       mmplayer_t *player = MM_PLAYER_CAST(cb_data);
+       g_autoptr(GMutexLocker) locker = NULL;
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       LOGI("rm callback info mm_player_t [%p] handle : %d event_src : %d", player, handle, event_src);
+
+       locker = g_mutex_locker_new(&player->res.callback_lock);
+
+       switch (event_src) {
+       case RM_CALLBACK_TYPE_RESOURCE_CONFLICT:
+       case RM_CALLBACK_TYPE_RESOURCE_CONFLICT_UD:
+               _mmplayer_execute_resource_release(player);
+               break;
+       default:
+               break;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       LOGI("RM_CB_RESULT_OK");
+       return RM_CB_RESULT_OK;
+}
+
+int _mmplayer_rm_create(mmplayer_t *player)
+{
+       int ret;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if (player->res.handle) {
+               LOGI("[%d] resource manager handle is already registered", player->res.handle);
+               return MM_ERROR_NONE;
+       }
+
+       g_mutex_init(&player->res.control_lock);
+       g_mutex_init(&player->res.callback_lock);
+
+       memset(&player->res.rci, 0x00, sizeof(rm_consumer_info));
+
+       player->res.rci.app_pid = player->client_pid;
+
+       if (__mmplayer_get_appid_by_pid(player->res.rci.app_pid, player->res.rci.app_id, sizeof(player->res.rci.app_id)) != MM_ERROR_NONE) {
+               LOGE("__mmplayer_get_appid_by_pid is failed");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       LOGI("app pid %d app id %s", player->res.rci.app_pid, player->res.rci.app_id);
+
+       ret = rm_register((rm_resource_cb)__mmplayer_rm_callback,
+                                               (void *)player,
+                                               &(player->res.handle),
+                                               (player->res.rci.app_id[0] != '\0') ? &player->res.rci : NULL);
+       if (ret != RM_OK) {
+               LOGE("rm_register fail %d", ret);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+int _mmplayer_rm_allocate(mmplayer_t *player, mmplayer_resource_type_e type)
+{
+       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;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       locker = g_mutex_locker_new(&player->res.control_lock);
+
+       LOGI("app id : %s type %d", player->res.rci.app_id, type);
+       memset(&request_resources, 0x0, sizeof(rm_category_request_s));
+
+       device = &player->res.devices[type];
+       memset(device, 0x0, sizeof(rm_device_return_s));
+
+       switch (type) {
+       case MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER:
+               state = RM_STATE_EXCLUSIVE;
+               category_id = RM_CATEGORY_VIDEO_DECODER;
+               break;
+       case MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY:
+               state = RM_STATE_EXCLUSIVE;
+               category_id = RM_CATEGORY_SCALER;
+               break;
+       case MMPLAYER_RESOURCE_TYPE_AUDIO_OFFLOAD:
+               state = RM_STATE_EXCLUSIVE;
+               category_id = RM_CATEGORY_AUDIO_OFFLOAD;
+               break;
+       default:
+               LOGE("category id can't set");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       category_option = rc_get_capable_category_id(player->res.handle, player->res.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;
+       LOGI("state %d category id 0x%x category option %d", state, category_id, category_option);
+
+       ret = rm_allocate_resources(player->res.handle, &request_resources, device);
+       if (ret != RM_OK) {
+               LOGW("Resource allocation request failed ret %d [error type %d]", ret, device->error_type);
+               MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       for (idx = 0; idx < device->allocated_num; idx++)
+               LOGI("#%d / %d [%p] device %d %s %s", idx, device->allocated_num, device,
+                       device->device_id[idx], device->device_node[idx],
+                       device->device_name[idx]);
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+int _mmplayer_rm_deallocate(mmplayer_t *player, mmplayer_resource_type_e type)
+{
+       int rm_ret = RM_OK;
+       int idx = 0;
+       rm_device_request_s requested;
+       rm_device_return_s *devices;
+       g_autoptr(GMutexLocker) locker = NULL;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player->res.handle, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       locker = g_mutex_locker_new(&player->res.control_lock);
+
+       devices = &player->res.devices[type];
+
+       LOGI("[%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];
+                       LOGI("[device id %d] [device name %s]", devices->device_id[idx], devices->device_name[idx]);
+               }
+
+               rm_ret = rm_deallocate_resources(player->res.handle, &requested);
+               if (rm_ret != RM_OK) {
+                       LOGE("Resource deallocation request failed [%d] [request num %d]", rm_ret, requested.request_num);
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+       }
+
+       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;
+               }
+       }
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+int _mmplayer_rm_release(mmplayer_t *player)
+{
+       int ret;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       if (!player->res.handle) {
+               LOGI("resource manager handle is not registered");
+               return MM_ERROR_NONE;
+       }
+
+       ret = rm_unregister(player->res.handle);
+       if (ret != RM_OK) {
+               LOGE("rm_unregister fail %d", ret);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       g_mutex_clear(&player->res.control_lock);
+       g_mutex_clear(&player->res.callback_lock);
+
+       LOGD("rm_unregister[%d]", ret);
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+#endif /* RM_COMMON */
+