AC_SUBST(CAPI_SYSTEM_INFO_CFLAGS)
AC_SUBST(CAPI_SYSTEM_INFO_LIBS)
-PKG_CHECK_MODULES(MM_RESOURCE_MANAGER, mm-resource-manager)
-AC_SUBST(MM_RESOURCE_MANAGER_CFLAGS)
-AC_SUBST(MM_RESOURCE_MANAGER_LIBS)
+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)
PKG_CHECK_MODULES(MM_DISPLAY_INTERFACE, mm-display-interface)
AC_SUBST(MM_DISPLAY_INTERFACE_CFLAGS)
Name: libmm-wfd
Summary: Multimedia Framework Wifi-Display Library
-Version: 0.3.13
+Version: 0.4.1
Release: 0
Group: System/Libraries
License: Apache-2.0
BuildRequires: pkgconfig(libtbm)
BuildRequires: pkgconfig(libtzplatform-config)
BuildRequires: pkgconfig(capi-system-info)
-BuildRequires: pkgconfig(mm-resource-manager)
+BuildRequires: pkgconfig(resource-manager)
+BuildRequires: pkgconfig(resource-center-api)
BuildRequires: pkgconfig(mm-display-interface)
%if 0%{?gtests:1}
BuildRequires: pkgconfig(gmock)
mm_wfd_sink_manager.c \
mm_wfd_sink_config.c \
mm_wfd_sink_priv.c \
- mm_wfd_sink_wayland.c
+ mm_wfd_sink_wayland.c \
+ mm_wfd_sink_rm.c
libmmfwfdsink_la_CFLAGS = -I$(srcdir)/include \
$(GST_VIDEO_CFLAGS) \
$(TZPLATFORM_CONFIG_CFLAGS) \
$(CAPI_SYSTEM_INFO_CFLAGS) \
- $(MM_RESOURCE_MANAGER_CFLAGS) \
+ $(RM_CFLAGS) \
+ $(RC_CFLAGS) \
$(MM_DISPLAY_INTERFACE_CFLAGS)
libmmfwfdsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = include/mm_wfd_sink_manager.h \
- include/mm_wfd_sink_wayland.h
+ include/mm_wfd_sink_wayland.h \
+ include/mm_wfd_sink_rm.h
libmmfwfdsink_la_LIBADD = $(GST_LIBS) \
$(GST_PLUGINS_BASE_LIBS) \
$(TZPLATFORM_CONFIG_LIBS) \
$(CAPI_SYSTEM_INFO_LIBS) \
$(GST_VIDEO_LIBS) \
- $(MM_RESOURCE_MANAGER_LIBS) \
+ $(RM_LIBS) \
+ $(RC_LIBS) \
$(MM_DISPLAY_INTERFACE_LIBS)
libmmfwfdsink_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x02000000 -DMMF_DEBUG_PREFIX=\"MMF-WFD-SINK\"
#include <mm_message.h>
#include <mm_error.h>
#include <mm_types.h>
-#include <mm_resource_manager.h>
+#include <rm_api.h>
+#include <rm_type.h>
+#include <resource_center.h>
#include <mm_display_interface.h>
#include "mm_wfd_sink_ini.h"
#include "mm_wfd_sink_attrs.h"
MMWFDSinkVideoStreamInfo video_stream_info;
} MMWFDSinkStreamInfo;
-
typedef struct {
gint id;
GstElement *gst;
int(*unprepare)(MMHandleType wfd_sink);
} MMWFDSinkPrivateFunc;
+/* priv func */
+typedef struct {
+ int handle;
+ rm_device_return_s devices[MM_WFD_SINK_RESOURCE_TYPE_MAX];
+ rm_consumer_info rci;
+ gboolean need_to_acquire[MM_WFD_SINK_RESOURCE_TYPE_MAX];
+ GMutex callback_lock;
+ GMutex control_lock;
+ gboolean interrupted_by_resource;
+} MMWFDSinkResource;
+
+
#define MMWFDSINK_CAST(x_wfd) ((mm_wfd_sink_t *)(x_wfd))
#define MMWFDSINK_GET_ATTRS(x_wfd) ((x_wfd) ? ((mm_wfd_sink_t*)x_wfd)->attrs : (MMHandleType)NULL)
gchar *coupled_sink_address;
gboolean is_coupled_sink_supported;
- /* resource manager for H/W resources */
- mm_resource_manager_h resource_manager;
- mm_resource_manager_res_h hw_resource[MM_WFD_SINK_RESOURCE_TYPE_MAX];
- gboolean interrupted_by_resource;
+ MMWFDSinkResource res;
int display_surface_id;
} mm_wfd_sink_t;
--- /dev/null
+/*
+ * libmm-wfd
+ *
+ * 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.
+ *
+ */
+
+#ifndef _MM_WFD_SINK_RM_H_
+#define _MM_WFD_SINK_RM_H_
+
+#include "mm_wfd_sink_priv.h"
+
+int mm_wfd_sink_rm_create(mm_wfd_sink_t *wfd_sink);
+int mm_wfd_sink_rm_allocate(mm_wfd_sink_t *wfd_sink, MMWFDSinkResourceType type);
+int mm_wfd_sink_rm_deallocate(mm_wfd_sink_t *wfd_sink, MMWFDSinkResourceType type);
+int mm_wfd_sink_rm_release(mm_wfd_sink_t *wfd_sink);
+
+#endif
#include <mm_types.h>
#include "mm_wfd_sink_dlog.h"
+#define MMWFDSINK_RET_FAIL(expr) \
+ do { \
+ if (!(expr)) { \
+ LOGE("failed [%s]", #expr); \
+ return; \
+ } \
+ } while (0)
+
+#define MMWFDSINK_RET_VAL_FAIL(expr, val) \
+ do { \
+ if (!(expr)) { \
+ LOGE("failed [%s]", #expr); \
+ return (val); \
+ } \
+ } while (0)
+
+
#define MMWFDSINK_FREEIF(x) \
do {\
if ((x)) \
mm_attrs_set_valid_range(attrs, idx,
wfd_attrs[idx].value_min,
wfd_attrs[idx].value_max,
- (int)wfd_attrs[idx].default_value);
+ GPOINTER_TO_INT(wfd_attrs[idx].default_value));
}
break;
/* macro */
#define MM_WFD_SINK_INI_GET_STRING(x_dict, x_item, x_ini, x_default) \
do { \
- gchar *str = NULL; \
+ const gchar *str = NULL; \
gint length = 0; \
\
str = iniparser_getstring(x_dict, x_ini, (char *)x_default); \
#include "mm_wfd_sink_enum.h"
#include "mm_wfd_sink_wayland.h"
#include "mm_wfd_sink_config.h"
+#include "mm_wfd_sink_rm.h"
#define PRINT_WFD_REF_COUNT(wfd_sink)\
do {\
/* util */
static void __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink);
-static int
-__resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
- void *user_data)
-{
- mm_wfd_sink_t *wfdsink = NULL;
- MMWFDSinkResourceType res_idx = MM_WFD_SINK_RESOURCE_TYPE_MAX;
-
- wfd_sink_debug_fenter();
-
- if (!user_data) {
- wfd_sink_error("user_data is null");
- return FALSE;
- }
-
- wfdsink = (mm_wfd_sink_t *)user_data;
-
- wfdsink->interrupted_by_resource = TRUE;
-
- wfd_sink_debug("resource is interrupted. resource would be released after destroying");
-
- MMWFDSINK_CMD_LOCK(wfdsink);
- if (_mm_wfd_sink_disconnect(wfdsink) != MM_ERROR_NONE)
- wfd_sink_error("failed to disconnect");
-
- if (_mm_wfd_sink_unprepare(wfdsink) != MM_ERROR_NONE)
- wfd_sink_error("failed to unprepare");
- for (res_idx = MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MM_WFD_SINK_RESOURCE_TYPE_MAX; res_idx++) {
- wfdsink->hw_resource[res_idx] = NULL;
- }
- MMWFDSINK_CMD_UNLOCK(wfdsink);
-
- wfd_sink_debug_fleave();
- return TRUE; /* release all the resources */
-}
-
-static int __mm_wfd_sink_acquire_hw_resource (mm_wfd_sink_t* wfd_sink, MMWFDSinkResourceType type)
-{
- int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-
- wfd_sink_debug_fenter();
-
- mm_resource_manager_res_type_e rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
-
- switch (type) {
- case MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER:
- rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER;
- break;
- case MM_WFD_SINK_RESOURCE_TYPE_VIDEO_OVERLAY:
- rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY;
- break;
- default:
- wfd_sink_error("invalid wfd sink resource type %d", type);
- return MM_ERROR_WFD_INTERNAL;
- }
-
- if (wfd_sink->hw_resource[type] != NULL) {
- wfd_sink_debug("[%d type] resource was already acquired", type);
- return MM_ERROR_NONE;
- }
-
- wfd_sink_debug("mark for acquire [%d type] resource", type);
- rm_ret = mm_resource_manager_mark_for_acquire(wfd_sink->resource_manager,
- rm_res_type, MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &wfd_sink->hw_resource[type]);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- wfd_sink_error("failed to mark resource for acquire, ret(0x%x)", rm_ret);
- return MM_ERROR_WFD_INTERNAL;
- }
-
- rm_ret = mm_resource_manager_commit(wfd_sink->resource_manager);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- wfd_sink_error("failed to commit of resource, ret(0x%x)", rm_ret);
- return MM_ERROR_WFD_INTERNAL;
- }
-
- wfd_sink_debug_fleave();
- return MM_ERROR_NONE;
-}
-
-static int __mm_wfd_sink_release_hw_resource(mm_wfd_sink_t *wfd_sink, MMWFDSinkResourceType type)
-{
- int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-
- wfd_sink_debug_fenter();
-
- if (wfd_sink->hw_resource[type] == NULL) {
- wfd_sink_debug("there is no acquired [%d type] resource", type);
- return MM_ERROR_NONE;
- }
-
- wfd_sink_debug("mark for release [%d type] resource", type);
- rm_ret = mm_resource_manager_mark_for_release(wfd_sink->resource_manager, wfd_sink->hw_resource[type]);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- wfd_sink_error("failed to mark resource for release, ret(0x%x)", rm_ret);
- return MM_ERROR_WFD_INTERNAL;
- }
-
- wfd_sink->hw_resource[type] = NULL;
-
- rm_ret = mm_resource_manager_commit(wfd_sink->resource_manager);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- wfd_sink_error("failed to commit of resource, ret(0x%x)", rm_ret);
- return MM_ERROR_WFD_INTERNAL;
- }
-
- wfd_sink_debug_fleave();
- return MM_ERROR_NONE;
-}
-
int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink, const char *ini_path)
{
int result = MM_ERROR_NONE;
}
/* initialize resource manager */
- if (mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
- __resource_release_cb, new_wfd_sink, &new_wfd_sink->resource_manager)
- != MM_RESOURCE_MANAGER_ERROR_NONE) {
- wfd_sink_error("failed to initialize resource manager");
- MMWFDSINK_FREEIF(new_wfd_sink);
- return MM_ERROR_WFD_INTERNAL;
+ result = mm_wfd_sink_rm_create(new_wfd_sink);
+ if (result != MM_ERROR_NONE) {
+ result = MM_ERROR_WFD_INTERNAL;
+ wfd_sink_error("failed to mm_wfd_sink_rm_create %d", result);
+ goto fail_to_attrs;
}
/* Initialize gstreamer related */
fail_to_load_ini:
_mmwfd_deconstruct_attribute(new_wfd_sink->attrs);
fail_to_attrs:
- mm_resource_manager_destroy(new_wfd_sink->resource_manager);
+ mm_wfd_sink_rm_release(new_wfd_sink);
MMWFDSINK_FREEIF(new_wfd_sink);
*wfd_sink = NULL;
/* set state */
__mm_wfd_sink_set_state(wfd_sink, MM_WFD_SINK_STATE_NULL);
- if (!wfd_sink->interrupted_by_resource) {
+ if (!wfd_sink->res.interrupted_by_resource) {
int rm_ret = MM_ERROR_NONE;
MMWFDSinkResourceType res_idx = MM_WFD_SINK_RESOURCE_TYPE_MAX;
for (res_idx = MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MM_WFD_SINK_RESOURCE_TYPE_MAX; res_idx++) {
- rm_ret = __mm_wfd_sink_release_hw_resource(wfd_sink, res_idx);
+ rm_ret = mm_wfd_sink_rm_deallocate(wfd_sink, res_idx);
if (rm_ret != MM_ERROR_NONE)
wfd_sink_error("failed to release [%d] resources", res_idx);
}
g_free(wfd_sink->coupled_sink_address);
/* release resource manager */
- if (MM_ERROR_NONE != mm_resource_manager_destroy(wfd_sink->resource_manager)) {
+ if (MM_ERROR_NONE != mm_wfd_sink_rm_release(wfd_sink)) {
result = MM_ERROR_WFD_INTERNAL;
wfd_sink_error("failed to destroy resource manager");
}
MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_H264_PARSE].gst, "src");
if (!g_strcmp0(wfd_sink->ini.name_of_video_h264_decoder, "sprddec_h264") ||
- !g_strcmp0(wfd_sink->ini.name_of_video_h264_decoder, "omxdec_h264")) {
+ !g_strcmp0(wfd_sink->ini.name_of_video_h264_decoder, "omxdec_h264") ||
+ !g_strcmp0(wfd_sink->ini.name_of_video_h264_decoder, "v4l2h264dec")) {
/* acquire HW resource */
wfd_sink_error("wfd_sink->ini.name_of_video_h264_decoder1 :: %s", wfd_sink->ini.name_of_video_h264_decoder);
- if (__mm_wfd_sink_acquire_hw_resource(wfd_sink, MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+ if (mm_wfd_sink_rm_allocate(wfd_sink, MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
wfd_sink_error("failed to acquire video decoder resource");
goto CREATE_ERROR;
}
/* create sink */
mm_attrs_get_int_by_name(wfd_sink->attrs, "display_surface_type", &surface_type);
if (surface_type == MM_DISPLAY_SURFACE_OVERLAY &&
- (__mm_wfd_sink_acquire_hw_resource(wfd_sink, MM_WFD_SINK_RESOURCE_TYPE_VIDEO_OVERLAY) == MM_ERROR_NONE)) {
+ (mm_wfd_sink_rm_allocate(wfd_sink, MM_WFD_SINK_RESOURCE_TYPE_VIDEO_OVERLAY) == MM_ERROR_NONE)) {
MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_SINK, wfd_sink->ini.name_of_video_sink, "video_sink", TRUE);
if(!g_strcmp0(wfd_sink->ini.name_of_video_h264_decoder, "v4l2h264dec") || !g_strcmp0(wfd_sink->ini.name_of_video_h264_decoder, "sprddec_h264"))
if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(v_sinkbin[WFD_SINK_V_S_SINK].gst)), "use-tbm"))
goto CREATE_ERROR;
}
- wfd_sink->interrupted_by_resource = FALSE;
+ wfd_sink->res.interrupted_by_resource = FALSE;
MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_SINK].gst, "sink");
if (v_sinkbin[WFD_SINK_V_S_SINK].gst) {
--- /dev/null
+/*
+ * libmm-wfd
+ *
+ * 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 <unistd.h>
+#include "mm_wfd_sink_rm.h"
+#include "mm_wfd_sink_util.h"
+
+static void
+_mm_wfd_execute_resource_release(mm_wfd_sink_t *wfd_sink)
+{
+ wfd_sink_debug_fenter();
+
+ MMWFDSINK_RET_FAIL(wfd_sink);
+
+ MMWFDSINK_CMD_LOCK(wfd_sink);
+
+ if (_mm_wfd_sink_disconnect(wfd_sink) != MM_ERROR_NONE)
+ wfd_sink_error("failed to disconnect");
+
+ if (_mm_wfd_sink_unprepare(wfd_sink) != MM_ERROR_NONE)
+ wfd_sink_error("failed to unprepare");
+
+ MMWFDSINK_CMD_UNLOCK(wfd_sink);
+
+ wfd_sink_debug_fleave();
+}
+
+static int
+__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;
+
+ MMWFDSINK_RET_VAL_FAIL(name, MM_ERROR_WFD_INVALID_ARGUMENT);
+ MMWFDSINK_RET_VAL_FAIL(size, MM_ERROR_WFD_INVALID_ARGUMENT);
+
+ cmdline = g_strdup_printf("/proc/%d/cmdline", pid);
+
+ if (!g_file_get_contents(cmdline, &contents, NULL, &error)) {
+ wfd_sink_error("error : %s", error->message);
+ return MM_ERROR_WFD_INTERNAL;
+ }
+
+ base = g_path_get_basename(contents);
+
+ if (g_strlcpy(name, base, size) >= size)
+ wfd_sink_error("string truncated");
+
+ return MM_ERROR_NONE;
+}
+
+static rm_cb_result
+__resource_release_cb(int handle, rm_callback_type event_src, rm_device_request_s *info, void *cb_data)
+{
+ mm_wfd_sink_t *wfd_sink = NULL;
+ g_autoptr(GMutexLocker) locker = NULL;
+
+ wfd_sink_debug_fenter();
+
+ if (!cb_data) {
+ wfd_sink_error("cb_data is null");
+ return RM_CB_RESULT_ERROR;
+ }
+
+ wfd_sink = (mm_wfd_sink_t *)cb_data;
+
+ wfd_sink_info("rm callback info wfdsink [%p] handle : %d event_src : %d", wfd_sink, handle, event_src);
+
+ locker = g_mutex_locker_new(&wfd_sink->res.callback_lock);
+
+ switch (event_src) {
+ case RM_CALLBACK_TYPE_RESOURCE_CONFLICT:
+ case RM_CALLBACK_TYPE_RESOURCE_CONFLICT_UD:
+ _mm_wfd_execute_resource_release(wfd_sink);
+ break;
+ default:
+ break;
+ }
+
+ wfd_sink_debug_fleave();
+
+ return RM_CB_RESULT_OK;
+}
+
+int mm_wfd_sink_rm_create(mm_wfd_sink_t *wfd_sink)
+{
+ int ret = 0;
+
+ wfd_sink_debug_fenter();
+
+ MMWFDSINK_RET_VAL_FAIL(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+ g_mutex_init(&wfd_sink->res.control_lock);
+ g_mutex_init(&wfd_sink->res.callback_lock);
+
+ wfd_sink->res.rci.app_pid = (int)getpid();
+
+ if (__get_appid_by_pid(wfd_sink->res.rci.app_pid, wfd_sink->res.rci.app_id, sizeof(wfd_sink->res.rci.app_id)) != MM_ERROR_NONE) {
+ wfd_sink_error("__get_appid_by_pid is failed");
+ return MM_ERROR_WFD_INTERNAL;
+ }
+
+ ret = rm_register((rm_resource_cb)__resource_release_cb,
+ (void *)wfd_sink,
+ &(wfd_sink->res.handle),
+ (wfd_sink->res.rci.app_id[0] != '\0') ? &wfd_sink->res.rci : NULL);
+ if (ret != RM_OK) {
+ wfd_sink_error("rm_register fail %d", ret);
+ return MM_ERROR_WFD_INTERNAL;
+ }
+
+ wfd_sink_info("app pid %d app id %s resource h %d", wfd_sink->res.rci.app_pid, wfd_sink->res.rci.app_id, wfd_sink->res.handle);
+
+ wfd_sink_debug_fleave();
+
+ return MM_ERROR_NONE;
+}
+
+int mm_wfd_sink_rm_allocate(mm_wfd_sink_t *wfd_sink, MMWFDSinkResourceType 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 *devices;
+ g_autoptr(GMutexLocker) locker = NULL;
+
+ wfd_sink_debug_fenter();
+
+ MMWFDSINK_RET_VAL_FAIL(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+ locker = g_mutex_locker_new(&wfd_sink->res.control_lock);
+
+ wfd_sink_info("app id : %s type %d", wfd_sink->res.rci.app_id, type);
+ memset(&request_resources, 0x0, sizeof(rm_category_request_s));
+
+ devices = &wfd_sink->res.devices[type];
+ memset(devices, 0x0, sizeof(rm_device_return_s));
+
+ switch (type) {
+ case MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER:
+ state = RM_STATE_EXCLUSIVE;
+ category_id = RM_CATEGORY_VIDEO_DECODER;
+ break;
+ case MM_WFD_SINK_RESOURCE_TYPE_VIDEO_OVERLAY:
+ state = RM_STATE_EXCLUSIVE;
+ category_id = RM_CATEGORY_SCALER;
+ break;
+ default:
+ wfd_sink_error("category id can't set");
+ return MM_ERROR_WFD_INTERNAL;
+ }
+
+ category_option = rc_get_capable_category_id(wfd_sink->res.handle, wfd_sink->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;
+ wfd_sink_info("state %d category id 0x%x category option %d", state, category_id, category_option);
+
+ ret = rm_allocate_resources(wfd_sink->res.handle, &request_resources, devices);
+ if (ret != RM_OK) {
+ wfd_sink_warning("Resource allocation request failed ret %d [error type %d]", ret, devices->error_type);
+ return MM_ERROR_WFD_INTERNAL;
+ }
+
+ for (idx = 0; idx < devices->allocated_num; idx++)
+ wfd_sink_info("#%d / %d [%p] device %d %s %s", idx, devices->allocated_num, devices,
+ devices->device_id[idx], devices->device_node[idx],
+ devices->device_name[idx]);
+
+ wfd_sink_debug_fleave();
+
+ return MM_ERROR_NONE;
+}
+
+int mm_wfd_sink_rm_deallocate(mm_wfd_sink_t *wfd_sink, MMWFDSinkResourceType type)
+{
+ int rm_ret = RM_OK;
+ int idx = 0;
+ rm_device_request_s requested;
+ rm_device_return_s *r_devices;
+ g_autoptr(GMutexLocker) locker = NULL;
+
+ wfd_sink_debug_fenter();
+
+ MMWFDSINK_RET_VAL_FAIL(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+ MMWFDSINK_RET_VAL_FAIL(wfd_sink->res.handle, MM_ERROR_WFD_NOT_INITIALIZED);
+
+ locker = g_mutex_locker_new(&wfd_sink->res.control_lock);
+
+ r_devices = &wfd_sink->res.devices[type];
+
+ wfd_sink_info("[%p] #%d (type %d) alloc num %d", r_devices, idx, type, r_devices->allocated_num);
+
+ if (r_devices->allocated_num > 0) {
+ memset(&requested, 0x0, sizeof(rm_device_request_s));
+ requested.request_num = r_devices->allocated_num;
+ for (idx = 0; idx < requested.request_num; idx++) {
+ requested.device_id[idx] = r_devices->device_id[idx];
+ wfd_sink_info("[device id %d] [device name %s]", r_devices->device_id[idx], r_devices->device_name[idx]);
+ }
+
+ rm_ret = rm_deallocate_resources(wfd_sink->res.handle, &requested);
+ if (rm_ret != RM_OK) {
+ wfd_sink_error("Resource deallocation request failed [%d] [request num %d]", rm_ret, requested.request_num);
+ return MM_ERROR_WFD_INTERNAL;
+ }
+ }
+
+ for (idx = 0; idx < r_devices->allocated_num; idx++) {
+ if (r_devices->device_node[idx]) {
+ free(r_devices->device_node[idx]);
+ r_devices->device_node[idx] = NULL;
+ }
+
+ if (r_devices->omx_comp_name[idx]) {
+ free(r_devices->omx_comp_name[idx]);
+ r_devices->omx_comp_name[idx] = NULL;
+ }
+ }
+
+ wfd_sink_debug_fleave();
+
+ return MM_ERROR_NONE;
+}
+
+int mm_wfd_sink_rm_release(mm_wfd_sink_t *wfd_sink)
+{
+ int ret;
+
+ wfd_sink_debug_fenter();
+
+ MMWFDSINK_RET_VAL_FAIL(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+ if (!wfd_sink->res.handle) {
+ wfd_sink_info("resource manager handle is not registered");
+ return MM_ERROR_NONE;
+ }
+
+ ret = rm_unregister(wfd_sink->res.handle);
+ if (ret != RM_OK) {
+ wfd_sink_error("rm_unregister fail %d", ret);
+ return MM_ERROR_WFD_INTERNAL;
+ }
+
+ g_mutex_clear(&wfd_sink->res.control_lock);
+ g_mutex_clear(&wfd_sink->res.callback_lock);
+
+ wfd_sink_debug("rm_unregister[%d]", ret);
+
+ wfd_sink_debug_fleave();
+
+ return MM_ERROR_NONE;
+}