#include "trackrenderer/resourcemanager.h"
#include "trackrenderer/core/utils/log.h"
+#include "resource_center.h"
+#include "rm_module_api.h"
+
namespace plusplayer {
namespace trackrenderer {
namespace internal {
-const std::map<ResourceCategory, mm_resource_manager_res_type_e> TypeToCategoryConverter = {
- {ResourceCategory::kVideoDecoder, MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER},
- {ResourceCategory::kVideoRenderer, MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY}};
+static std::mutex rsc_lock;
+static std::list<ResourceManager*> rsc_list;
+
+const std::map<ResourceCategory, rm_rsc_category_e> TypeToCategoryConverter = {
+ {ResourceCategory::kVideoDecoder, RM_CATEGORY_VIDEO_DECODER},
+ {ResourceCategory::kVideoRenderer, RM_CATEGORY_SCALER}};
+
+void AddRMHandle(ResourceManager *handle) {
+ TRACKRENDERER_INFO("Resource manager handle[%p]", handle);
+ std::lock_guard<std::mutex> lock(rsc_lock);
+ rsc_list.push_back(handle);
+}
+
+void RemoveRMHandle(ResourceManager *handle) {
+ TRACKRENDERER_INFO("Resource manager handle[%p]", handle);
+ std::lock_guard<std::mutex> lock(rsc_lock);
+ auto iter = find(rsc_list.begin(), rsc_list.end(), handle);
+ if (iter != rsc_list.end())
+ rsc_list.erase(iter);
+ else
+ TRACKRENDERER_ERROR("Invalid handle[%p]", handle);
+}
+rm_rsc_category_e GetCategoryID(const ResourceProperty& property) {
+ rm_rsc_category_e category_id;
+ category_id = internal::TypeToCategoryConverter.at(property.category);
+
+ return category_id;
+}
+
+bool GetAppIdByPid(int pid, std::string& name) {
+ gchar *con;
+
+ g_autoptr(GError) error = NULL;
+
+ auto cmdline = g_strdup_printf("/proc/%d/cmdline", pid);
+ if (!g_file_get_contents(cmdline, &con, NULL, &error)) {
+ TRACKRENDERER_ERROR("error : %s", error->message);
+ return false;
+ }
+
+ name = g_path_get_basename(con);
+
+ g_free(cmdline);
+ return true;
+}
} // namespace internal
ResourceManager::ResourceManager(ResourceConflictListener* listener)
: resourceconflict_listener_(listener) {
- assert(listener && "listener is nullptr!!");
-
- int ret = mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
- (mm_resource_manager_release_cb)ResourceConflictCallback_,
- (void*)this, &resourcemanager_handle_);
- assert(ret == MM_RESOURCE_MANAGER_ERROR_NONE && "rm creation is failed");
-
- TRACKRENDERER_INFO("resource manager Listener = %p", listener);
+ if (!listener)
+ TRACKRENDERER_ERROR("listener is nullptr!!");
+
+ internal::AddRMHandle(this);
+ int ret = rm_register((rm_resource_cb)ResourceConflictCallback_, (void*)this,
+ &resourcemanager_handle_, NULL);
+ if (ret != RM_OK)
+ TRACKRENDERER_ERROR("rm_register() is failed");
+
+ TRACKRENDERER_INFO_P(resourceconflict_listener_,
+ "resource manager handle = %d, Listener = %p, this = %p",
+ resourcemanager_handle_, listener, this);
}
ResourceManager::~ResourceManager() {
- int ret = mm_resource_manager_destroy(resourcemanager_handle_);
- assert(ret == MM_RESOURCE_MANAGER_ERROR_NONE && "rm destroy is failed");
- TRACKRENDERER_DEBUG("rm destroy() was done");
+ if (resourcemanager_handle_ != -1) {
+ int ret = rm_unregister(resourcemanager_handle_);
+ if (ret != RM_OK)
+ TRACKRENDERER_ERROR_P(resourceconflict_listener_,
+ "rm_unregister() was done");
+ }
+
+ internal::RemoveRMHandle(this);
}
-int ResourceManager::ResourceConflictCallback_(
- ResourceManagerHandle rmhandle, ResourceHandle res, void *userdata)
-{
- TRACKRENDERER_ENTER;
+// LCOV_EXCL_START
+rm_cb_result ResourceManager::ResourceConflictCallback_(
+ ResourceManagerHandle rmhandle, rm_callback_type eventtype,
+ rm_device_request_s* info, void* userdata) {
+ TRACKRENDERER_DEBUG(
+ "ResourceManagerHandle[%d], cb_type[%d], conflicted num[%d], "
+ "device_id[%d]",
+ rmhandle, eventtype, info->request_num, info->device_id[0]);
+
ResourceManager* resourcemanager = static_cast<ResourceManager*>(userdata);
+ std::lock_guard<std::mutex> lock(internal::rsc_lock);
+ auto iter = find(internal::rsc_list.begin(), internal::rsc_list.end(),
+ resourcemanager);
+ if (iter == internal::rsc_list.end()) {
+ TRACKRENDERER_WARN("ResourceManager[%p] is released", resourcemanager);
+ return RM_CB_RESULT_OK;
+ }
{
- std::lock_guard<std::mutex> lock(resourcemanager->control_lock_);
+ std::lock_guard<std::mutex> lock2(resourcemanager->control_lock_);
if (resourcemanager->resourcelist_.empty()) {
- TRACKRENDERER_ERROR("resourcelist is empty! return.");
- return true;
+ TRACKRENDERER_ERROR_P(resourcemanager->resourceconflict_listener_,
+ "resourcelist is empty! return.");
+ return RM_CB_RESULT_OK;
}
}
if (!resourcemanager->resourceconflict_listener_) {
TRACKRENDERER_ERROR("confilict listener is nullptr. ERROR!");
- assert(0 && "resourceconflict_listener_ is nullptr");
- return true;
+ return RM_CB_RESULT_ERROR;
}
resourcemanager->resourceconflict_listener_->OnResourceConflicted();
- /* default player > OnResourceConflicted > trackrenderer_->Stop() */
- /* es player > OnResourceConflicted > trackrenderer_->Stop */
+ TRACKRENDERER_LEAVE_P(resourcemanager->resourceconflict_listener_);
+ return RM_CB_RESULT_OK;
+}
+// LCOV_EXCL_STOP
+
+bool ResourceManager::Acquire_(const ResourceProperty& property) {
+ rm_rsc_category_e category_id = internal::TypeToCategoryConverter.at(property.category);
+ std::string app_id;
+ if (!internal::GetAppIdByPid((int)getpid(), app_id))
+ TRACKRENDERER_ERROR("[RM_ERROR] GetAppIdByPid() fail");
+
+ app_id_ = app_id;
+ TRACKRENDERER_INFO("app id[%s]", app_id_.c_str());
+
+ if (rm_set_app_id(resourcemanager_handle_, (char *)app_id_.c_str()) != RM_OK)
+ TRACKRENDERER_ERROR("[RM_ERROR] rm_set_app_id fail");
+
+ rm_category_request_s req;
+ memset(&req, 0, sizeof(rm_category_request_s));
+ rm_device_return_s devices;
+ memset(&devices, 0, sizeof(rm_device_return_s));
+
+ req.request_num = 1;
+ req.state[0] = RM_STATE_EXCLUSIVE;
+ req.category_id[0] = internal::GetCategoryID(property);
+ req.category_option[0] = rc_get_capable_category_id(resourcemanager_handle_, app_id_.c_str(),category_id);
+
+ int rm_ret = rm_allocate_resources(resourcemanager_handle_, &req, &devices);
+ if (rm_ret == RM_ERROR) {
+ TRACKRENDERER_ERROR("[RM_ERROR] rm_allocate_resources fail");
+ return false;
+ }
- TRACKRENDERER_LEAVE;
+ TRACKRENDERER_INFO_P(resourceconflict_listener_,
+ "resource Type[%d], device id[%d], comp_name[%s]",
+ static_cast<int>(property.category),
+ devices.device_id[0], devices.omx_comp_name[0]);
+
+ resourcelist_.emplace_back(property, devices.device_id[0], resourcemanager_handle_);
+
+ if (devices.device_node[0]) {
+ free(devices.device_node[0]);
+ }
+ if (devices.omx_comp_name[0]) {
+ free(devices.omx_comp_name[0]);
+ }
return true;
}
-
bool ResourceManager::Acquire(const std::list<ResourceProperty>& properties) {
- TRACKRENDERER_ENTER;
for (const auto& property : properties) {
- ResourceHandle res = nullptr;
- int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-
- TRACKRENDERER_INFO("resource Type[%d]", static_cast<int>(property.category));
-
- /* FIXME_RM : can get res vol size based on the property.track */
- rm_ret = mm_resource_manager_mark_for_acquire(resourcemanager_handle_,
- internal::TypeToCategoryConverter.at(property.category),
- MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &res);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- TRACKRENDERER_ERROR("failed to mark resource for acquire, ret(0x%x)", rm_ret);
- return false;
- }
-
- rm_ret = mm_resource_manager_commit(resourcemanager_handle_);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- TRACKRENDERER_ERROR("failed to commit of resource, ret(0x%x)", rm_ret);
- return false;
- }
- resourcelist_.emplace_back(property, res);
- TRACKRENDERER_INFO("resource acquired");
+ TRACKRENDERER_INFO_P(resourceconflict_listener_, "Resource Type[%d]]", static_cast<int>(property.category));
+ if (Acquire_(property) == false) return false;
}
-
- TRACKRENDERER_LEAVE;
return true;
}
bool ResourceManager::Release() {
- int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+ TRACKRENDERER_ENTER_P(resourceconflict_listener_);
- TRACKRENDERER_ENTER;
if (resourcelist_.empty()) return true;
- rm_ret = mm_resource_manager_mark_all_for_release(resourcemanager_handle_);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- TRACKRENDERER_ERROR("failed to mark resource for release, ret(0x%x)", rm_ret);
- } else {
- rm_ret = mm_resource_manager_commit(resourcemanager_handle_);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- TRACKRENDERER_ERROR("failed to commit of resource, ret(0x%x)", rm_ret);
- }
+ rm_device_request_s devices;
+ memset(&devices, 0, sizeof(rm_device_request_s));
+
+ size_t device_num = 0;
+ std::for_each(resourcelist_.begin(), resourcelist_.end(),
+ [&devices, &device_num](const Resource& resource) {
+ if (resource.GetDeviceId() != 0) {
+ devices.device_id[device_num++] = resource.GetDeviceId();
+ }
+ });
+
+ if (device_num == 0) {
+ TRACKRENDERER_WARN_P(resourceconflict_listener_,
+ "therer are no resource to dealloc");
+ return true;
+ }
+
+ devices.request_num = device_num;
+ int rm_err = rm_deallocate_resources(resourcemanager_handle_, &devices);
+ if (rm_err != RM_OK) {
+ TRACKRENDERER_ERROR_P(resourceconflict_listener_,
+ "rm_deallocate_resources failed, rm_err[%d]",
+ rm_err);
+ return false;
}
std::lock_guard<std::mutex> lock(control_lock_);
resourcelist_.clear();
- TRACKRENDERER_LEAVE;
- return (rm_ret == MM_RESOURCE_MANAGER_ERROR_NONE);
+ TRACKRENDERER_LEAVE_P(resourceconflict_listener_);
+ return true;
}
bool ResourceManager::Release(const ResourceCategory type) {
- int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
-
- TRACKRENDERER_ENTER;
+ TRACKRENDERER_ENTER_P(resourceconflict_listener_);
if (resourcelist_.empty()) return true;
- auto compare = [type](Resource & item) noexcept->bool {
+ rm_device_request_s devices;
+ memset(&devices, 0, sizeof(rm_device_request_s));
+ devices.request_num = 1;
+
+ auto compare = [type](Resource &item) noexcept->bool {
return item.GetResourceCategory() == type;
};
auto target =
std::find_if(resourcelist_.begin(), resourcelist_.end(), compare);
// There is no resource.
- if (target == resourcelist_.end()) {
- TRACKRENDERER_ERROR("there is no acquired [%d type] resource", (int)type);
+ if (target == resourcelist_.end()) return true;
+ if (target->GetDeviceId() == 0) {
+ std::lock_guard<std::mutex> lock(control_lock_);
+ resourcelist_.erase(target);
+ TRACKRENDERER_DEBUG_P(resourceconflict_listener_,
+ "resourcelist_.size() = %d", (int)resourcelist_.size());
return true;
}
- TRACKRENDERER_INFO("resource Type[%d]", (int)type);
- rm_ret = mm_resource_manager_mark_for_release(resourcemanager_handle_, target->GetResourceHandle());
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- TRACKRENDERER_ERROR("failed to mark resource for release, ret(0x%x)", rm_ret);
- } else {
- rm_ret = mm_resource_manager_commit(resourcemanager_handle_);
- if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
- TRACKRENDERER_ERROR("failed to commit of resource, ret(0x%x)", rm_ret);
- }
+ devices.device_id[0] = target->GetDeviceId();
+
+ int rm_err = rm_deallocate_resources(resourcemanager_handle_, &devices);
+ if (rm_err != RM_OK) {
+ TRACKRENDERER_ERROR_P(resourceconflict_listener_,
+ "rm_deallocate_resources failed, rm_err[%d]", rm_err);
+ return false;
}
std::lock_guard<std::mutex> lock(control_lock_);
resourcelist_.erase(target);
- TRACKRENDERER_DEBUG("resourcelist_.size() = %zu", resourcelist_.size());
- TRACKRENDERER_LEAVE;
- return (rm_ret == MM_RESOURCE_MANAGER_ERROR_NONE);
+ TRACKRENDERER_LEAVE_P(resourceconflict_listener_);
+ return true;
+}
+
+int ResourceManager::GetDeviceId(const ResourceCategory& type) {
+ TRACKRENDERER_ENTER_P(resourceconflict_listener_);
+ auto compare = [type](const Resource& item) noexcept -> bool {
+ return item.GetResourceCategory() == type;
+ };
+ auto target =
+ std::find_if(resourcelist_.begin(), resourcelist_.end(), compare);
+ if (target == resourcelist_.end()) {
+ TRACKRENDERER_ERROR_P(resourceconflict_listener_,
+ "This resource[%d] is not allocated ",
+ static_cast<int>(type));
+ return -1;
+ }
+ return target->GetDeviceId();
}
} // namespace trackrenderer