SET(dependents "dlog glib-2.0 mm-common libtbm capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-pbutils-1.0 gstreamer-tag-1.0 capi-system-info gstreamer-allocators-1.0")
SET(pc_dependents "capi-base-common capi-media-tool")
-IF(TIZEN_FEATURE_MM_RESOURCE_MANAGER)
-SET(dependents "${dependents} mm-resource-manager")
-ENDIF(TIZEN_FEATURE_MM_RESOURCE_MANAGER)
+IF(RMC)
+SET(dependents "${dependents} resource-manager resource-center-api")
+ENDIF(RMC)
INCLUDE(FindPkgConfig)
pkg_check_modules(${fw_name} REQUIRED ${dependents})
ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
ADD_DEFINITIONS("-DTIZEN_DEBUG")
-IF(TIZEN_FEATURE_MM_RESOURCE_MANAGER)
-ADD_DEFINITIONS("-DUSE_MM_RESOURCE_MANAGER")
-ENDIF(TIZEN_FEATURE_MM_RESOURCE_MANAGER)
+IF(RMC)
+ADD_DEFINITIONS("-DRM_COMMON")
+ENDIF(RMC)
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
#include <media_codec.h>
#include <mm_types.h>
-#ifdef USE_MM_RESOURCE_MANAGER
-#include <mm_resource_manager.h>
+#ifdef RM_COMMON
+#include <rm_api.h>
#endif
#ifdef __cplusplus
MEDIACODEC_PORT_TYPE_MAX,
} mediacodec_port_type_e;
+#ifdef RM_COMMON
+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 */
+} mediacodec_res_type_e;
+
+typedef struct _mediacodec_res_s {
+ int handle;
+ rm_device_return_s devices[RES_TYPE_MAX];
+ rm_consumer_info rci;
+ GMutex callback_lock;
+ GMutex control_lock;
+} mediacodec_res_s;
+#endif
+
/**
* @brief Media Codec's format for configuring codec.
*/
int state;
bool is_omx;
char *m_mime;
-#ifdef USE_MM_RESOURCE_MANAGER
- mm_resource_manager_res_h codec_resource;
+
+#ifdef RM_COMMON
+ mediacodec_res_s resource;
#endif
mediacodec_input_buffer_used_cb empty_buffer_cb;
} mediacodec_s;
bool __mediacodec_state_validate(mediacodec_h mediacodec, mediacodec_state_e threshold);
+gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data);
#ifdef __cplusplus
}
--- /dev/null
+/*
+* Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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 __TIZEN_MEDIA_CODEC_RM_H__
+#define __TIZEN_MEDIA_CODEC_RM_H__
+
+#include <media_codec_private.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int mediacodec_resource_create(mediacodec_s *mediacodec );
+int mediacodec_resource_allocate(mediacodec_s *mediacodec, mediacodec_res_type_e type);
+int mediacodec_resource_deallocate(mediacodec_s *mediacodec, mediacodec_res_type_e type);
+int mediacodec_resource_release(mediacodec_s *mediacodec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_MEDIA_CODEC_RM_H__ */
Name: capi-media-codec
Summary: A Media Codec library in Tizen Native API
-Version: 1.0.2
+Version: 1.1.0
Release: 0
Group: Multimedia/API
License: Apache-2.0
BuildRequires: pkgconfig(capi-system-info)
BuildRequires: pkgconfig(iniparser)
%if "%{tizen_profile_name}" != "tv"
-BuildRequires: pkgconfig(mm-resource-manager)
+BuildRequires: pkgconfig(resource-center-api)
+BuildRequires: pkgconfig(resource-manager)
%endif
#BuildRequires: pkgconfig(capi-media-camera)
#BuildRequires: pkgconfig(capi-mediademuxer)
SO_MAJORVER=`echo ${SO_FULLVER} | awk 'BEGIN {FS="."}{print $1}'`
%cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} -DSO_FULLVER=${SO_FULLVER} -DSO_MAJORVER=${SO_MAJORVER} \
%if "%{tizen_profile_name}" == "tv"
- -DTIZEN_FEATURE_MM_RESOURCE_MANAGER=NO
+ -DRMC=NO
%else
- -DTIZEN_FEATURE_MM_RESOURCE_MANAGER=YES
+ -DRMC=YES
%endif
make %{?jobs:-j%jobs}
#include <dlog.h>
-#define MC_PREALLOCATED_HANDLE_ARRAY_SIZE 16
-
-#ifdef USE_MM_RESOURCE_MANAGER
-static mm_resource_manager_h g_mc_resource_manager;
-static GPtrArray *g_mediacodec_handles;
-static GMutex g_mediacodec_lock;
+#ifdef RM_COMMON
+#include <media_codec_rm.h>
#endif
static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data);
static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data);
-static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data);
static gboolean __mediacodec_eos_cb(void *user_data);
static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data);
-#ifdef USE_MM_RESOURCE_MANAGER
-static void __mediacodec_init_lib() __attribute__((constructor));
-static void __mediacodec_deinit_lib() __attribute__((destructor));
-static int __mediacodec_resource_release_cb(mm_resource_manager_h rm,
- mm_resource_manager_res_h resource_h, void *user_data);
-#endif
/*
* Internal Implementation
LOGD("mediacodec_create..");
-#ifdef USE_MM_RESOURCE_MANAGER
- g_mutex_lock(&g_mediacodec_lock);
-
- if (!g_mc_resource_manager) {
- int mm_ret = mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
- __mediacodec_resource_release_cb, NULL, &g_mc_resource_manager);
- if (mm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- g_mutex_unlock(&g_mediacodec_lock);
- LOGE("mm_resource_manager_create failed 0x%x", mm_ret);
- return MEDIACODEC_ERROR_INTERNAL;
- }
- }
-
- g_mutex_unlock(&g_mediacodec_lock);
-#endif
-
handle = (mediacodec_s *)malloc(sizeof(mediacodec_s));
if (handle != NULL) {
memset(handle, 0 , sizeof(mediacodec_s));
mc_set_eos_cb(handle->mc_handle, (mediacodec_eos_cb)__mediacodec_eos_cb, handle);
mc_set_buffer_status_cb(handle->mc_handle, (mediacodec_buffer_status_cb)__mediacodec_buffer_status_cb, handle);
-#ifdef USE_MM_RESOURCE_MANAGER
- g_mutex_lock(&g_mediacodec_lock);
- g_ptr_array_insert(g_mediacodec_handles, -1, *mediacodec);
- g_mutex_unlock(&g_mediacodec_lock);
+#ifdef RM_COMMON
+ ret = mediacodec_resource_create(handle);
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ handle->state = MEDIACODEC_STATE_NONE;
+ if (mc_destroy(handle->mc_handle) != MEDIACODEC_ERROR_NONE) {
+ LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
+ return MEDIACODEC_ERROR_INVALID_OPERATION;
+ }
+ g_free(handle);
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ }
#endif
return MEDIACODEC_ERROR_NONE;
int ret = mc_destroy(handle->mc_handle);
if (ret != MEDIACODEC_ERROR_NONE) {
- LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION); //LCOV_EXCL_LINE
+ LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION); //LCOV_EXCL_LINE
return MEDIACODEC_ERROR_INVALID_OPERATION;
- } else {
-#ifdef USE_MM_RESOURCE_MANAGER
- g_mutex_lock(&g_mediacodec_lock);
- g_ptr_array_remove_fast(g_mediacodec_handles, mediacodec);
- g_mutex_unlock(&g_mediacodec_lock);
-#endif
+ }
- handle->state = MEDIACODEC_STATE_NONE;
- free(handle);
- handle = NULL;
- return MEDIACODEC_ERROR_NONE;
+#ifdef RM_COMMON
+ ret = mediacodec_resource_release(handle);
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
}
+#endif
+
+ handle->state = MEDIACODEC_STATE_NONE;
+ free(handle);
+ handle = NULL;
+ return MEDIACODEC_ERROR_NONE;
+
}
int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, int flags)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
mediacodec_s *handle = (mediacodec_s *)mediacodec;
-#ifdef USE_MM_RESOURCE_MANAGER
- mc_handle_t *mc_handle = (mc_handle_t *) handle->mc_handle;
- int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
- mm_resource_manager_res_h resource;
-#endif
+ int ret;
+ mc_handle_t *mc_handle = NULL;
+
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
-#ifdef USE_MM_RESOURCE_MANAGER
+#ifdef RM_COMMON
+//LCOV_EXCL_START
+ mc_handle = handle->mc_handle;
+ MEDIACODEC_INSTANCE_CHECK(mc_handle);
+
if (mc_handle->is_hw && mc_handle->is_video) {
+ mc_handle = (mc_handle_t *) handle->mc_handle;
- if (handle->codec_resource) {
- LOGE("Codec resource is tried to be acquired twice\n"); //LCOV_EXCL_LINE
- return MC_INTERNAL_ERROR;
- }
+ ret = mediacodec_resource_allocate(handle, mc_handle->is_encoder ? RES_TYPE_VIDEO_ENCODER : RES_TYPE_VIDEO_DECODER);
- /*
- * TODO
- * Currently volume of requested resource is set to 1. Default
- * capacity for video encoder/decoder is 1 too. The actual capacity
- * should be set in mmfw-sysconf > mmfw_resource_manager.ini.
- * If different encode/decode operation needs different volume of
- * video encoder/decoder, '1' in the following
- * mm_resource_manager_mark_for_acquire function should be set to
- * corresponding value.
- * If that value depends on platform where it's executed,
- * MM_RESOURCE_MANAGER_RES_TYPE_COND_* and
- * mm_resource_manager_get_res_type_volume() can be used.
- * Additional info can be found in doxygen comments of mm_resource_manager.h
- */
-//LCOV_EXCL_START
- rm_ret = mm_resource_manager_mark_for_acquire(g_mc_resource_manager,
- mc_handle->is_encoder ?
- MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER :
- MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER,
- 1, &resource);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- LOGE("Failed to acquire resource manager %x", rm_ret);
- switch (rm_ret) {
- case MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED:
- return MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
- case MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH:
- return MEDIACODEC_ERROR_RESOURCE_OVERLOADED;
- default:
- return MEDIACODEC_ERROR_INTERNAL;
- }
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
}
-
- rm_ret = mm_resource_manager_commit(g_mc_resource_manager);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- mm_resource_manager_mark_for_release(g_mc_resource_manager, resource);
- LOGE("Failed to commit resource manager : %x", rm_ret);
- return MEDIACODEC_ERROR_INTERNAL;
- }
- handle->codec_resource = resource;
//LCOV_EXCL_STOP
}
#endif
- int ret = mc_prepare(handle->mc_handle);
+ ret = mc_prepare(handle->mc_handle);
if (ret != MEDIACODEC_ERROR_NONE) {
return __convert_error_code(ret, (char *)__FUNCTION__);
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
mediacodec_s *handle = (mediacodec_s *)mediacodec;
-#ifdef USE_MM_RESOURCE_MANAGER
- int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-#endif
+ mc_handle_t *mc_handle = handle->mc_handle;
+
+ MEDIACODEC_INSTANCE_CHECK(mc_handle);
int ret = mc_unprepare(handle->mc_handle);
if (ret != MEDIACODEC_ERROR_NONE) {
return __convert_error_code(ret, (char *)__FUNCTION__);
- } else {
-#ifdef USE_MM_RESOURCE_MANAGER
- if (handle->codec_resource != NULL) {
+ }
+
+#ifdef RM_COMMON
//LCOV_EXCL_START
- mm_resource_manager_mark_for_release(g_mc_resource_manager,
- handle->codec_resource);
- handle->codec_resource = NULL;
- rm_ret = mm_resource_manager_commit(g_mc_resource_manager);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- mm_resource_manager_mark_for_release(g_mc_resource_manager, handle->codec_resource);
- switch (rm_ret) {
- case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY:
- return MEDIACODEC_ERROR_RESOURCE_OVERLOADED;
- default:
- return MEDIACODEC_ERROR_INTERNAL;
- }
- }
+ ret = mediacodec_resource_deallocate(handle, mc_handle->is_encoder ? RES_TYPE_VIDEO_ENCODER : RES_TYPE_VIDEO_DECODER);
+
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ }
//LCOV_EXCL_STOP
- } else {
- LOGD("No codec resource to release. Probably resource release cb called\n");
- }
#endif
- handle->state = MEDIACODEC_STATE_IDLE;
- return MEDIACODEC_ERROR_NONE;
- }
+ handle->state = MEDIACODEC_STATE_IDLE;
+ return MEDIACODEC_ERROR_NONE;
}
int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
return 1;
}
-static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
+gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
{
if (user_data == NULL)
return 0;
return 1;
}
-
-#ifdef USE_MM_RESOURCE_MANAGER
-//LCOV_EXCL_START
-static int __mediacodec_resource_release_cb(mm_resource_manager_h rm,
- mm_resource_manager_res_h resource_h, void *user_data)
-{
- int i;
- mediacodec_s *handle;
-
- g_mutex_lock(&g_mediacodec_lock);
- for (i = 0; i < g_mediacodec_handles->len; i++) {
- handle = g_ptr_array_index(g_mediacodec_handles, i);
- if (handle->codec_resource == resource_h) {
- /*
- * TODO
- * The resource release cb is asynchronous, so mediacodec_unprepare might be
- * called in this thread and in the main thread at the same time.
- * Mutex lock/unlock should be added in the body of mediacodec_unprepare() to
- * avoid the race condition.
- */
- handle->codec_resource = NULL;
- mediacodec_unprepare((mediacodec_h)handle);
- __mediacodec_error_cb(MEDIACODEC_ERROR_RESOURCE_CONFLICT, handle);
- break;
- }
- }
- g_mutex_unlock(&g_mediacodec_lock);
-
- return FALSE;
-}
-//LCOV_EXCL_STOP
-
-
-static void __mediacodec_init_lib()
-{
- LOGD("START");
-
- g_mutex_init(&g_mediacodec_lock);
- g_mediacodec_handles = g_ptr_array_sized_new(MC_PREALLOCATED_HANDLE_ARRAY_SIZE);
-
- LOGD("DONE");
-}
-
-static void __mediacodec_deinit_lib()
-{
- LOGD("START");
-
- if (g_mc_resource_manager != NULL)
- mm_resource_manager_destroy(g_mc_resource_manager);
-
- g_ptr_array_unref(g_mediacodec_handles);
- g_mutex_clear(&g_mediacodec_lock);
-
- LOGD("DONE");
-}
-#endif
-
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#ifdef RM_COMMON
+
+#include "media_codec_rm.h"
+#include <dlog.h>
+
+#include <rm_api.h>
+#include <rm_type.h>
+#include <resource_center.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+//LCOV_EXCL_START
+static rm_cb_result
+__mediacodec_resource_release_cb(int handle, rm_callback_type event_src, rm_device_request_s *info, void *cb_data)
+{
+ mediacodec_s *mediacodec = (mediacodec_s *)cb_data;
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+ g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&mediacodec->resource.callback_lock);
+
+ LOGI("rm callback info mediacodec_s [%p] handle : %d event_src : %d", mediacodec, handle, event_src);
+
+ switch (event_src) {
+ case RM_CALLBACK_TYPE_RESOURCE_CONFLICT:
+ case RM_CALLBACK_TYPE_RESOURCE_CONFLICT_UD:
+ mediacodec_unprepare((mediacodec_h)mediacodec);
+ __mediacodec_error_cb(MEDIACODEC_ERROR_RESOURCE_CONFLICT, mediacodec);
+ break;
+ default:
+ break;
+ }
+
+ LOGI("RM_CB_RESULT_OK");
+
+ return RM_CB_RESULT_OK;
+}
+//LCOV_EXCL_STOP
+
+static int
+__mediacodec_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;
+
+ MEDIACODEC_NULL_ARG_CHECK(name);
+
+ cmdline = g_strdup_printf("/proc/%d/cmdline", (int)pid);
+
+ if (!g_file_get_contents(cmdline, &contents, NULL, &error)) {
+ LOGE("error : %s", error->message);
+ return MEDIACODEC_ERROR_INVALID_OPERATION;
+ }
+
+ base = g_path_get_basename(contents);
+
+ if (g_strlcpy(name, base, size) >= size) {
+ LOGE("string truncated");
+ return MEDIACODEC_ERROR_INVALID_OPERATION;
+ }
+
+ return MEDIACODEC_ERROR_NONE;
+}
+
+int mediacodec_resource_create(mediacodec_s *mediacodec)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+ int ret = 0;
+
+ g_mutex_init(&mediacodec->resource.control_lock);
+ g_mutex_init(&mediacodec->resource.callback_lock);
+
+ g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&mediacodec->resource.control_lock);
+
+ memset(&mediacodec->resource.rci, 0x00, sizeof(rm_consumer_info));
+
+ mediacodec->resource.rci.app_pid = (int)getpid();
+
+ if (__mediacodec_get_appid_by_pid(mediacodec->resource.rci.app_pid,
+ mediacodec->resource.rci.app_id,
+ sizeof(mediacodec->resource.rci.app_id)) != MEDIACODEC_ERROR_NONE) {
+ LOGE("__mediacodec_get_appid_by_pid is failed");
+ return MEDIACODEC_ERROR_INTERNAL;
+ }
+
+ LOGI("app pid %d app id %s", mediacodec->resource.rci.app_pid, mediacodec->resource.rci.app_id);
+
+ ret = rm_register((rm_resource_cb)__mediacodec_resource_release_cb,
+ (void *)mediacodec,
+ &(mediacodec->resource.handle),
+ (mediacodec->resource.rci.app_id[0] != '\0') ? &mediacodec->resource.rci : NULL);
+ if (ret != RM_OK) {
+ LOGE("rm_register fail %d", ret);
+ return MEDIACODEC_ERROR_INTERNAL;
+ }
+
+ return MEDIACODEC_ERROR_NONE;
+}
+
+int mediacodec_resource_allocate(mediacodec_s *mediacodec, mediacodec_res_type_e type)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+
+ int ret = 0;
+ 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 = g_mutex_locker_new(&mediacodec->resource.control_lock);
+
+ memset(&request_resources, 0x0, sizeof(rm_category_request_s));
+
+ device = &mediacodec->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:
+ LOGE("category id can't set");
+ return MEDIACODEC_ERROR_INTERNAL;
+ }
+
+ category_option = rc_get_capable_category_id(mediacodec->resource.handle, mediacodec->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;
+ LOGI("state %d category id 0x%x category option %d", state, category_id, category_option);
+
+ ret = rm_allocate_resources(mediacodec->resource.handle, &request_resources, device);
+ if (ret != RM_OK) {
+ LOGW("Resource allocation request failed ret %d [error type %d]", ret, device->error_type);
+ return MEDIACODEC_ERROR_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]);
+ }
+
+ return MEDIACODEC_ERROR_NONE;
+}
+
+int mediacodec_resource_deallocate(mediacodec_s *mediacodec, mediacodec_res_type_e type)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+
+ int rm_ret = RM_OK;
+ int idx = 0;
+ rm_device_request_s requested;
+ rm_device_return_s *r_devices;
+ g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&mediacodec->resource.control_lock);
+
+ LOGI("app id : %s type %d", mediacodec->resource.rci.app_id, type);
+
+ if (mediacodec->resource.handle == 0) {
+ LOGE("Resource handle is not initialized");
+ return MEDIACODEC_ERROR_INVALID_OPERATION;
+ }
+
+ r_devices = &mediacodec->resource.devices[type];
+
+ LOGI("[%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];
+ LOGI("[device id %d] [device name %s]", r_devices->device_id[idx], r_devices->device_name[idx]);
+ }
+
+ rm_ret = rm_deallocate_resources(mediacodec->resource.handle, &requested);
+ if (rm_ret != RM_OK) {
+ LOGE("Resource deallocation request failed [%d] [request num %d]", rm_ret, requested.request_num);
+ return MEDIACODEC_ERROR_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;
+ }
+ }
+
+ return MEDIACODEC_ERROR_NONE;
+}
+
+
+int mediacodec_resource_release(mediacodec_s *mediacodec)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+ int ret = 0;
+ g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&mediacodec->resource.control_lock);
+
+ ret = rm_unregister(mediacodec->resource.handle);
+ if (ret != RM_OK) {
+ LOGE("rm_unregister fail %d", ret);
+ return MEDIACODEC_ERROR_INTERNAL;
+ }
+
+ g_clear_pointer (&locker, g_mutex_locker_free);
+
+ g_mutex_clear(&mediacodec->resource.control_lock);
+ g_mutex_clear(&mediacodec->resource.callback_lock);
+
+ return MEDIACODEC_ERROR_NONE;
+}
+#endif