From: YoungHun Kim Date: Tue, 16 Jul 2024 08:23:00 +0000 (+0900) Subject: Enable resource manager commonization X-Git-Tag: accepted/tizen/unified/20240816.171352^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F18%2F314618%2F17;p=platform%2Fcore%2Fapi%2Fmediacodec.git Enable resource manager commonization [Version] 1.1.0 [Issue Type] Update Change-Id: Iafc1f27db618838b47138ae9f36ffd5cde5f7e68 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index fb87c89..9f3c7ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,9 @@ INCLUDE_DIRECTORIES(${INC_DIR}) 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}) @@ -31,9 +31,9 @@ ENDIF("${ARCH}" STREQUAL "arm") 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}") diff --git a/include/media_codec_private.h b/include/media_codec_private.h index 08cfecc..12915a0 100644 --- a/include/media_codec_private.h +++ b/include/media_codec_private.h @@ -24,8 +24,8 @@ #include #include -#ifdef USE_MM_RESOURCE_MANAGER -#include +#ifdef RM_COMMON +#include #endif #ifdef __cplusplus @@ -75,6 +75,22 @@ typedef enum { 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. */ @@ -103,8 +119,9 @@ typedef struct _mediacodec_s { 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; @@ -120,6 +137,7 @@ typedef struct _mediacodec_s { } 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 } diff --git a/include/media_codec_rm.h b/include/media_codec_rm.h new file mode 100644 index 0000000..2265e79 --- /dev/null +++ b/include/media_codec_rm.h @@ -0,0 +1,35 @@ +/* +* 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 + +#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__ */ diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index deae11c..187de3d 100644 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ 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 @@ -25,7 +25,8 @@ BuildRequires: pkgconfig(gstreamer-allocators-1.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) @@ -73,9 +74,9 @@ SO_FULLVER=0.7.0 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} diff --git a/src/media_codec.c b/src/media_codec.c index 0e094fd..649c126 100644 --- a/src/media_codec.c +++ b/src/media_codec.c @@ -24,25 +24,14 @@ #include -#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 #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 @@ -134,22 +123,6 @@ int mediacodec_create(mediacodec_h *mediacodec) 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)); @@ -179,10 +152,17 @@ int mediacodec_create(mediacodec_h *mediacodec) 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; @@ -197,20 +177,22 @@ int mediacodec_destroy(mediacodec_h mediacodec) 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) @@ -313,65 +295,29 @@ int mediacodec_prepare(mediacodec_h mediacodec) { 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__); @@ -385,40 +331,28 @@ int mediacodec_unprepare(mediacodec_h mediacodec) { 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) @@ -661,7 +595,7 @@ static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data 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; @@ -699,60 +633,3 @@ static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void * 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 - diff --git a/src/media_codec_rm.c b/src/media_codec_rm.c new file mode 100644 index 0000000..f7c8739 --- /dev/null +++ b/src/media_codec_rm.c @@ -0,0 +1,242 @@ +/* + * 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 + +#include +#include +#include +#include +#include + +//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