*/
#include "webrtc.h"
#include "webrtc_private.h"
+#include <rm_type.h>
+#include <resource_center.h>
-int _acquire_resource_if_needed(webrtc_s *webrtc)
+static int __get_appid_by_pid(int pid, char *name, size_t size)
{
- int i;
- int ret = WEBRTC_ERROR_NONE;
+ g_autofree gchar *cmdline = NULL;
+ g_autofree gchar *contents = NULL;
+ g_autofree gchar *base = NULL;
+ g_autoptr(GError) error = NULL;
- RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(name == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "name is NULL");
+ RET_VAL_IF(size == 0, WEBRTC_ERROR_INVALID_PARAMETER, "size is 0");
+
+ cmdline = g_strdup_printf("/proc/%d/cmdline", pid);
- for (i = 0; i < RESOURCE_TYPE_MAX; i++) {
- if (!webrtc->resource.need_to_acquire[i])
- continue;
- if ((ret = _acquire_resource_for_type(webrtc, i)) != WEBRTC_ERROR_NONE)
- return ret;
- webrtc->resource.need_to_acquire[i] = false;
+ if (!g_file_get_contents(cmdline, &contents, NULL, &error)) {
+ LOG_ERROR("error : %s", error->message);
+ return WEBRTC_ERROR_INVALID_OPERATION;
}
- return ret;
+ base = g_path_get_basename(contents);
+
+ if (g_strlcpy(name, base, size) >= size)
+ LOG_ERROR("string truncated");
+
+ return WEBRTC_ERROR_NONE;
+}
+
+static void __execute_resource_release(webrtc_s *webrtc)
+{
+ RET_IF(webrtc == NULL, "webrtc is NULL");
+
+ if (_stop(webrtc) != WEBRTC_ERROR_NONE)
+ LOG_ERROR("stop is failed");
+
+ _post_error_cb_in_idle(webrtc, WEBRTC_ERROR_RESOURCE_CONFLICT);
}
//LCOV_EXCL_START
-static int __resource_release_cb(mm_resource_manager_h mgr,
- mm_resource_manager_res_h res, void *user_data)
+static rm_cb_result __rm_callback(int handle, rm_callback_type event_src, rm_device_request_s *info, void *cb_data)
{
- int i;
- int ret = true;
- webrtc_s *webrtc = (webrtc_s *)user_data;
+ webrtc_s *webrtc = (webrtc_s *)(cb_data);
+ g_autoptr(GMutexLocker) locker = NULL;
- RET_VAL_IF(webrtc == NULL, false, "webrtc is NULL");
+ ASSERT(webrtc);
- webrtc->resource.release_cb_is_calling = true;
+ LOGI("webrtc[%p] rm handle[%d] event_src[%d]", webrtc, handle, event_src);
- for (i = 0; i < RESOURCE_TYPE_MAX; i++) {
- if (webrtc->resource.res[i] == res) {
- LOG_INFO("type[%d] resource was released by resource manager", i);
- webrtc->resource.res[i] = NULL;
- }
+ switch (event_src) {
+ case RM_CALLBACK_TYPE_RESOURCE_CONFLICT:
+ case RM_CALLBACK_TYPE_RESOURCE_CONFLICT_UD:
+ __execute_resource_release(webrtc);
+ break;
+ default:
+ break;
}
- if (_stop(webrtc) != WEBRTC_ERROR_NONE)
- ret = false;
+ LOG_DEBUG_LEAVE();
- _post_error_cb_in_idle(webrtc, WEBRTC_ERROR_RESOURCE_CONFLICT);
+ return RM_CB_RESULT_OK;
+}
+//LCOV_EXCL_STOP
+
+//LCOV_EXCL_START
+int _release_all_resources(webrtc_s *webrtc)
+{
+ int idx;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
- webrtc->resource.release_cb_is_calling = false;
+ for (idx = 0; idx < RES_TYPE_MAX; idx++) {
+ if (_release_resource(webrtc, idx) != WEBRTC_ERROR_NONE) {
+ LOG_ERROR("#%d resource deallocate is failed", idx);
+ return WEBRTC_ERROR_RESOURCE_FAILED;
+ }
+ }
- return ret;
+ return WEBRTC_ERROR_NONE;
}
//LCOV_EXCL_STOP
-int _create_resource_manager(webrtc_s *webrtc)
+int _acquire_resource_if_needed(webrtc_s *webrtc)
{
+ int idx;
+
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
- if (mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
- __resource_release_cb, webrtc,
- &webrtc->resource.mgr) != MM_RESOURCE_MANAGER_ERROR_NONE) {
-//LCOV_EXCL_START
- LOG_ERROR("failed to init resource manager for media");
- return WEBRTC_ERROR_RESOURCE_FAILED;
-//LCOV_EXCL_STOP
+ for (idx = 0; idx < RES_TYPE_MAX; idx++) {
+ if (webrtc->resource.need_to_acquire[idx] && _acquire_resource(webrtc, idx) != WEBRTC_ERROR_NONE) {
+ LOG_ERROR("#%d resource allocate is failed", idx);
+ return WEBRTC_ERROR_RESOURCE_FAILED;
+ }
}
return WEBRTC_ERROR_NONE;
}
-int _acquire_resource_for_type(webrtc_s *webrtc, mm_resource_manager_res_type_e type)
+//LCOV_EXCL_START
+int _register_resource_manager(webrtc_s *webrtc)
{
- int ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+ int ret;
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
- RET_VAL_IF(type >= RESOURCE_TYPE_MAX, WEBRTC_ERROR_INVALID_PARAMETER, "invalid type(%d)", type);
- if (!webrtc->resource.mgr)
- return WEBRTC_ERROR_NONE;
+ g_mutex_init(&webrtc->resource.control_lock);
- if (webrtc->resource.res[type] != NULL) {
-//LCOV_EXCL_START
- LOG_ERROR("type[%d] resource was already acquired", type);
- return WEBRTC_ERROR_RESOURCE_FAILED;
-//LCOV_EXCL_STOP
+ memset(&webrtc->resource.rci, 0x00, sizeof(rm_consumer_info));
+
+ webrtc->resource.rci.app_pid = (int)getpid();
+
+ if (__get_appid_by_pid(webrtc->resource.rci.app_pid, webrtc->resource.rci.app_id, sizeof(webrtc->resource.rci.app_id)) != WEBRTC_ERROR_NONE) {
+ LOGE("__mmplayer_get_appid_by_pid is failed");
+ return WEBRTC_ERROR_INVALID_OPERATION;
}
- LOG_DEBUG("mark for acquire type[%d] resource", type);
- ret = mm_resource_manager_mark_for_acquire(webrtc->resource.mgr, type,
- MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &webrtc->resource.res[type]);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-//LCOV_EXCL_START
- LOG_ERROR("failed to mark resource for acquire, ret[0x%x]", ret);
+ ret = rm_register((rm_resource_cb)__rm_callback,
+ (void *)webrtc,
+ &(webrtc->resource.handle),
+ (webrtc->resource.rci.app_id[0] != '\0') ? &webrtc->resource.rci : NULL);
+ if (ret != RM_OK) {
+ LOG_ERROR("rm_register fail %d", ret);
return WEBRTC_ERROR_RESOURCE_FAILED;
+ }
+
+ LOG_INFO("app pid %d app id %s resource h %d", webrtc->resource.rci.app_pid, webrtc->resource.rci.app_id, webrtc->resource.handle);
+
+ return WEBRTC_ERROR_NONE;
+}
//LCOV_EXCL_STOP
+
+int _acquire_resource(webrtc_s *webrtc, res_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;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(type >= RES_TYPE_MAX, WEBRTC_ERROR_INVALID_PARAMETER, "invalid type(%d)", type);
+
+ locker = g_mutex_locker_new(&webrtc->resource.control_lock);
+
+ LOG_INFO("app id : %s type %d", webrtc->resource.rci.app_id, type);
+ memset(&request_resources, 0x0, sizeof(rm_category_request_s));
+
+ device = &webrtc->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_OVERLAY:
+ state = RM_STATE_EXCLUSIVE;
+ category_id = RM_CATEGORY_SCALER;
+ break;
+ case RES_TYPE_CAMERA:
+ state = RM_STATE_EXCLUSIVE;
+ category_id = RM_CATEGORY_CAMERA;
+ break;
+ case RES_TYPE_VIDEO_ENCODER:
+ state = RM_STATE_EXCLUSIVE;
+ category_id = RM_CATEGORY_VIDEO_ENCODER;
+ break;
+ default:
+ LOG_ERROR("category id can't set");
+ return WEBRTC_ERROR_RESOURCE_FAILED;
}
- LOG_DEBUG("commit type[%d] resource", type);
- ret = mm_resource_manager_commit(webrtc->resource.mgr);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-//LCOV_EXCL_START
- LOG_ERROR("failed to commit of resource, ret([0x%x]", ret);
+ category_option = rc_get_capable_category_id(webrtc->resource.handle, webrtc->resource.rci.app_id, category_id);
+
+ request_resources.request_num = 1;
+ request_resources.state[0] = state;
+ request_resources.category_id[0] = category_id;
+ request_resources.category_option[0] = category_option;
+ LOG_INFO("state %d category id 0x%x category option %d", state, category_id, category_option);
+
+ ret = rm_allocate_resources(webrtc->resource.handle, &request_resources, device);
+ if (ret != RM_OK) {
+ LOG_ERROR("Resource allocation request failed ret %d [error type %d]", ret, device->error_type);
return WEBRTC_ERROR_RESOURCE_FAILED;
-//LCOV_EXCL_STOP
}
+ for (idx = 0; idx < device->allocated_num; idx++)
+ LOG_INFO("#%d / %d [%p] device %d %s %s", idx, device->allocated_num, device,
+ device->device_id[idx], device->device_node[idx],
+ device->device_name[idx]);
+
return WEBRTC_ERROR_NONE;
}
-int _release_all_resources(webrtc_s *webrtc)
+int _release_resource(webrtc_s *webrtc, res_type_e type)
{
- int i;
- int ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+ int rm_ret = RM_OK;
+ int idx = 0;
+ rm_device_request_s requested;
+ rm_device_return_s *devices;
+ g_autoptr(GMutexLocker) locker = NULL;
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(webrtc->resource.handle == 0, WEBRTC_ERROR_RESOURCE_FAILED, "webrtc resource handle is NULL");
- if (!webrtc->resource.mgr)
- return WEBRTC_ERROR_NONE;
+ locker = g_mutex_locker_new(&webrtc->resource.control_lock);
- if (webrtc->resource.release_cb_is_calling) {
-//LCOV_EXCL_START
- LOG_INFO("__resource_release_cb is calling, so skip");
- return WEBRTC_ERROR_NONE;
-//LCOV_EXCL_STOP
- }
+ devices = &webrtc->resource.devices[type];
- ret = mm_resource_manager_mark_all_for_release(webrtc->resource.mgr);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-//LCOV_EXCL_START
- LOG_ERROR("failed to mark all for release, ret[0x%x]", ret);
- return WEBRTC_ERROR_RESOURCE_FAILED;
-//LCOV_EXCL_STOP
- }
- ret = mm_resource_manager_commit(webrtc->resource.mgr);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-//LCOV_EXCL_START
- LOG_ERROR("failed to commit resource, ret[0x%x]", ret);
- return WEBRTC_ERROR_RESOURCE_FAILED;
-//LCOV_EXCL_STOP
+ LOG_INFO("[%p] #%d (type %d) alloc num %d", devices, idx, type, devices->allocated_num);
+
+ if (devices->allocated_num > 0) {
+ memset(&requested, 0x0, sizeof(rm_device_request_s));
+ requested.request_num = devices->allocated_num;
+ for (idx = 0; idx < requested.request_num; idx++) {
+ requested.device_id[idx] = devices->device_id[idx];
+ LOG_INFO("[device id %d] [device name %s]", devices->device_id[idx], devices->device_name[idx]);
+ }
+
+ rm_ret = rm_deallocate_resources(webrtc->resource.handle, &requested);
+ if (rm_ret != RM_OK) {
+ LOG_ERROR("Resource deallocation request failed [%d] [request num %d]", rm_ret, requested.request_num);
+ return WEBRTC_ERROR_RESOURCE_FAILED;
+ }
}
- LOG_DEBUG("all resources were released by resource manager");
- for (i = 0; i < RESOURCE_TYPE_MAX; i++) {
- webrtc->resource.need_to_acquire[i] = false;
- webrtc->resource.res[i] = NULL;
+ for (idx = 0; idx < devices->allocated_num; idx++) {
+ if (devices->device_node[idx]) {
+ free(devices->device_node[idx]);
+ devices->device_node[idx] = NULL;
+ }
+
+ if (devices->omx_comp_name[idx]) {
+ free(devices->omx_comp_name[idx]);
+ devices->omx_comp_name[idx] = NULL;
+ }
}
return WEBRTC_ERROR_NONE;
}
-int _destroy_resource_manager(webrtc_s *webrtc)
+int _unregister_resource_manager(webrtc_s *webrtc)
{
- int ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+ int ret;
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(webrtc->resource.handle == 0, WEBRTC_ERROR_RESOURCE_FAILED, "webrtc resource handle is NULL");
- if (!webrtc->resource.mgr)
- return WEBRTC_ERROR_NONE;
-
- ret = mm_resource_manager_destroy(webrtc->resource.mgr);
- if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+ ret = rm_unregister(webrtc->resource.handle);
+ if (ret != RM_OK) {
//LCOV_EXCL_START
- LOG_ERROR("failed to destroy resource manager, ret[0x%x]", ret);
+ LOGE("rm_unregister fail %d", ret);
return WEBRTC_ERROR_RESOURCE_FAILED;
//LCOV_EXCL_STOP
}
- webrtc->resource.mgr = NULL;
- LOG_DEBUG("destroyed resource manager");
+
+ g_mutex_clear(&webrtc->resource.control_lock);
+
+ LOG_INFO("ret [%d]", ret);
return WEBRTC_ERROR_NONE;
}