Enable resource manager commonization 79/314879/10 accepted/tizen/unified/20240816.171355 accepted/tizen/unified/dev/20240819.095610 accepted/tizen/unified/x/20240819.023352
authorYoungHun Kim <yh8004.kim@samsung.com>
Mon, 22 Jul 2024 11:05:44 +0000 (20:05 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Thu, 25 Jul 2024 10:39:46 +0000 (19:39 +0900)
[Version] 0.1.0
[Issue Type] Update

Change-Id: Idc6262611b47c3e705cdef65e09be74d2a93e6cb

packaging/libtrackrenderer.spec
src/CMakeLists.txt
src/include_internal/trackrenderer/resource.h
src/include_internal/trackrenderer/resourcemanager.h
src/include_internal/trackrenderer/version.h
src/resourcemanager.cpp

index fa49db2afeaafacbe8aa835007e050fa27e856c5..70c74233765a96fd79c70bdf0323c7d6dc953fc5 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libtrackrenderer
 Summary:    new multimedia streaming player trackrenderer
-Version:    0.0.57
+Version:    0.1.0
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
@@ -20,11 +20,12 @@ BuildRequires:  pkgconfig(evas)
 BuildRequires:  pkgconfig(ecore-wl2)
 BuildRequires:  pkgconfig(wayland-client)
 BuildRequires:  pkgconfig(tizen-extension-client)
+BuildRequires:  pkgconfig(resource-manager)
+BuildRequires:  pkgconfig(resource-center-api)
 BuildRequires:  pkgconfig(jsoncpp)
 BuildRequires:  pkgconfig(capi-system-info)
 BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(libtbm)
-BuildRequires:  pkgconfig(mm-resource-manager)
 BuildRequires:  pkgconfig(libpulse)
 BuildRequires:  pkgconfig(capi-media-sound-manager)
 BuildRequires:  gtest-devel
index 85bd4b832df1deb1b252a3cab1dbb77daa829a7a..20cb6f661de431e17e90f7447bc4b95d0fdffc6b 100644 (file)
@@ -17,7 +17,7 @@ SET(dependents "gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-video-1.0 gst
                "libtbm"
                "jsoncpp"
                "capi-system-info"
-               "mm-resource-manager"
+               "resource-manager resource-center-api"
                "capi-media-sound-manager libpulse")
 
 INCLUDE(FindPkgConfig)
index b742a978181cd69c20c81ac4cec39bae63ffde6b..3d46fe01c7205435e5cd70838e9099106c28db28 100644 (file)
@@ -22,7 +22,7 @@
 namespace plusplayer {
 
 namespace trackrenderer {
-using ResourceHandle = void*;
+using ResourceHandle = int;
 
 enum class ResourceCategory {
   kVideoDecoder,
@@ -36,15 +36,19 @@ struct ResourceProperty {
 
 class Resource {
  public:
-  Resource(const ResourceProperty& property, ResourceHandle res)
+  Resource(const ResourceProperty& property, int deviceId, ResourceHandle res)
       : property_(property),
+        deviceId_(deviceId),
         resource_(res){}
-  const ResourceCategory& GetResourceCategory() const { return property_.category; }
+  ResourceCategory GetResourceCategory() const { return property_.category; }
   ResourceHandle GetResourceHandle() const { return resource_; }
+  int GetDeviceId() const { return deviceId_; }
 
  private:
   const ResourceProperty property_;
+  const int deviceId_ = 0;
   ResourceHandle resource_;
+
 };
 
 }  // namespace trackrenderer
index 75d7bce77603be8b34431bc1205f0581c706d2b5..2a0cf8bbe1134f1e2a5b5de11fa51dafb8fb1327 100644 (file)
@@ -19,7 +19,9 @@
 
 #include <list>
 #include <mutex>
-#include "mm_resource_manager.h"
+#include <string>
+
+#include "rm_api.h"
 #include "trackrenderer/core/track.h"
 #include "trackrenderer/resource.h"
 #include "trackrenderer/resource_conflict_listener.h"
@@ -28,7 +30,7 @@ namespace plusplayer {
 
 namespace trackrenderer {
 
-using ResourceManagerHandle = void*;
+using ResourceManagerHandle = int;
 
 constexpr int kMaxUhd8kWidth = 7680;
 constexpr int kMaxUhd8kHeight = 4320;
@@ -45,17 +47,24 @@ class ResourceManager {
   bool Acquire(const std::list<ResourceProperty>& properties);
   bool Release();
   bool Release(const ResourceCategory type);
+  bool GetAppIdByPid(int pid, std::string& name);
+  int GetDeviceId(const ResourceCategory& type);
 
  private:
-  static int ResourceConflictCallback_(
-    ResourceManagerHandle rmhandle, ResourceHandle res, void *userdata);
+  bool Acquire_(const ResourceProperty& property);
 
  private:
-  ResourceManagerHandle resourcemanager_handle_ = 0;
+  static rm_cb_result ResourceConflictCallback_(ResourceManagerHandle rmhandle,
+                                                rm_callback_type eventtype,
+                                                rm_device_request_s* info,
+                                                void* userdata);
 
+ private:
+  ResourceManagerHandle resourcemanager_handle_ = 0;
   std::list<Resource> resourcelist_;
   std::mutex control_lock_;
   ResourceConflictListener* resourceconflict_listener_ = nullptr;
+  std::string app_id_;
 };  // class ResourceManager
 
 }  // namespace trackrenderer
index 493a62229dd993a755442b85b703ba4a6fd092a4..618f1deabc1a2b46c7a89e0eb0e834ecd112b02b 100644 (file)
@@ -29,8 +29,8 @@
 #define TRACKRENDERER_GET_VERSION_MICRO(a) ((a)&0xFF)
 
 #define LIB_TRACKRENDERER_VERSION_MAJOR 0
-#define LIB_TRACKRENDERER_VERSION_MINOR 0
-#define LIB_TRACKRENDERER_VERSION_MICRO 2
+#define LIB_TRACKRENDERER_VERSION_MINOR 1
+#define LIB_TRACKRENDERER_VERSION_MICRO 0
 
 #define LIB_TRACKRENDERER_VERSION_INT                        \
   TRACKRENDERER_VERSION_INT(LIB_TRACKRENDERER_VERSION_MAJOR, \
index 3197116cc0c49e87f877e2d801676ee2cbd351be..4f62611abc4f463d9998dbd32a7dc5e3ee693d85 100644 (file)
 #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